From 36094741a5a60c6499fb54961eb245b9823e64be Mon Sep 17 00:00:00 2001 From: Christoph Stahl Date: Thu, 14 Dec 2023 09:20:08 +0100 Subject: [PATCH] Forgot to commit Day13 --- aoc/day13.py | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 aoc/day13.py diff --git a/aoc/day13.py b/aoc/day13.py new file mode 100644 index 0000000..2ca004e --- /dev/null +++ b/aoc/day13.py @@ -0,0 +1,90 @@ +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()