def test_is_in(): gr = Grid(TEST_GRID_IRREG, rectangular=False) assert (gr.is_in(0, 0) == True) assert (gr.is_in(1, 6) == True) assert (gr.is_in(1, 7) == False) assert (gr.is_in(2, 6) == False) assert (gr.is_in(4, 0) == False)
def load_image(): def _bit(v): if v == ".": return "0" else: return "1" return Grid.from_file("day20.image", _bit)
def make_grid(input): ingrid = Grid(input.get_valid_lines()) grid = defaultdict(bool) for row in range(ingrid.h): for col in range(ingrid.w): if ingrid.grid[row][col] == '#': grid[(col, row, 0)] = True return grid, ((0, ingrid.w), (0, ingrid.h), (0, 1))
def main(): # Part 1 grid = Grid.from_file("day18.input") for _ in range(100): copy = grid.copy() for y in range(grid.height): for x in range(grid.width): p = Position(x, y) neighbours = [n for n in copy.neighbours(p) if copy.get(n) == '#'] match grid.get(p): case '#': if len(neighbours) != 2 and len(neighbours) != 3: grid.set(p, '.') case '.': if len(neighbours) == 3: grid.set(p, '#') print("Part one:", grid.count('#')) # Part 2 grid = Grid.from_file("day18.input") stuck = [Position(0, 0), Position(99, 0), Position(0, 99), Position(99, 99)] for p in stuck: grid.set(p, '#') for _ in range(100): copy = grid.copy() for y in range(grid.height): for x in range(grid.width): p = Position(x, y) neighbours = [n for n in copy.neighbours(p) if copy.get(n) == '#'] match grid.get(p): case '#': if len(neighbours) != 2 and len(neighbours) != 3: if p not in stuck: grid.set(p, '.') case '.': if len(neighbours) == 3: grid.set(p, '#') print("Part two:", grid.count('#'))
def part(steps): img = load_image() alg = load_algorithm() max_width = img.width + (steps*2) max_height = img.height + (steps*2) src = Grid(max_width, max_height, "0") for y in range(img.height): for x in range(img.width): imgp = Position(x, y) srcp = Position(x+(max_width-img.width)//2, y+(max_height-img.height)//2) src.set(srcp, img.get(imgp)) for step in range(steps): dst = Grid(max_width, max_height, "0") for y in range(src.height): for x in range(src.width): p = Position(x, y) dst.set(p, lookup(src, p, alg, step)) src = dst return src.count("1")
def step(grid: Grid): for y in range(grid.height): for x in range(grid.width): p = Position(x, y) grid.set(p, grid.get(p) + 1) flashed = set() while True: c = len(flashed) for y in range(grid.height): for x in range(grid.width): p = Position(x, y) if grid.get(p) > 9: if p not in flashed: flash(grid, p, flashed) if len(flashed) == c: break for p in flashed: grid.set(p, 0) return len(flashed)
def test_neighbors_8(): gr = Grid(TEST_GRID_IRREG, rectangular=False) n = sorted(gr.neighbors8(0, 5)) assert (n == [(0, 4), (1, 4), (1, 5), (1, 6)])
def test_neighbors_4_outside(): gr = Grid(TEST_GRID_IRREG, rectangular=False) n = sorted(gr.neighbors4(2, 5, outside=True)) assert (n == [(1, 5), (2, 4), (2, 6), (3, 5)])
def test_neighbors_4_wrapped(): gr = Grid(TEST_GRID_RECT) n = sorted(gr.neighbors4(0, 3, wrap=True)) assert (n == [(0, 2), (0, 4), (1, 3), (3, 3)])
def test_neighbors_4(): gr = Grid(TEST_GRID_IRREG, rectangular=False) n = sorted(gr.neighbors4(2, 5)) assert (n == [(1, 5), (2, 4)])
def part1(): grid = Grid.from_file("day11.input", int) return sum(step(grid) for _ in range(100))
def test_get_wrap(): gr = Grid(TEST_GRID_IRREG, rectangular=False) assert (gr.get_wrap(0, 0) == ' ') assert (gr.get_wrap(0, -1) == '#') assert (gr.get_wrap(5, 2) == '.') assert (gr.get_wrap(-2, 3) == '.')
def flash(grid: Grid, p: Position, flashed): flashed.add(p) for n in grid.neighbours(p, diagonal=True): grid.set(n, grid.get(n) + 1)
def test_grid_construction_irregular(): gr = Grid(TEST_GRID_IRREG, rectangular=False) assert (gr.h == 4) assert (gr.w == 7) assert (gr.min_width == 5) assert (gr.max_width == 7)
def part2(): grid = Grid.from_file("day9.input", value_fn=int) sizes = sorted([len(basin_points(grid, p)) for p in low_points(grid)], reverse=True) return sizes[0] * sizes[1] * sizes[2]
def part1(): grid = Grid.from_file("day9.input", value_fn=int) return sum(grid.get(p) + 1 for p in low_points(grid))
def main(): instructions = [Instruction.from_string(line.strip()) for line in open("day06.input").readlines()] # Part 1 grid = Grid(1000, 1000, False) for i in instructions: for y in range(i.fr.y, i.to.y+1): for x in range(i.fr.x, i.to.x+1): match i.op: case "toggle": grid.set(Position(x, y), not grid.get(Position(x, y))) case "on": grid.set(Position(x, y), True) case "off": grid.set(Position(x, y), False) print("Part one:", grid.count(True)) # Part 2 grid = Grid(1000, 1000, 0) for i in instructions: for y in range(i.fr.y, i.to.y+1): for x in range(i.fr.x, i.to.x+1): match i.op: case "toggle": grid.set(Position(x, y), grid.get(Position(x, y)) + 2) case "on": grid.set(Position(x, y), grid.get(Position(x, y)) + 1) case "off": grid.set(Position(x, y), max(0, grid.get(Position(x, y)) - 1)) print("Part two:", sum(node for node in grid.nodes))
def test_grid_construction(): gr = Grid(TEST_GRID_RECT) assert (gr.w == 5) assert (gr.h == 4) assert (gr.min_width == 5) assert (gr.max_width == 5)
def test_get(): gr = Grid(TEST_GRID_IRREG, rectangular=False) assert (gr.get(0, 0) == ' ') assert (gr.get(2, 1) == '#') assert (gr.get(1, 3) == '.')
inp = Input('input11.txt', [ """L.LL.LL.LL LLLLLLL.LL L.L.L..L.. LLLL.LL.LL L.LL.LL.LL L.LLLLL.LL ..L.L..... LLLLLLLLLL L.LLLLLL.L L.LLLLL.LL""" ]) # inp.use_test(0) orig_grid = Grid(inp.get_lines()) def surrounding_seats_part1(grid): visible_seats = defaultdict(list) for r in range(grid.h): for c in range(grid.w): if grid.get(r, c) == '.': continue visible_seats[(r, c)] = grid.neighbors8(r, c) return visible_seats def surrounding_seats_part2(grid): visible_seats = defaultdict(list) for r in range(grid.h):
def part2(): grid = Grid.from_file("day11.input", int) for n in range(1_000_000): if step(grid) == (grid.width * grid.height): return n + 1