From 36e238b64a741910ce5f999c7c936b03eff4d93f Mon Sep 17 00:00:00 2001 From: Inga Date: Sun, 10 Dec 2023 12:17:40 +0000 Subject: [PATCH] day 8, part 2 (final solution), updated readme --- day08-hard/README.md | 56 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/day08-hard/README.md b/day08-hard/README.md index 8faaf1f..77e4214 100644 --- a/day08-hard/README.md +++ b/day08-hard/README.md @@ -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. 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. 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". @@ -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), and six dereferences and assignments. -The resulting performance is over 100 million steps per second (single-threaded), -meaning that we get to ~250 billion steps in just half an hour. +The resulting performance (single-threaded) on my laptop is +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; -it is not accepted by AoC website. -Must be some bug somewhere, even though it works correctly on the (modified) sample input. +## Solving with math 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: @@ -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. -But I can't be bothered to do this now. \ No newline at end of file +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.