aoc2019/day15.py

86 lines
2.2 KiB
Python

from collections import deque
from intcode import IntCode
from tools.aoc import AOCDay
from tools.coordinate import Coordinate
from tools.grid import Grid
from typing import Any
MOVEMENTS = [Coordinate(0, -1), Coordinate(0, 1), Coordinate(-1, 0), Coordinate(1, 0)]
OXYGEN_POS = None
def discover(comp: IntCode, grid: Grid, pos: Coordinate, visited: set = None) -> Grid:
global OXYGEN_POS
if visited is None:
visited = set()
visited.add(pos)
for m in range(4):
next_pos = pos + MOVEMENTS[m]
if next_pos in visited:
continue
comp.addInput(m + 1)
outcome = comp.getOutput()
if outcome == 0:
grid.set(next_pos)
else:
if outcome == 2:
OXYGEN_POS = next_pos
grid = discover(comp, grid, next_pos, visited)
comp.addInput(MOVEMENTS.index(MOVEMENTS[m].reverse()) + 1)
comp.getOutput() # just ignore one to keep the queue clear
return grid
class Day(AOCDay):
inputs = [
[
(354, "input15")
],
[
(370, "input15")
]
]
def get_grid(self) -> Grid:
comp = IntCode(self.getInputAsArraySplit(",", int))
comp.start()
pos = Coordinate(0, 0)
return discover(comp, Grid(), pos)
def part1(self) -> Any:
return len(self.get_grid().getPath(Coordinate(0, 0), OXYGEN_POS, includeDiagonal=False, walls=[True])) - 1
def part2(self) -> Any:
grid = self.get_grid()
queue = deque()
queue.append(OXYGEN_POS)
grid.set(OXYGEN_POS, 2)
count = 0
grid.print(true_char='#', false_char=' ', mark=[Coordinate(0, 0), OXYGEN_POS])
while queue:
print("step", count, "=>", queue)
count += 1
next_queue = deque()
for pos in queue:
for next_pos in grid.getNeighboursOf(pos, includeDefault=True, includeDiagonal=False):
if grid.get(next_pos) is False:
next_queue.append(next_pos)
grid.set(next_pos, 2)
queue = next_queue
return count - 1
if __name__ == '__main__':
day = Day(2019, 15)
day.run(verbose=True)