An implementation of grambulation in Rust, as initially explained on Reddit and more precisely defined for Code Golf.
The approach described below may seem confusing, but it avoids any loops that change with the inputs; the only loops in my code iterate only over the 4 types of Diagonal
.
This allows very low execution time regardless of input; results from a rough test on my computer:
value_a |
value_b |
time per iteration, average of 100'000'000 |
---|---|---|
1 | 2 | 529ns |
10 | 25 | 395ns |
100000 | 2500000 | 601ns |
100000000000000 | 2500000000000000 | 364ns |
These were just the first numbers I chose and this is in no way a proper test, but it'll do for an impression.
If the MathJax doesn't render, try viewing the README on GitHub.
To grambulate two numbers
To do so, we can calculate the 'rings'
Diagonal | |
---|---|
top-right | 3 |
top-left | 5 |
bottom-left | 7 |
bottom-right | 9 |
This gives us 4 values near our desired value (either
Now that we have both pairs of coordinates, we can calculate the connecting vector
Once we know
We now determine which diagonal we need to calculate, retrieve the value using the above formula and subtract the difference of the relevant coordinate.
Let
We can use the ring formula to determine
Starting with
The closest of these values that is
Moving on to
The closest of these values that is
As we determined the closest value ahead of
Now we know:
The connecting vector is
Applying this to
As the value is not directly on a diagonal (
condition | diagonal |
---|---|
top-left | |
top-right | |
bottom-left | |
bottom-right |
We need the top-left diagonal. We also know that our value is on ring
That's it!