For optimizing the calculations instead of the
$$
D(n)=(2[n/5]∗D([n/5])∗D(n \mod5)) \mod10
$$
we can calculate
$$
D(n)=(LastDigitOf(2⌊n/5⌋)∗D(⌊n/5⌋)∗D(n \mod5)) \mod10
$$
Modified formula is:
$$
D(0) = 1 \\
D(1) = 1 \\
D(2) = 2 \\
D(3) = 6 \\
D(4) = 4 \\
D(5) = 2 \\
D(6) = 2 \\
D(7) = 4 \\
D(8) = 2 \\
D(9) = 8 \\
D(n) = (LastDigitOf(2^{\lfloor n/5 \rfloor}) * D(\lfloor n/5 \rfloor) * D(n \mod 5)) \mod 10, \;where \;n > 9
$$
How?
The original formula is $D(n) = (2^{[n/5]} * D([n/5]) * D(n \mod 5)) \mod 10$
But there is a problem: we need to calculate $2^{[n/5]}$. For example if $n = 10 000 $ then we need to calculate $2^{2000}$ which is already too hard (in JS it will output Infinity
). But I discovered that we don't need to calculate it instead of this we just need to calculate the last digit of $2^{[n/5]}$. Why? Because each time we just need to calculate the last digit of $2^{[n/5]} * D([n/5]) * D(n \mod 5)$
Theorem
The last digit of multiplication is the last digit of multiplication of last digits of each multiplier
Proof
Let's say we have two numbers $a$ and $b$. We can represent each of them to the power of 10
:
$$
a = x_n * 10^n + x_{n - 1} * 10^{n - 1} + \ldots + x_1 * 10^1 + x_0 \\
b = y_n * 10^m + y_{m - 1} * 10^{m - 1} + \ldots + y_1 * 10^1 + y_0
$$
or
$$
a = (x_n * 10^{n - 1} + x_{n - 1} * 10^{n - 2} + \ldots + x_1) * 10 + x_0 \\
b = (y_n * 10^{m - 1} + y_{m - 1} * 10^{m - 2} + \ldots + y_1) * 10 + y_0
$$
When we multiply them we will get:
$$
a * b = (...) * 10 + x_0 * y_0
$$
Now it is clear that the last digit of multiplication is the last digit of $x_0 * y_0$, where the $x_0$ and $y_0$ are the last digits of $a$ and $b$ respectively. So we proved the theorem
Now we need to find the last digits of powers of 2
. Let's write some of them:
$$
2^0 = 1 \\
2^1 = 2 \\
2^2 = 4 \\
2^3 = 8 \\
2^4 = 16 \\
2^5 = 32 \\
2^6 = 64 \\
2^7 = 128 \\
2^8 = 256
$$
Now we can see the pattern 1 (2 4 8 6) (2 4 8 6)
and can write it $(k = [n / 5])$:
if (k == 0) return 1;
else return [6, 2, 4, 8][k % 4];
We can ignore the first case when k == 0
and here is why:
k % 4 == 0
when k is one of [0, 4, 8, 12, 16, ...]
but we need to consider cases when k is one of [0, 4, 8]
because for bigger values we will run recursion. The second multiplier in our formula is $D(k)$ and for k is on of [0, 4, 8]
we get [1, 4, 2]
respectively. We had to multiply these values by 1
but instead of this we will multiply them by 6
so we will get [1, 24, 12]
, the last digits of these values are [1, 4, 2]
. Now we can see that it doesn't matter to multiply them by 1
or 6
the last digits will be the same
The last thing we need it is to prove that $[n / 5] = \lfloor n / 5 \rfloor$ for $n \ge 0$. I think it is obvious
Here is the implementation in JS:
const lastDigigtsOfPowerOfTwo = [6, 2, 4, 8];
const initialValuesOfD_n = [1, 1, 2, 6, 4, 2, 2, 4, 2, 8];
function D(n) {
if (n > 9) {
const k = Math.floor(n / 5);
const lastDigitOfPowerOfTwo = lastDigigtsOfPowerOfTwo[k % 4];
return (lastDigitOfPowerOfTwo * D(k) * D(n % 5)) % 10
} else {
return initialValuesOfD_n[n];
}
}
// TESTS
;[
0, // 1
1, // 1
2, // 2
3, // 6
4, // 4
5, // 2
6, // 2
7, // 4
8, // 2
9, // 8
10, // 8
20, // 4
100, // 4
1000, // 2
10000, // 8
100000, // 6
1000000, // 4
].forEach(n => console.log(n, D(n)))
```
http://math.stackexchange.com/questions/111385/derive-a-formula-to-find-the-number-of-trailing-zeroes-in-n
– Hans Giebenrath Apr 11 '12 at 08:30