Files
aocpy/2019/d15.py
2024-08-17 16:01:06 -04:00

116 lines
2.7 KiB
Python

from lib import get_data, str_to_ints, add2
from d9 import Amp
DIRS = {1: (-1, 0), 2: (1, 0), 3: (0, -1), 4: (0, 1)}
PATH_REVERSED = {1: 2, 2: 1, 3: 4, 4: 3}
def print_field(fields, walls, pos):
dim = 40
for y in range(-dim, dim + 1):
row = ""
for x in range(-dim, dim + 1):
if (y, x) == pos:
row += "X"
elif (y, x) in fields:
row += "."
elif (y, x) in walls:
row += "|"
else:
row += " "
print(row)
def part_1(data):
xs = str_to_ints(data)
a = Amp(xs)
walls = set()
pos = (0, 0)
target = None
dir = None
path = []
dir_cmds_for_pos = {pos: [1, 2, 3, 4]}
while not a.done:
if len(dir_cmds_for_pos[pos]) > 0:
dir_cmd = dir_cmds_for_pos[pos].pop()
dir = DIRS[dir_cmd]
new_pos = add2(pos, dir)
if new_pos in dir_cmds_for_pos:
continue
a.feed(dir_cmd)
a.go()
status = a.pop()
if status == 0:
walls.add(new_pos)
elif status == 1:
pos = new_pos
path.append(dir_cmd)
elif status == 2:
pos = new_pos
path.append(dir_cmd)
target = pos
if pos not in dir_cmds_for_pos:
dir_cmds_for_pos[pos] = [1, 2, 3, 4]
elif len(path) > 0:
dir_cmd = PATH_REVERSED[path.pop()]
dir = DIRS[dir_cmd]
pos = add2(pos, dir)
a.feed(dir_cmd)
a.go()
status = a.pop()
assert status == 1 or status == 2
elif target is not None:
break
else:
break
fields = set(dir_cmds_for_pos.keys())
# print_field(fields, walls, pos)
seen = set()
to_visit = [(0, 0)]
steps = 0
while len(to_visit) > 0:
new = []
for current in to_visit:
if current == target:
print(steps)
seen.add(current)
for dir in DIRS.values():
nb = add2(current, dir)
if nb in fields and nb not in seen:
new.append(nb)
to_visit = new
steps += 1
seen = set()
to_visit = [target]
steps = 0
while len(to_visit) > 0:
new = []
for current in to_visit:
seen.add(current)
for dir in DIRS.values():
nb = add2(current, dir)
if nb in fields and nb not in seen:
new.append(nb)
to_visit = new
steps += 1
print(steps - 1)
def main():
data = get_data(__file__)
part_1(data)
if __name__ == "__main__":
main()