from tools.aoc import AOCDay from tools.coordinate import Coordinate from tools.grid import Grid from typing import Any def get_reflection_value(grid: Grid, ignore: int = 0) -> int: # search horizontal for x in grid.rangeX(): nx = x + 1 col = grid.get_column(x) if col == grid.get_column(nx): match = True for dx in range(1, grid.maxX - x): if x - dx < 0: break if grid.get_column(x - dx) != grid.get_column(nx + dx): match = False break if match and nx != ignore: return nx # search vertical for y in grid.rangeY(): ny = y + 1 row = grid.get_row(y) if row == grid.get_row(ny): match = True for dy in range(1, grid.maxY - y): if y - dy < 0: break if grid.get_row(y - dy) != grid.get_row(ny + dy): match = False break if match and 100 * ny != ignore: return 100 * ny return -1 class Day(AOCDay): inputs = [ [ (405, "input13_test"), (30158, "input13_dennis"), (32035, "input13"), ], [ (400, "input13_test"), (36474, "input13_dennis"), (24847, "input13"), ], ] def parse_input(self) -> list[Grid]: return [Grid.from_data(pattern) for pattern in self.getMultiLineInputAsArray()] def part1(self) -> Any: grids = self.parse_input() return sum([get_reflection_value(grid) for grid in grids]) def part2(self) -> Any: grids = self.parse_input() ref_value = 0 for grid in grids: orig_ref = get_reflection_value(grid) found = False for x in grid.rangeX(): for y in grid.rangeY(): c = Coordinate(x, y) grid.set(c, "." if grid.get(c) == "#" else "#") v = get_reflection_value(grid, orig_ref) if v > 0: ref_value += v found = True break grid.set(c, "." if grid.get(c) == "#" else "#") if found: break return ref_value if __name__ == "__main__": day = Day(2023, 13) day.run(verbose=True)