2021-12-11 12:16:48 +01:00

98 lines
3.0 KiB
Python

# SPDX-License-Identifier: MIT
# Copyright (c) 2021 Akumatic
#
# https://adventofcode.com/2021/day/11
class Octopus:
def __init__(self, idx, energy):
self.idx = idx
self._get_neighbor_idx()
self.energy = energy
self.flashed = False
self.neighbors = list()
def _get_neighbor_idx(self):
if self.idx == 0: # top left corner
self.neighbor_idx = [self.idx + i for i in (1, 10, 11)]
elif self.idx == 9: # top right corner
self.neighbor_idx = [self.idx + i for i in (-1, 9, 10)]
elif self.idx == 90: # bottom left corner
self.neighbor_idx = [self.idx + i for i in (-10, -9, 1)]
elif self.idx == 99: # bottom right corner
self.neighbor_idx = [self.idx + i for i in (-11, -10, -1)]
elif self.idx < 10: # top edge
self.neighbor_idx = [self.idx + i for i in (-1, 1, 9, 10, 11)]
elif self.idx > 90: # bottom edge
self.neighbor_idx = [self.idx + i for i in (-11, -10, -9, -1, 1)]
elif self.idx % 10 == 0: # left edge
self.neighbor_idx = [self.idx + i for i in (-10, -9, 1, 10, 11)]
elif self.idx % 10 == 9: # right edge
self.neighbor_idx = [self.idx + i for i in (-11, -10, -1, 9, 10)]
else:
self.neighbor_idx = [self.idx + i for i in (-11, -10, -9, -1, 1, 9, 10, 11)]
def add_neighbor(self, neighbor):
self.neighbors.append(neighbor)
def flash(self):
self.flashed = True
for neighbor in self.neighbors:
neighbor.energy += 1
def read_file(filename: str = "input.txt") -> list:
with open(f"{__file__.rstrip('code.py')}{filename}", "r") as f:
lines = [line for line in f.read().strip().split("\n")]
values = list()
for line in lines:
values += [int(x) for x in list(line)]
return values
def create_octopuses(vals: int) -> list:
octopuses = [Octopus(i, vals[i]) for i in range(len(vals))]
for octopus in octopuses:
for i in octopus.neighbor_idx:
octopus.add_neighbor(octopuses[i])
return octopuses
def step(octopuses: list) -> int:
flashes = 0
for octopus in octopuses:
octopus.energy += 1
repeat = True
while repeat:
repeat = False
for octopus in octopuses:
if octopus.energy > 9 and octopus.flashed == False:
octopus.flash()
flashes += 1
repeat = True
for octopus in octopuses:
if octopus.flashed:
octopus.flashed = False
octopus.energy = 0
return flashes
def part1(vals: list) -> int:
flashes = 0
octopuses = create_octopuses(vals)
for _ in range(100):
flashes += step(octopuses)
return flashes
def part2(vals: list) -> int:
octopuses = create_octopuses(vals)
count = 0
flashes = 0
while flashes != 100:
flashes = step(octopuses)
count += 1
return count
if __name__ == "__main__":
vals = read_file()
print(f"Part 1: {part1(vals)}")
print(f"Part 2: {part2(vals)}")