#!/usr/bin/env python3 import numpy as np l = -1 def calc(line): x = 0 for elem in line: x = x*2 + elem return x def solve(arr, pos, s, left_keys): global l if pos >= s*s: return True idx = (pos // s * 2, pos % s * 2) 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 bottom = (idx[0], idx[1]+1) if idx[1] < s else None left = (idx[0]-1, idx[1]) if idx[0] > 0 else None right = (idx[0]+1, idx[1]) if idx[0] < s else None for key in left_keys: new_keys = left_keys.copy() new_keys.discard(key) for transpose, rotate in ([(False, 0)] if pos == 0 else rotations): view = np.rot90(tiles[key].T if transpose else tiles[key], rotate) if (top is None or arr[top] == -1 or arr[top] == calc(view[0])) and \ (bottom is None or arr[bottom] == -1 or arr[bottom] == calc(view[-1])) and \ (left is None or arr[left] == -1 or arr[left] == calc(view[:, 0])) and \ (right is None or arr[right] == -1 or arr[right] == calc(view[:, -1])): arr[idx] = key if right is not None: arr[right] = calc(view[:, -1]) if bottom is not None: arr[bottom] = calc(view[-1]) #print("B", arr) #print("bef", pos) if pos % s == 0: p = pos // s + 1 p = p if p != s else p+s-1 else: p = pos + s - 1 p = p if p <= s*s-1 else (p-s*s+3)*s-1 #print("change", p) if solve(arr, p, s, new_keys): return True arr[idx] = -1 if right is not None: arr[right] = -1 if bottom is not None: arr[bottom] = -1 return False lines = (x.strip() for x in open("input.txt")) rotations = [(t, r) for t in (True, False) for r in range(4)] tiles = {} num = None tile = None lnr = None 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 == "": tiles[num] = tile else: a = np.array([(0 if x == '.' else 1) for x in line], dtype=np.int8) tile[lnr] = a lnr += 1 tiles[num] = tile size = int(np.sqrt(len(tiles))) positioning = -np.ones((size*2-1, size*2-1), dtype=np.int64) print(positioning.shape) if solve(positioning, 0, size, set(tiles.keys())): print(positioning) print(positioning[0, 0]*positioning[-1, 0]*positioning[0, -1]*positioning[-1, -1]) else: print("fail")