Module aoc::year2018::day01

source ·
Expand description

§Chronal Calibration

The simplest approach to part two is to store previously seen numbers in a HashSet then stop once a duplicate is found. However this approach requires scanning the input of ~1,000 numbers multiple times, around 150 times for my input.

A much faster O(nlogn) approach relies on the fact that each frequency increases by the same amount (the sum of all deltas) each time the list of numbers is processed. For example:

   Deltas: +1, -2, +3, +1 =>
   0    1   -1    2
   3    4    2    5

Two frequencies that are a multiple of the sum will eventually repeat. First we group each frequencies by its remainder modulo the sum, using rem_euclid to handle negative frequencies correctly, Then we sort, first by the remainder to group frequencies that can repeat together, then by the frequency increasing in order to help find the smallest gap between similar frequencies, then lastly by index as this is needed in the next step.

For the example this produces [(0, 0, 0), (1, 1, 1), (2, -1, 2), (2, 2, 3)]. Then we use a sliding windows of size two to compare each pair of adjacent canditates, considering only candidates with the same remainder. For each valid pair we then produce a tuple of (frequency gap, index, frequency).

Finally we sort the tuples in ascending order, first by smallest frequency gap, breaking any ties using the index to find frequencies that appear earlier in the list. The first tuple in the list gives the result, in the example this is [(3, 2, 2)].

Functions§