90 lines
2.2 KiB
Python
90 lines
2.2 KiB
Python
from __future__ import annotations
|
|
from array import array
|
|
from typing import TypeAlias
|
|
from itertools import groupby, islice
|
|
|
|
from .aoc import Aoc2, AocSameParser
|
|
from .day11 import Matrix
|
|
|
|
|
|
P1: TypeAlias = list[Matrix]
|
|
|
|
|
|
class Day13(AocSameParser[P1], Aoc2[P1, P1]):
|
|
def parseinput(self, inpt: str) -> P1:
|
|
fields = inpt.split("\n\n")
|
|
|
|
return [Matrix(group) for group in fields]
|
|
|
|
@staticmethod
|
|
def check_horiz(m: Matrix, max_diffs: int) -> int | None:
|
|
rows = list(m.iter_rows())
|
|
|
|
nr_rows = len(rows)
|
|
|
|
for x in range(1, nr_rows):
|
|
y = 0
|
|
if x > nr_rows / 2:
|
|
y = x + x - nr_rows
|
|
|
|
diff = Day13.diff_lines(rows[y:x], list(reversed(rows[x : x + x - y])))
|
|
if diff == max_diffs:
|
|
return x
|
|
|
|
return None
|
|
|
|
@staticmethod
|
|
def check_vert(m: Matrix, max_diffs: int) -> int | None:
|
|
cols = list(m.iter_cols())
|
|
|
|
nr_cols = len(cols)
|
|
|
|
for x in range(1, nr_cols):
|
|
y = 0
|
|
if x > nr_cols / 2:
|
|
y = x + x - nr_cols
|
|
|
|
diff = Day13.diff_lines(cols[y:x], list(reversed(cols[x : x + x - y])))
|
|
|
|
if diff == max_diffs:
|
|
return x
|
|
|
|
return None
|
|
|
|
@staticmethod
|
|
def diff_lines(a: list[array[str]], b: list[array[str]]) -> int:
|
|
return sum(map(lambda x, y: Day13.diff_line(x, y), a, b))
|
|
|
|
@staticmethod
|
|
def diff_line(a: array[str], b: array[str]) -> int:
|
|
return sum(map(lambda x, y: x != y, a, b))
|
|
|
|
@staticmethod
|
|
def compute(inpt: P1, max_diffs: int) -> int:
|
|
verts = 0
|
|
horiz = 0
|
|
for m in inpt:
|
|
mverts = Day13.check_vert(m, max_diffs)
|
|
if mverts is not None:
|
|
verts += mverts
|
|
else:
|
|
mhoriz = Day13.check_horiz(m, max_diffs)
|
|
if mhoriz is not None:
|
|
horiz += mhoriz
|
|
|
|
return verts + 100 * horiz
|
|
|
|
def part1(self, inpt: P1) -> int:
|
|
return self.compute(inpt, 0)
|
|
|
|
def part2(self, inpt: P1) -> int:
|
|
return self.compute(inpt, 1)
|
|
|
|
|
|
def main() -> None:
|
|
aoc = Day13(2023, 13, example_code_nr2=0)
|
|
aoc.run()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|