Finish 2020.

This commit is contained in:
felixm 2024-10-13 16:28:30 -04:00
parent 800d1a6af3
commit 87ab42743e
2 changed files with 80 additions and 146 deletions

View File

@ -1,11 +1,6 @@
from lib import get_data, add2 from lib import get_data, add2
from collections import defaultdict from collections import defaultdict
data = "^WNE$"
data = "^ENWWW(NEEE|SSE(EE|N))$"
data = "^ESSWWN(E|NNENN(EESS(WNSE|)SSS|WWWSSSSE(SW|NNNE)))$"
data = "^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$"
DIRS = { DIRS = {
"N": (-1, 0), "N": (-1, 0),
"E": (0, 1), "E": (0, 1),
@ -13,148 +8,87 @@ DIRS = {
"W": (0, -1), "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()
def part_1(data): c = (pos, i, tuple(i_outs))
g = defaultdict(set) if c in seen:
continue
else:
seen.add(c)
stack: list[tuple[tuple, int, list]] = [((0, 0), 0, [])] assert i is not None
while len(stack) > 0: while i < len(data):
pos, i, i_outs = stack.pop() c = data[i]
assert i is not None if c in DIRS.keys():
while i < len(data): npos = add2(pos, DIRS[c])
c = data[i] g[pos].add(npos)
if c in DIRS.keys(): g[npos].add(pos)
npos = add2(pos, DIRS[c]) pos = npos
g[pos].add(npos) i += 1
g[npos].add(pos) elif c == "(":
pos = npos to_continue = [i + 1]
i += 1 open_count = 0
elif c == "(": j_out = None
to_continue = [i + 1] for j in range(i + 1, len(data)):
open_count = 0 c = data[j]
j_out = None if c == "|" and open_count == 0:
for j in range(i + 1, len(data)): to_continue.append(j + 1)
c = data[j] elif c == "(":
if c == "|" and open_count == 0: open_count += 1
to_continue.append(j + 1) elif c == ")" and open_count != 0:
elif c == "(": open_count -= 1
open_count += 1 elif c == ")" and open_count == 0:
elif c == ")" and open_count != 0: j_out = j
open_count -= 1 break
elif c == ")" and open_count == 0: assert j_out is not None
j_out = j
break
assert j_out is not None
for new_i in to_continue: for new_i in to_continue:
new_i_outs = list(i_outs) new_i_outs = list(i_outs)
new_i_outs.append(j_out) new_i_outs.append(j_out)
stack.append((pos, new_i, new_i_outs)) stack.append((pos, new_i, new_i_outs))
break break
elif c == "$": elif c == "$":
break break
elif c == ")" and len(i_outs) == 0: elif c == ")" and len(i_outs) == 0:
assert False, "Encountered | without i_out" assert False, "Encountered | without i_out"
elif c == ")": elif c == ")":
i_new = i_outs.pop() i_new = i_outs.pop()
assert i == i_new assert i == i_new
i += 1 i += 1
elif c == "^": elif c == "^":
i += 1 i += 1
elif c == "|" and len(i_outs) == 0: elif c == "|" and len(i_outs) == 0:
assert False, "Encountered | without i_out" assert False, "Encountered | without i_out"
elif c == "|": elif c == "|":
i = i_outs.pop() i = i_outs.pop()
i += 1 i += 1
else: else:
assert False 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
# def parse(i): print(max(dists.values()))
# max_len = 0 print(len(over_thousand))
# cur_len = 0
# while i < len(data):
# c = data[i]
# if c in DIRS.keys():
# i += 1
# cur_len += 1
# elif c == "(":
# sub_len, i = parse(i + 1)
# cur_len += sub_len
# elif c == "|":
# max_len = max(max_len, cur_len)
# cur_len = 0
# i += 1
# elif c == ")":
# all_max = max(max_len, cur_len)
# return all_max, i + 1
# elif c == "$":
# max_len = max(max_len, cur_len)
# i += 1
# else:
# print(c)
# assert False
# return max_len, i
#
# print(parse(0)[0])
# g = defaultdict(set)
# def parse(xs, i):
# xs_orig = xs.copy()
# xs_done = []
#
# while i < len(data):
# c = data[i]
# if c in DIRS.keys():
# for xi in range(len(xs)):
# pos = xs[xi]
# npos = add2(pos, DIRS[c])
# g[pos].add(npos)
# g[npos].add(pos)
# xs[xi] = npos
# i += 1
# elif c == "(":
# xs, i = parse(xs, i + 1)
# elif c == "|":
# xs_done += xs
# xs = xs_orig
# i += 1
# elif c == ")":
# xs_done += xs
# return xs_done, i + 1
# elif c == "$":
# xs_done += xs
# i += 1
# else:
# assert False
# return xs_done, i
#
# parse([(0, 0)], 0)
seen = set()
dists = {}
xs = [(0, 0)]
steps = 0
while len(xs) > 0:
nxs = []
for x in xs:
if x in seen:
continue
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()))
def main():
# data = get_data(__file__).strip()
part_1(data)
if __name__ == "__main__":
main()

View File

@ -107,7 +107,7 @@ Solutions and utility script for Advent of Code challenges in Python.
- Day 17: 180:00 - Day 17: 180:00
- Day 18: 24:04 - Day 18: 24:04
- Day 19: days (super fun, but hard for me) - Day 19: days (super fun, but hard for me)
- Day 20: - Day 20: weeks (a cache was all it took - weak)
- Day 21: 28:40 (16th - brute force but still not so bad) - Day 21: 28:40 (16th - brute force but still not so bad)
- Day 22: 185:00 (should not have been so slow but was fun) - Day 22: 185:00 (should not have been so slow but was fun)
- Day 23: days - Day 23: days