Files
aocpy/2018/d20.py
2024-10-13 16:28:30 -04:00

95 lines
2.3 KiB
Python

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))