|
|
@ -10,6 +10,8 @@ Transitions are periodic; since successor of every state is clearly defined, and |
|
|
|
this means that no matter at what state we start, we will eventually find ourselves in a loop with the length lower than 200k. |
|
|
|
this means that no matter at what state we start, we will eventually find ourselves in a loop with the length lower than 200k. |
|
|
|
There might be several non-intersecting loops. |
|
|
|
There might be several non-intersecting loops. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Solving with brute force |
|
|
|
|
|
|
|
|
|
|
|
One way to solve the problem would be to use some complicated math in order to compute the result. |
|
|
|
One way to solve the problem would be to use some complicated math in order to compute the result. |
|
|
|
Another, to brute force the result naively, by doing what the puzzle describes: |
|
|
|
Another, to brute force the result naively, by doing what the puzzle describes: |
|
|
|
running several "ghosts", one from each starting state, and on every step checking if all the current states are "ending". |
|
|
|
running several "ghosts", one from each starting state, and on every step checking if all the current states are "ending". |
|
|
@ -43,12 +45,12 @@ So ultimately, every step is just six bitwise-ands, one comparison |
|
|
|
(which is only true once we found the result, meaning that there is no performance penalty for branch misprediction), |
|
|
|
(which is only true once we found the result, meaning that there is no performance penalty for branch misprediction), |
|
|
|
and six dereferences and assignments. |
|
|
|
and six dereferences and assignments. |
|
|
|
|
|
|
|
|
|
|
|
The resulting performance is over 100 million steps per second (single-threaded), |
|
|
|
The resulting performance (single-threaded) on my laptop is |
|
|
|
meaning that we get to ~250 billion steps in just half an hour. |
|
|
|
over 100 million steps per second, or 500 billions per hour. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The correct result for the puzzle input I got is around 15 trillion, I got it in ~30 hours. |
|
|
|
|
|
|
|
|
|
|
|
Unfortunately, the result it produces (around ~250 billion) is apparently incorrect; |
|
|
|
## Solving with math |
|
|
|
it is not accepted by AoC website. |
|
|
|
|
|
|
|
Must be some bug somewhere, even though it works correctly on the (modified) sample input. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Another option, with math, would be to iterate over all possible direction numbers, |
|
|
|
Another option, with math, would be to iterate over all possible direction numbers, |
|
|
|
and for every direction number (out of 270), and for each permutation of final nodes (6^6~=47k) compute: |
|
|
|
and for every direction number (out of 270), and for each permutation of final nodes (6^6~=47k) compute: |
|
|
@ -66,4 +68,46 @@ With A being the first time when we reach this configuration. |
|
|
|
|
|
|
|
|
|
|
|
And then we would just need to find the smallest A for all ~10 million configurations. |
|
|
|
And then we would just need to find the smallest A for all ~10 million configurations. |
|
|
|
|
|
|
|
|
|
|
|
But I can't be bothered to do this now. |
|
|
|
But I can't be bothered to do this now. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Solving as everybody else did |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
It seems that most people computed "steps to the first xxZ" for every starting xxA position, |
|
|
|
|
|
|
|
and then just computed lowest common multiple of these six numbers. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Such an answer would only be correct if all of the following assumptions hold: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. From any xxA point, only one xxZ point can be reached |
|
|
|
|
|
|
|
(counterexample, even with a single direction: `AAA -> XXZ -> YYZ -> XXZ`); |
|
|
|
|
|
|
|
2. From that Z point, time until next entry into this point does not depend on the current step number |
|
|
|
|
|
|
|
(i.e. we always return to that point in `N` steps for some `N`, and never return to it in less than `N`); |
|
|
|
|
|
|
|
3. Number of steps between Z points is the same as number of steps from A point to Z point |
|
|
|
|
|
|
|
(counterexamples, even with a single direction: `AAA -> BBB -> CCC -> ZZZ -> CCC -> ZZZ`; |
|
|
|
|
|
|
|
`AAA -> BBB -> ZZZ -> CCC -> AAA -> BBB -> ZZZ`). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Turns out that all puzzle inputs are carefully crafted in such a way that all three assumptions hold, |
|
|
|
|
|
|
|
so that a naive "lowest common multiple" answer happens to be correct for these inputs. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Yet nowhere does the text of the puzzle say that this should be the case. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
And it seems that a lot of people did not even explicitly made these assumptions. |
|
|
|
|
|
|
|
They just had an incorrect idea that LCM should be the solution, without understanding why... |
|
|
|
|
|
|
|
and this incorrect idea just happened to produce the correct answer for this specific input. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
I don't like making assumptions like these, and I prefer to make more or less universal solutions, |
|
|
|
|
|
|
|
those that work on everybody's input (and even if my input had these magic properties, |
|
|
|
|
|
|
|
there is no guarantee other inputs do). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The only assumptions I made in my solution are: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1. That there is an answer; |
|
|
|
|
|
|
|
2. That the puzzle input contains at most 270 directions, at most 896 lines, and at most six entry points; |
|
|
|
|
|
|
|
3. That the answer is below ~100 trillions (the most dangerous assumption). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
That said, attempting to solve the task "with math" (as described above) |
|
|
|
|
|
|
|
would quickly result in understanding that instead of 6^6 possible "start nodes -> end nodes" combinations, |
|
|
|
|
|
|
|
only one is possible, meaning that only 270 configurations (instead of 10 millions) should be checked, |
|
|
|
|
|
|
|
and only 3300 values (instead of 20k) have to be precomputed, with ~400k operations for each. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
That would be the assumption 1 listed above ("from any xxA point, only one xxZ point can be reached"), |
|
|
|
|
|
|
|
which is also the one easiest to check. |
|
|
|