from tools.aoc import AOCDay from typing import Any from tools.coordinate import Coordinate from tools.grid import Grid def simulate(starfield: Grid, print_grid: bool = True) -> int: minSteps = 1e9 for pos in starfield.getActiveCells(): vec = starfield.get(pos)[0] min_x_steps = abs(pos.x // vec.x) - 10 min_y_stepd = abs(pos.y // vec.y) - 10 minSteps = min(minSteps, min_x_steps, min_y_stepd) new_starfield = Grid() for pos in starfield.getActiveCells(): new_starfield.set(pos + starfield.get(pos)[0] * minSteps, starfield.get(pos)) starfield = new_starfield for i in range(20000): new_starfield = Grid() for pos in starfield.getActiveCells(): for vec in starfield.get(pos): target = pos + vec if new_starfield.get(target): new_starfield.get(target).append(vec) else: new_starfield.set(target, [vec]) starfield = new_starfield if starfield.maxY - starfield.minY == 9: if print_grid: starfield.print(bool_mode=True) return i + 1 + minSteps class Day(AOCDay): inputs = [ [ ("BFFZCNXE", "input10"), ], [ (10391, "input10"), ] ] def getInputGrid(self) -> Grid: grid = Grid() for line in self.getInput(): (pos_str, vel_str) = line.split("> ") (pos_x, pos_y) = map(int, pos_str.split("<")[1].split(",")) (vel_x, vel_y) = map(int, vel_str[:-1].split("<")[1].split(",")) grid.set(Coordinate(pos_x, pos_y), [Coordinate(vel_x, vel_y)]) return grid def part1(self) -> Any: starfield = self.getInputGrid() simulate(starfield) return "BFFZCNXE" def part2(self) -> Any: starfield = self.getInputGrid() return simulate(starfield, print_grid=False) if __name__ == '__main__': day = Day(2018, 10) day.run(verbose=True)