2021-12-11 - Dumbo Octopus
(original .ipynb)
Day 11 puzzle input is a grid of integers representing "energy level" of dumbo octopuses (mine is here). Over discrete time steps their energy increments, and if at any time it exceeds 9
then this increases to neighbouring octopuses' energy levels also (and if they exceed 9 this gives a boost to neighbouring octopuses and so on, it cascades). Part 1 involves finding how many times an octopus crossed that energy level from 9
to 10
(i.e. it "flashes") over 100 time steps. Part 2 involves finding the number of time steps that pass before all octopuses "flash" in one particular step.
puzzle_input_str = open("puzzle_input/day11.txt").read() test_input_str = """5483143223 2745854711 5264556173 6141336146 6357385478 4167524645 2176841721 6882881134 4846848554 5283751526""" from advent import neighbours8 def parse_input_lines(input_str): return [ [int(c) for c in line] for line in input_str.split("\n") ] def increase_neighbours(grid, r, c, flashed): neighbours = neighbours8(grid, r, c) for nr, nc in neighbours: grid[nr][nc] += 1 if grid[nr][nc] > 9 and not ((nr,nc) in flashed): flashed.add((nr, nc)) increase_neighbours(grid, nr, nc, flashed) def advance_octopuses(grid): flashed = set() for r, row in enumerate(grid): for c, col in enumerate(row): grid[r][c] += 1 if grid[r][c] > 9 and not ((r,c) in flashed): flashed.add((r,c)) increase_neighbours(grid, r, c, flashed) return flashed def part_one(input_str, steps=100): grid = parse_input_lines(input_str) total_flashes = 0 while steps > 0: flashed = advance_octopuses(grid) total_flashes += len(flashed) for r, c in flashed: grid[r][c] = 0 steps -= 1 return total_flashes assert 1656 == part_one(test_input_str) print("part one:", part_one(puzzle_input_str))
part one: 1571
from advent import grid_animated_render_frame, grid_animated_combine palette = {n:f"#00{hex(n)[2:]}" for n in range(10)} palette[0] = "#fff" def part_two(input_str, show_image=True): grid = parse_input_lines(input_str) total_octopuses = len(grid) * len(grid[0]) step = 0 flashed = set() image_frames = [grid_animated_render_frame(grid, palette)] while len(flashed) != total_octopuses: flashed = advance_octopuses(grid) for r, c in flashed: grid[r][c] = 0 step += 1 image_frames.append( grid_animated_render_frame(grid, palette) ) grid_animated_combine(image_frames, "day11-p2.gif", show=show_image) return step assert 195 == part_two(test_input_str, False) print("part two:", part_two(puzzle_input_str))
part two: 387