Reputation: 712
I have two lookup tables that I would like to eliminate with simple math if possible.
The first is a map from indices in an array to the sequence {0} => 1, {1, 2} => 2, {3, 4, 5} => 3, s.t. there is one 1, two 2s, three 3s, etc. Or visually:
lookup1[N] = {
1,
2, 2,
3, 3, 3,
4, 4, 4, 4,
5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7,
8, 8, 8, 8, 8, 8, 8, 8,
...
}
The second is for increasing sequences, the first sequence is (1), the second (1, 2), the third (1, 2, 3). It's like a modulus cycle, but increasing after each cycle. Visually:
lookup2[N] = {
1,
1, 2,
1, 2, 3,
1, 2, 3, 4,
1, 2, 3, 4, 5,
1, 2, 3, 4, 5, 6,
1, 2, 3, 4, 5, 6, 7,
1, 2, 3, 4, 5, 6, 7, 8,
1, 2, 3, 4, 5, 6, 7, 8, 9,
...
}
These need to map from indices. For the second lookup, inputs 5, 4, 3 would map to 3, 2, 1 respectively.
Are there any mathematical formulas that would produce these patterns? I would rather execute a few instructions than do a memory access.
Upvotes: 1
Views: 113
Reputation: 7824
For lookup1 this looks closely related to Triangular numbers, infact it is the inverse problem. The triangles numbers are the number of items in a triangle with n rows. So you have T1 = 1, T2 = 1+2 = 3, T3 = 1+2+3 = 6, T4 = 1+2+3+4 = 10. Or as a function f(1) = 1, f(2)=3, f(3)=6, f(4)=10.
You want to do the inverse so g(1) = 1, g(3) = 2, g(6) = 3, g(10) = 4. We worry about other values later.
There is a formula for the triangular numbers f(n) = n (n+1) / 2. And a more complex one for the inverse
g(n) = (sqrt(8 * n + 1) - 1) / 2
A little experiment shows that
ceil((sqrt(8*n+1) - 1) / 2 )
gives your desired numbers.
For the second part you can use the function for the inverse triangular number and then find the previous triangular number, and take the difference
X = ceil((sqrt(8*n+1) - 1) / 2);
T = (X * (X-1))/2 ;
print(n-T);
A slight cautionary note. At the transition points sqrt(8*n+1)
should evaluate to an odd integer value. What might happen for very large n is than rounding errors might pay a part. I've tested this to well over a million and not seen the problem occur.
Upvotes: 3