116 lines
2.7 KiB
Python
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()
|