AoC 2021 - Day 3
Today’s challenge is here. It turned out to be pretty tricky with many possible approaches to solve it. First task was pretty trivial, but I kind of feel like my second solution was a bit overengineered 😄
Loading data is pretty simple, all I had to do here was to load strings:
Task 1
Here we had to find two binary numbers based on the frequency of digits at each position. I used a dict
to store count of 0
s and 1
s at each position for all binary numbers. Then I used this dict
to construct two binary numbers. The number for gamma consists of the most frequent digits at each position, and the number for epsilon consists of the least frequent digits at each position.
After finding the binary numbers I converted both of them to decimal and multiplied them. An interesting part here is the usage of zip(*iterable])
notation to turn a list of tuples into a tuple of lists.
It can be visualized as:
[(x1, y1), (x2, y2), ...] -> [[x1, x2, ...], [y1, y2, ...]]
Task 2
Here we had to find a single remaining binary number for each case - oxygen and carbon. I used a dict
once again to store the frequency of each digit at each position. Then I used this data to filter out the binary numbers until there is only one left. The part where I filter the numbers is also where I update the dict by subtracting the frequency, so that it stays up to date for the next iteration.
Here I use the function to find the multiply from the resulting numbers for oxygen and cargon:
Bonus: Task 1 in NumPy
The way this works is it loads all data into a single matrix, calculates mean value for each place, converts to nearest integer. The other thing is the logical_not
of that. Then you get decimal number by calculating dot product of the binary number and a [1, 2, 4, 8, ...]
vector reversed.