2022-12-14 - Regolith Reservoir
(original .ipynb)
Day 14 puzzle input is a sequence of "->"-separated point pairs which describe rock formations (mine is here). Part 1 dropping grains of sand from a given point, until the sand overflows and drops off to "the abyss". Part two involves assuming there is no abyss, but an infinitely wide floor 2 rows below the lowest rock and pouring sand in until it builds up to the top and finding how many grains this takes.
puzzle_input_str = open("./puzzle_input/day14.txt").read() test_input_str = """498,4 -> 498,6 -> 496,6 503,4 -> 502,4 -> 502,9 -> 494,9""" def parse_point(point_str): col, row = point_str.split(",") return int(row), int(col) def parse_line(line): return [parse_point(point) for point in line.split(" -> ")] def draw_line(grid, point1, point2): from_point = min(point1, point2) to_point = max(point1, point2) from_row, from_col = from_point to_row, to_col = to_point for row in range(from_row, to_row+1): for col in range(from_col, to_col+1): grid[row][col] = "#" def build_grid(shapes, with_floor=False): max_row, max_col = 0, 0 for shape in shapes: for row, col in shape: max_row = max(max_row, row) max_col = max(max_col, col) max_col *= 2 # why not grid = [] for row in range(max_row+1): grid.append(["." for _ in range(max_col+1)]) for shape in shapes: point = shape[0] for next_point in shape[1:]: draw_line(grid, point, next_point) point = next_point if with_floor: grid.append(["." for _ in range(max_col+1)]) grid.append(["#" for _ in range(max_col+1)]) return grid def add_sand(grid): r, c = 0, 500 directions = ((1, 0), (1, -1), (1, 1)) moved = True while moved: if r+1 == len(grid): return False moved = False for dr, dc in directions: if grid[r+dr][c+dc] == ".": r += dr c += dc moved = True break grid[r][c] = "o" return True def part_one(input_str): shapes = [parse_line(line) for line in input_str.splitlines()] grid = build_grid(shapes) sand = 0 while add_sand(grid): sand += 1 return sand assert 24 == part_one(test_input_str) print("part one:", part_one(puzzle_input_str))
part one: 674
def add_sand(grid): r, c = 0, 500 directions = ((1, 0), (1, -1), (1, 1)) moved = True while moved: moved = False for dr, dc in directions: if r+1 < len(grid) and grid[r+dr][c+dc] == ".": r += dr c += dc moved = True break if r == 0 and not moved: return False grid[r][c] = "o" return True def part_two(input_str): shapes = [parse_line(line) for line in input_str.splitlines()] grid = build_grid(shapes, True) sand = 1 while add_sand(grid): sand += 1 return sand assert 93 == part_two(test_input_str) print("part two:", part_two(puzzle_input_str))
part two: 24958