91 lines
2.7 KiB
Python
91 lines
2.7 KiB
Python
from enum import Enum
|
|
|
|
from tools.aoc import AOCDay
|
|
from tools.coordinate import Coordinate
|
|
from tools.grid import Grid
|
|
from typing import Any
|
|
|
|
|
|
DIRECTIONS = [
|
|
Coordinate(0, -1),
|
|
Coordinate(1, 0),
|
|
Coordinate(0, 1),
|
|
Coordinate(-1, 0)
|
|
]
|
|
|
|
|
|
class NodeState(Enum):
|
|
CLEAN = 0
|
|
WEAKENED = 1
|
|
INFECTED = 2
|
|
FLAGGED = 3
|
|
|
|
|
|
class Day(AOCDay):
|
|
inputs = [
|
|
[
|
|
(5587, "input22_test"),
|
|
(5460, "input22")
|
|
],
|
|
[
|
|
(2511944, "input22_test"),
|
|
(2511702, "input22")
|
|
]
|
|
]
|
|
|
|
def get_init_state(self) -> (Grid, int, Coordinate):
|
|
grid = Grid.from_str(
|
|
"/".join(self.getInput()),
|
|
true_char='#',
|
|
true_value=NodeState.INFECTED,
|
|
default=NodeState.CLEAN
|
|
)
|
|
|
|
carrier_direction_index = 0
|
|
cattier_position = Coordinate((len(self.getInput()[0]) - 1) // 2, (len(self.getInput()) - 1) // 2)
|
|
|
|
return grid, carrier_direction_index, cattier_position
|
|
|
|
def part1(self) -> Any:
|
|
grid, carrier_direction_index, carrier_position = self.get_init_state()
|
|
infect_count = 0
|
|
for _ in range(10_000):
|
|
if grid.get(carrier_position) == NodeState.INFECTED:
|
|
carrier_direction_index = (carrier_direction_index + 1) % 4
|
|
grid.set(carrier_position, NodeState.CLEAN)
|
|
else:
|
|
infect_count += 1
|
|
carrier_direction_index = (carrier_direction_index - 1) % 4
|
|
grid.set(carrier_position, NodeState.INFECTED)
|
|
|
|
carrier_position += DIRECTIONS[carrier_direction_index]
|
|
|
|
return infect_count
|
|
|
|
def part2(self) -> Any:
|
|
grid, carrier_direction_index, carrier_position = self.get_init_state()
|
|
infect_count = 0
|
|
for _ in range(10_000_000):
|
|
match grid.get(carrier_position):
|
|
case NodeState.CLEAN:
|
|
carrier_direction_index = (carrier_direction_index - 1) % 4
|
|
grid.set(carrier_position, NodeState.WEAKENED)
|
|
case NodeState.WEAKENED:
|
|
grid.set(carrier_position, NodeState.INFECTED)
|
|
infect_count += 1
|
|
case NodeState.INFECTED:
|
|
carrier_direction_index = (carrier_direction_index + 1) % 4
|
|
grid.set(carrier_position, NodeState.FLAGGED)
|
|
case NodeState.FLAGGED:
|
|
carrier_direction_index = (carrier_direction_index + 2) % 4
|
|
grid.set(carrier_position, NodeState.CLEAN)
|
|
|
|
carrier_position += DIRECTIONS[carrier_direction_index]
|
|
|
|
return infect_count
|
|
|
|
|
|
if __name__ == '__main__':
|
|
day = Day(2017, 22)
|
|
day.run(verbose=True)
|