advent_of_code_2021

My attempts to work through the 2021 Advent of Code problems.
git clone https://git.eamoncaddigan.net/advent_of_code_2021.git
Log | Files | Refs | README | LICENSE

day11_part2.py (1891B)


      1 #!/usr/bin/env python
      2 """Advent of Code 2021, day 11 (part 2): Flashing octopuses
      3 For part 2, we're simulating bioluminescent octopuses again, and this time we
      4 want to find the `step` at which they all flash simultaneously."""
      5 
      6 # I think I can pretty much use everything from part 1 here and just update the
      7 # solving code
      8 
      9 import numpy as np
     10 from day11_part1 import (EXAMPLE_INPUT,
     11                          simulate_step)
     12 from utils import get_puzzle_input, convert_input_to_array
     13 
     14 def all_flashed(energy_levels: np.ndarray) -> bool:
     15     """Detects the moment when all energy levels have been reset to 0"""
     16     return not energy_levels.any()
     17 
     18 def run_simulation_until_synchronized(energy_levels: np.ndarray) -> int:
     19     """Run the simulation from the initial 2d array of energy levels until all
     20     octopuses flash at the same time, and return the step number at which it
     21     occurred"""
     22     # Leaning on Python's nice iterator behavior and for/else syntax: no need
     23     # to risk an infinite loop, we can set a "reasonable" limit of iterations
     24     # up front. Also I just love underscores in numeric literals.
     25     for num_steps in range(1_000_000):
     26         energy_levels = simulate_step(energy_levels)[0]
     27         if all_flashed(energy_levels):
     28             break
     29     else:
     30         raise RuntimeError("No synchronized flash detected after many steps")
     31 
     32     # We're counting steps from 1 apparently
     33     return num_steps + 1
     34 
     35 def solve_puzzle(input_string: str) -> int:
     36     """Return the numeric solution to the puzzle"""
     37     return run_simulation_until_synchronized(
     38         convert_input_to_array(input_string)
     39     )
     40 
     41 def main() -> None:
     42     """Run when the file is called as a script"""
     43     assert solve_puzzle(EXAMPLE_INPUT) == 195
     44     # Is that you, Shevek?
     45     print("Number of steps to simultaneity:",
     46           solve_puzzle(get_puzzle_input(11)))
     47 
     48 if __name__ == "__main__":
     49     main()