6
votes
Day 16: Flawed Frequency Transmission
Today's problem description: https://adventofcode.com/2019/day/16
Join the Tildes private leaderboard! You can do that on this page, by entering join code 730956-de85ce0c
.
Please post your solutions in your own top-level comment. Here's a template you can copy-paste into your comment to format it nicely, with the code collapsed by default inside an expandable section with syntax highlighting (you can replace python
with any of the "short names" listed in this page of supported languages):
<details>
<summary>Part 1</summary>
```python
Your code here.
```
</details>
This, like the n-body problem, took a bit of doing and requires a few important insights.
Part 1 can be solved more or less naively, in the way you'd expect. Part 2 on the other hand requires substantial optimization.
Part 1 Crystal
My approach was straightforward: create a function
fft_base_pattern
that can expand the base pattern for the appropriate position, then loop through the input, multiply each digit by the matching value from the base pattern, sum all the results, take the abs (since some will be negative) then return the last digit of each.Already this is a little slow, but it gets the job done.
Part 2 - minor spoilers
We're going to need to massively optimize the first part, and there's a few things that work in our favor, the first relates to how the base pattern expands for each index.
In my case it helped to generate a table of patterns for each digit:
Part 2 - moderate spoilers
Looking at the table, we can see that something important happens halfway through the list: the patterns from here out will always be n-1 0s, followed by nothing but 1s to the end of the list.Fortunately, my input (and I expect all of them) are constructed in such a way that the offset is more than halfway through the list. This means that 1) we can ignore the first part of the input (everything before the offset), and 2) everything after the offset is just going to be the sum of the following digits (mod 10).
Part 2 - solution - Crystal
Unfortunately, even with the realization that we "simply" have to sum the digits of the latter part of the input, my code was too slow, and I needed to improve it a bit more. The last change I needed to make was to pre-compute the "sum of following digits" for each value past the offset. The pre-compute step has to be fast too, and can be optimized by doing it in reverse, which allows us to easily re-use the sum of the previous position.