Solve day 16.

This commit is contained in:
felixm 2023-12-16 00:32:59 -05:00
parent d41e4737cb
commit 87e2568b12
2 changed files with 110 additions and 0 deletions

View File

@ -12,3 +12,4 @@
- Day 10: 180:00; this one was hard for me.
- Day 11: 68:00; okay but not elegant and way too slow ofc; x-ray solution would have been neat
- Day 12: 52:00 and 22:00 for leaderboard; had the right idea and I am good at this type of problem
- Day 16: 00:27:30 745; best placement so far, of course still horribly slow

109
d16.py Normal file
View File

@ -0,0 +1,109 @@
import lib
EXAMPLE = r"""
.|...\....
|.-.\.....
.....|-...
........|.
..........
.........\
..../.\\..
.-.-/..|..
.|....-|.\
..//.|....
"""
NEW = {
'.': {
'w': (0, -1, 'w'),
'e': (0, 1, 'e'),
's': (1, 0, 's'),
'n': (-1, 0, 'n'),
},
'|': {
'w': [(1, 0, 's'), (-1, 0, 'n')],
'e': [(1, 0, 's'), (-1, 0, 'n')],
's': (1, 0, 's'),
'n': (-1, 0, 'n'),
},
'-': {
's': [(0, -1, 'w'), (0, 1, 'e')],
'n': [(0, -1, 'w'), (0, 1, 'e')],
'e': (0, 1, 'e'),
'w': (0, -1, 'w'),
},
'/': {
's': (0, -1, 'w'),
'n': (0, 1, 'e'),
'e': (-1, 0, 'n'),
'w': (1, 0, 's'),
},
'\\': {
's': (0, 1, 'e'),
'n': (0, -1, 'w'),
'e': (1, 0, 's'),
'w': (-1, 0, 'n'),
},
}
def solve(lines: list[str], second=False):
res = 0
g = list(map(list, lines))
rows = len(g)
cols = len(g[0])
if not second:
starts = [(0, 0, 'e')]
else:
starts = [(r, 0, 'e') for r in range(rows)]
starts += [(r, cols - 1, 'w') for r in range(rows)]
starts += [(0, c, 's') for c in range(cols)]
starts += [(rows - 1, c, 'n') for c in range(cols)]
for start in starts:
visited = set()
beams = [start]
while beams:
b = beams.pop()
row, col, d = b
visited.add((row, col, d))
f = g[row][col]
new = NEW[f][d]
if isinstance(new, tuple):
r, c, nd = new
nr = row + r
nc = col + c
if nr >= 0 and nc >= 0 and nr < rows and nc < cols:
if not (nr, nc, nd) in visited:
beams.append((nr, nc, nd))
else:
for r, c, nd in new:
nr = row + r
nc = col + c
if nr >= 0 and nc >= 0 and nr < rows and nc < cols:
if not (nr, nc, nd) in visited:
beams.append((nr, nc, nd))
v = set([(r, c) for (r, c, _) in list(visited)])
res = max(res, len(v))
return res
def main():
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 1:", solve(lines))
lines = lib.str_to_lines_no_empty(open("i16.txt").read())
print("Solution 1:", solve(lines))
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 2:", solve(lines, True))
lines = lib.str_to_lines_no_empty(open("i16.txt").read())
print("Solution 2:", solve(lines, True))
if __name__ == "__main__":
main()