From 99f5385f252b684c49f78a17b99c2cd989c4b6c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Ytterstr=C3=B6m?= Date: Fri, 3 Dec 2021 07:22:38 +0100 Subject: [PATCH] Solve 2021:3 "Binary Diagnostic" Yes, I do "".join(). Python is not always beautiful. I began reusing part 1 for part 2, until I realised you cannot reuse the Counter.most_common, and you need the actual values to be able to se equal occourences. I probably lost 5-15 minutes just to dribble with 3 levels of nested objects. In GMT+1 before coffee, that cost me. Part 2 was way uglier before some well motivated refactoring. Since all tests and expected output were in place, refactoring was easy. --- 2021-python/solutions/day_03.py | 43 ++++++++++++++++++++++++++++++++ 2021-python/tests/test_day_03.py | 41 ++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 2021-python/solutions/day_03.py create mode 100644 2021-python/tests/test_day_03.py diff --git a/2021-python/solutions/day_03.py b/2021-python/solutions/day_03.py new file mode 100644 index 0000000..586446f --- /dev/null +++ b/2021-python/solutions/day_03.py @@ -0,0 +1,43 @@ +from collections import Counter +from solutions import BaseSolution + + +class Solution(BaseSolution): + input_file = "03.txt" + + def __str__(self): + return "Day 3: Binary Diagnostic" + + def parse_input(self, data): + return data.split() + + def solve(self, puzzle_input): + e, g = self._eg(puzzle_input) + return int("".join(g), 2) * int("".join(e), 2) + + def solve_again(self, puzzle_input): + og = self._ogco2(puzzle_input, "1") + co2 = self._ogco2(puzzle_input, "0") + return int("".join(og), 2) * int("".join(co2), 2) + + def _eg(self, puzzle_input): + e = [] + g = [] + for r in zip(*puzzle_input): + x, y = Counter(r).most_common() + e.append(x[0]) + g.append(y[0]) + return e, g + + def _ogco2(self, values, default, i=0): + eg = [Counter(r).most_common() for r in zip(*values)] + k = default if eg[i][0][1] == eg[i][1][1] else eg[i][abs(int(default) - 1)][0] + rem = [v for v in values if v[i] == k] + if len(rem) == 1: + return rem + return self._ogco2(rem, default, i + 1) + + +if __name__ == "__main__": + solution = Solution() + solution.show_results() diff --git a/2021-python/tests/test_day_03.py b/2021-python/tests/test_day_03.py new file mode 100644 index 0000000..ab4341d --- /dev/null +++ b/2021-python/tests/test_day_03.py @@ -0,0 +1,41 @@ +import unittest + +from solutions.day_03 import Solution + + +class Day03TestCase(unittest.TestCase): + def setUp(self): + self.solution = Solution() + self.puzzle_input = self.solution.parse_input( + """ + 00100 +11110 +10110 +10111 +10101 +01111 +00111 +11100 +10000 +11001 +00010 +01010 + """ + ) + + def test_parse_puzzle_input(self): + data = """ + 00100 +11110 + """ + assert self.solution.parse_input(data) == ["00100", "11110"] + + def test_solve_first_part(self): + assert self.solution.solve(self.puzzle_input) == 198 + + def test_solve_second_part(self): + assert self.solution.solve_again(self.puzzle_input) == 230 + + +if __name__ == "__main__": + unittest.main()