Day 20 (Part 2 fi-na-l-l-yyyyy)
This commit is contained in:
53
day20/part1-v2.py
Normal file
53
day20/part1-v2.py
Normal file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from collections import defaultdict
|
||||
from functools import reduce
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
||||
lines = (x.strip() for x in open("input.txt"))
|
||||
rotations = [(t, r) for t in (True, False) for r in range(4)]
|
||||
tiles = {}
|
||||
borders = defaultdict(set)
|
||||
|
||||
|
||||
def add_tile(num, tile):
|
||||
global tiles, borders
|
||||
tiles[num] = tile
|
||||
for transpose, rotate in rotations:
|
||||
view = np.rot90(tile.T if transpose else tile, rotate)
|
||||
edge = np.packbits(view[0])
|
||||
edge = edge[0] * 4 + edge[1] // 64
|
||||
borders[edge].add(num)
|
||||
|
||||
|
||||
for line in lines:
|
||||
if line.startswith("Tile"):
|
||||
num = int(line[5:-1])
|
||||
tile = np.zeros((10, 10), dtype=np.int16)
|
||||
lnr = 0
|
||||
elif line == "":
|
||||
add_tile(num, tile)
|
||||
else:
|
||||
a = np.array([(0 if x == '.' else 1) for x in line], dtype=np.int16)
|
||||
tile[lnr] = a
|
||||
lnr += 1
|
||||
add_tile(num, tile)
|
||||
|
||||
# every border matches only once
|
||||
print("sum joints", sum(1 for key, val in borders.items() if len(val) > 1))
|
||||
print("should joints", (len(tiles)-np.sqrt(len(tiles))) * 2)
|
||||
print("sum outer", sum(1 for key, val in borders.items() if len(val) == 1))
|
||||
print("should outer", np.sqrt(len(tiles)) * 4)
|
||||
print("cnt tiles", len(tiles))
|
||||
print("multi matches", sum(1 for key, val in borders.items() if len(val) > 2))
|
||||
|
||||
# find corners
|
||||
edges = defaultdict(int)
|
||||
for key, val in borders.items():
|
||||
if len(val) == 1:
|
||||
for item in val:
|
||||
edges[item] += 1
|
||||
|
||||
print(reduce(lambda a, b: a*b, (key for key, val in edges.items() if val == 4), 1))
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import numpy as np
|
||||
l = 1000000000000
|
||||
l = -1
|
||||
|
||||
def calc(line):
|
||||
x = 0
|
||||
@@ -14,7 +14,7 @@ def solve(arr, pos, s, left_keys):
|
||||
if pos >= s*s:
|
||||
return True
|
||||
idx = (pos // s * 2, pos % s * 2)
|
||||
if l > len(left_keys):
|
||||
if l != len(left_keys):
|
||||
print("-"*pos, pos, len(left_keys), idx)
|
||||
l = len(left_keys)
|
||||
top = (idx[0], idx[1]-1) if idx[1] > 0 else None
|
||||
|
||||
115
day20/part2.py
Normal file
115
day20/part2.py
Normal file
@@ -0,0 +1,115 @@
|
||||
from collections import defaultdict
|
||||
from functools import reduce
|
||||
|
||||
import numpy as np
|
||||
from scipy.signal import convolve
|
||||
|
||||
lines = (x.strip() for x in open("input.txt"))
|
||||
rotations = [(t, r) for t in (True, False) for r in range(4)]
|
||||
tiles = {}
|
||||
borders = defaultdict(set)
|
||||
|
||||
|
||||
def edge_to_bin(edge):
|
||||
edge = np.packbits(edge)
|
||||
return edge[0] * 4 + edge[1] // 64
|
||||
|
||||
|
||||
def add_tile(num, tile):
|
||||
global tiles, borders
|
||||
tiles[num] = tile
|
||||
for transpose, rotate in rotations:
|
||||
view = np.rot90(tile.T if transpose else tile, rotate)
|
||||
edge = edge_to_bin(view[0])
|
||||
borders[edge].add(num)
|
||||
|
||||
|
||||
for line in lines:
|
||||
if line.startswith("Tile"):
|
||||
num = int(line[5:-1])
|
||||
tile = np.zeros((10, 10), dtype=np.int8)
|
||||
lnr = 0
|
||||
elif line == "":
|
||||
add_tile(num, tile)
|
||||
else:
|
||||
a = np.array([(0 if x == '.' else 1) for x in line], dtype=np.int8)
|
||||
tile[lnr] = a
|
||||
lnr += 1
|
||||
add_tile(num, tile)
|
||||
|
||||
|
||||
# find top left corner
|
||||
edges = defaultdict(int)
|
||||
corner = None
|
||||
for key, val in borders.items():
|
||||
if len(val) == 1:
|
||||
for item in val:
|
||||
edges[item] += 1
|
||||
for key, val in edges.items():
|
||||
if val == 4:
|
||||
corner = key
|
||||
break
|
||||
|
||||
# rotate top left corner
|
||||
corner_tile = tiles[corner]
|
||||
joints = []
|
||||
for x in range(4):
|
||||
edge = edge_to_bin(corner_tile[0])
|
||||
corner_tile = np.rot90(corner_tile)
|
||||
if len(borders[edge]) == 2:
|
||||
joints.append(edge)
|
||||
if len(joints) == 2:
|
||||
break
|
||||
corner_tile = np.rot90(corner_tile)
|
||||
|
||||
# prepare plane
|
||||
plane = np.zeros(((10-1)*12+1, (10-1)*12+1), dtype=np.int8)
|
||||
plane[:10, :10] = corner_tile
|
||||
used_tiles = {corner}
|
||||
|
||||
# orientate and add tiles to plane
|
||||
for idx in range(1, len(tiles)):
|
||||
x, y = (idx % 12) * (10-1), (idx // 12) * (10-1)
|
||||
next_tile_top = None if y == 0 else borders[edge_to_bin(plane[y, x:x+10])]
|
||||
next_tile_left = None if x == 0 else borders[edge_to_bin(plane[y:y+10, x].T)]
|
||||
if next_tile_top is None:
|
||||
next_tile = next_tile_left
|
||||
elif next_tile_left is None:
|
||||
next_tile = next_tile_top
|
||||
else:
|
||||
next_tile = next_tile_left.intersection(next_tile_top)
|
||||
next_tile = next_tile.difference(used_tiles).pop()
|
||||
used_tiles.add(next_tile)
|
||||
tile = tiles[next_tile]
|
||||
for transpose, rotate in rotations:
|
||||
view = np.rot90(tile.T if transpose else tile, rotate)
|
||||
if y != 0 and not np.all(np.equal(plane[y, x:x+10], view[0])):
|
||||
continue
|
||||
if x != 0 and not np.all(np.equal(plane[y:y+10, x], view[:, 0])):
|
||||
continue
|
||||
plane[y:y+10, x:x+10] = view
|
||||
break
|
||||
|
||||
# remove all edges
|
||||
plane = np.delete(plane, list(range(0, plane.shape[0], 10-1)), axis=0)
|
||||
plane = np.delete(plane, list(range(0, plane.shape[1], 10-1)), axis=1)
|
||||
|
||||
# kernel
|
||||
|
||||
#
|
||||
# ## ## ###
|
||||
# # # # # #
|
||||
|
||||
kernel = np.array([
|
||||
[0,0,0,0,0 ,0,0,0,0,0 ,0,0,0,0,0 ,0,0,0,1,0],
|
||||
[1,0,0,0,0 ,1,1,0,0,0 ,0,1,1,0,0 ,0,0,1,1,1],
|
||||
[0,1,0,0,1 ,0,0,1,0,0 ,1,0,0,1,0 ,0,1,0,0,0]
|
||||
])
|
||||
count = np.sum(kernel)
|
||||
|
||||
for transpose, rotate in rotations:
|
||||
view = np.rot90(plane.T if transpose else plane, rotate)
|
||||
neighbors = convolve(view, kernel, mode='valid')
|
||||
if np.max(neighbors) == count:
|
||||
print(len(np.where(view == 1)[0]) - len(np.where(neighbors == count)[0]) * count)
|
||||
|
||||
Reference in New Issue
Block a user