And we are off for 2021! (I, on the other hand, started late this year). The sleigh keys went overboard and our job this year is to collect enough stars to power the submarine experimental key-finding antenna. Any excuse for an advent calendar :-D
To kick off, we are asked to analyze sonar data. Part one is about counting increments. Easy peasy, use a paired window iterator to compare the previous with the current value, and sum the booleans (Python's boolean type is a subclass of its integer type, and False
has the value 0, True
has the value 1, so counting a series of boolean tests is as easy as passing the series to sum()
).
The[itertools
module documentation page has a recipes section, which includes a more generic sliding_window()
function definition for arbitrary size windows, which I've used here.
import aocd
scans = [int(depth) for depth in aocd.get_data(day=1, year=2021).splitlines()]
from collections import deque
from itertools import islice
def sliding_window(iterable, n):
# sliding_window('ABCDEFG', 4) -> ABCD BCDE CDEF DEFG
it = iter(iterable)
window = deque(islice(it, n), maxlen=n)
if len(window) == n:
yield tuple(window)
for x in it:
window.append(x)
yield tuple(window)
def count_increases(scans):
return sum(b > a for a, b in sliding_window(scans, 2))
print("Part 1:", count_increases(scans))
Part 1: 1791
My decision to use the generic sliding window function proved very handy for part 2, as this part is specifically about increasing the size of the sliding window!
Of course, Eric Wastl makes it slightly more complicated by asking you to combine sliding windows. We need a pair-wise sliding window over a size-3 sliding window that sums the 3 scans in that window. Still, Python itertools makes this super easy.
def count_3windowsum_increases(scans):
three_window_sum = (sum(window) for window in sliding_window(scans, 3))
return count_increases(three_window_sum)
print("Part 2:", count_3windowsum_increases(scans))
Part 2: 1822