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.
This commit is contained in:
Anders Englöf Ytterström 2021-12-03 07:22:38 +01:00
parent d63c7463cc
commit 99f5385f25
2 changed files with 84 additions and 0 deletions

View file

@ -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()

View file

@ -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()