import re import functools from math import gcd, inf from pprint import pprint from collections import deque, Counter, defaultdict from heapq import heappop, heappush from itertools import compress, combinations, chain, permutations from output import matrix, D, DD, ADJ, ints, sints, mhd, mdbg, vdbg, cw, ccw, bk def solve(data): r = r"^\[(.+)\] (.+) \{(.+)\}$" p1 = 0 p2 = 0 for line in data.splitlines(): il, b, j = re.findall(r, line)[0] B = [set(ints(s)) for s in b.split()] E = set([i for i, s in enumerate(il) if s == "#"]) j = tuple(ints(j)) p = 0 L = set() while L != E: p += 1 for bp in combinations(B, p): L = set() for b in bp: L = L ^ b if L == E: break if L == E: break p1 += p @functools.cache def _press(T): if not any(T): return 0 L = set(i for i, s in enumerate(T) if s % 2 == 1) R = inf for p in [bb for ii, bb in enumerate(B) if ii in L]: tt = list(T) for b in p: for i in b: tt[i] -= 1 if any(j < 0 for j in tt): continue Th = tuple(j // 2 for j in tt) n = _press(Th) if n is None: continue R = min(R, len(p) + 2 * n) return R p2 = _press(j) return p1, p2 if __name__ == "__main__": import os # use dummy data inp = """ [.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7} [...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2} [.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5} """.strip() # uncomment to instead use stdin # import sys; inp = sys.stdin.read().strip() # uncomment to use AoC provided puzzle input with open("./input/10.txt", "r") as f: in_p = f.read().strip() # uncomment to do initial data processing shared by part 1-2 p1, p2 = solve(inp) print(p1) os.system(f"echo {p1} | wl-copy") print(p2) os.system(f"echo {p2} | wl-copy") # uncomment and replace 0 with actual output to refactor code # and ensure nonbreaking changes # assert p1 == 466 # assert p2 == 17214