from collections import Counter from textwrap import dedent from typing import override from unittest import TestCase from puzzles._solver import Solver class DayOneSolver(Solver): list1: list[int] list2: list[int] @override def __init__(self, puzzle_input: str): lines = (line.partition(" ") for line in puzzle_input.strip().split("\n")) list1, list2 = zip(*((int(line[0]), int(line[2])) for line in lines)) self.list1 = list(list1) self.list2 = list(list2) @override def solve_p1(self) -> int: minimum_pairs = zip(sorted(self.list1), sorted(self.list2)) distances = (abs(pair[0] - pair[1]) for pair in minimum_pairs) return sum(distances) @override def solve_p2(self) -> int: occurrences = Counter(self.list2) similarities = (value * occurrences.get(value, 0) for value in self.list1) return sum(similarities) class TestDayOneSolver(TestCase): test_input = dedent( """ 3 4 4 3 2 5 1 3 3 9 3 3 """ ) def test_parse(self): solver = DayOneSolver(self.test_input) self.assertListEqual(solver.list1, [3, 4, 2, 1, 3, 3]) self.assertListEqual(solver.list2, [4, 3, 5, 3, 9, 3]) def test_solve_p1(self): solver = DayOneSolver(self.test_input) self.assertEqual(solver.solve_p1(), 11) def test_solve_p2(self): solver = DayOneSolver(self.test_input) self.assertEqual(solver.solve_p2(), 31)