from lib import get_data, add2 from collections import defaultdict DIRS = { "N": (-1, 0), "E": (0, 1), "S": (1, 0), "W": (0, -1), } data = get_data(__file__).strip() g = defaultdict(set) seen = set() stack: list[tuple[tuple, int, list]] = [((0, 0), 0, [])] while len(stack) > 0: pos, i, i_outs = stack.pop() c = (pos, i, tuple(i_outs)) if c in seen: continue else: seen.add(c) assert i is not None while i < len(data): c = data[i] if c in DIRS.keys(): npos = add2(pos, DIRS[c]) g[pos].add(npos) g[npos].add(pos) pos = npos i += 1 elif c == "(": to_continue = [i + 1] open_count = 0 j_out = None for j in range(i + 1, len(data)): c = data[j] if c == "|" and open_count == 0: to_continue.append(j + 1) elif c == "(": open_count += 1 elif c == ")" and open_count != 0: open_count -= 1 elif c == ")" and open_count == 0: j_out = j break assert j_out is not None for new_i in to_continue: new_i_outs = list(i_outs) new_i_outs.append(j_out) stack.append((pos, new_i, new_i_outs)) break elif c == "$": break elif c == ")" and len(i_outs) == 0: assert False, "Encountered | without i_out" elif c == ")": i_new = i_outs.pop() assert i == i_new i += 1 elif c == "^": i += 1 elif c == "|" and len(i_outs) == 0: assert False, "Encountered | without i_out" elif c == "|": i = i_outs.pop() i += 1 else: assert False seen = set() dists = {} xs = [(0, 0)] steps = 0 over_thousand = set() while len(xs) > 0: nxs = [] for x in xs: if x in seen: continue if steps >= 1000: over_thousand.add(x) seen.add(x) dists[x] = steps for nb in g[x]: if not nb in seen: nxs.append(nb) xs = nxs steps += 1 print(max(dists.values())) print(len(over_thousand))