Project Euler Problem 322

Let T(m, n) be the number of the binomial coefficients ^iCn that are divisible by 10 for n le i lt m (i, m and n are pos

Project Euler Problem 322

Solution

Answer: 999998760323313995

Let

$$T(m,n)=#\left{, i \mid n\le i<m,\ 10\mid \binom{i}{n}\right}.$$

We are given

$$T(10^9,10^7-10)=989697000$$

and we must compute

$$T(10^{18},10^{12}-10).$$


1. Mathematical analysis

We need to count when the binomial coefficient is divisible by $10$, i.e. by both $2$ and $5$.

So define:

  • $A_2$: number of $i$ such that $\binom{i}{n}$ is not divisible by $2$.
  • $A_5$: number of $i$ such that $\binom{i}{n}$ is not divisible by $5$.
  • $A_{10}$: number of $i$ such that $\binom{i}{n}$ is divisible by neither $2$ nor $5$.

Then by inclusion–exclusion,

$$T(m,n) = (m-n)-A_2-A_5+A_{10}.$$

So the problem reduces to computing these three quantities.


Lucas/Kummer theorem

For a prime $p$,

$$\binom{i}{n}\not\equiv 0 \pmod p$$

iff every base-$p$ digit of $n$ is at most the corresponding digit of $i$.

Equivalently, if $i=n+x$, then adding $n$ and $x$ in base $p$ produces no carries.


Computing $A_2$

Let

$$n=10^{12}-10.$$

In binary, $\binom{i}{n}$ is odd iff every binary 1-bit of $n$ is also a 1-bit of $i$.

A digit-DP in base 2 gives:

$$A_2 = 238418395136.$$


Computing $A_5$

In base 5, Lucas gives the analogous condition.

A base-5 digit DP yields:

$$A_5 = 1258291200.$$


Computing $A_{10}$

Now we need numbers satisfying both conditions simultaneously.

Write

$$i=n+x.$$

Then:

  • no carries in base 2 $\iff x& n =0$,
  • no carries in base 5 $\iff$ every base-5 digit of $x$ is bounded by $4-d_k(n)$.

The base-5 expansion of $n=10^{12}-10$ is

$$(1,1,2,3,4,0,4,4,4,4,4,4,4,4,4,4,3,0)_5$$

(reading high to low).

Most digits are $4$, forcing the corresponding digit of $x$ to be $0$.

Only $4800$ low-part possibilities remain.

Let

$$5^{18}=3814697265625.$$

Every admissible $x$ can be written uniquely as

$$x=y\cdot 5^{18}+z,$$

where:

  • $0\le y<262144$,
  • $z$ is one of those $4800$ admissible low parts.

Checking the binary condition $(x& n)=0$ over all such pairs gives

$$A_{10}=321.$$


Final computation

Now apply inclusion–exclusion:

$$\begin{aligned} T &=(10^{18}-(10^{12}-10)) -238418395136 -1258291200 +321 \ &=999999000000000010 -238418395136 -1258291200 +321 \ &=999998760323313995. \end{aligned}$$


2. Python implementation

from functools import lru_cache
from itertools import product
import numpy as np

def count_not_divisible(m, n, p):
    """
    Count i in [n, m) such that C(i,n) is NOT divisible by p.
    Lucas theorem:
    every base-p digit of n must be <= corresponding digit of i.
    """

    # digits of n
    nd = []
    x = n
    while x:
        nd.append(x % p)
        x //= p

    # digits of m-1
    md = []
    x = m - 1
    while x:
        md.append(x % p)
        x //= p

    L = max(len(nd), len(md))
    nd += [0] * (L - len(nd))
    md += [0] * (L - len(md))

    @lru_cache(None)
    def dp(pos, tight):
        if pos < 0:
            return 1

        limit = md[pos] if tight else (p - 1)

        total = 0
        for d in range(nd[pos], limit + 1):
            total += dp(pos - 1, tight and d == limit)

        return total

    return dp(L - 1, True)

def count_not_divisible_by_10(m, n):
    """
    Count i such that C(i,n) is divisible by neither 2 nor 5.
    """

    L = m - n

    # base-5 digits of n
    digits = []
    x = n
    while x:
        digits.append(x % 5)
        x //= 5

    # admissible low-part digits
    positions = [i for i, d in enumerate(digits) if d < 4]
    choices = [range(5 - digits[i]) for i in positions]

    zs = []

    for tup in product(*choices):
        z = 0
        for v, k in zip(tup, positions):
            z += v * (5 ** k)
        zs.append(z)

    zs = np.array(zs, dtype=np.uint64)

    p5 = 5 ** len(digits)

    Y = (L - 1) // p5 + 1

    ys = np.arange(Y, dtype=np.uint64) * np.uint64(p5)

    total = 0

    for z in zs:
        total += np.count_nonzero(((ys + z) & np.uint64(n)) == 0)

    return int(total)

def solve():
    m = 10 ** 18
    n = 10 ** 12 - 10

    A2 = count_not_divisible(m, n, 2)
    A5 = count_not_divisible(m, n, 5)
    A10 = count_not_divisible_by_10(m, n)

    T = (m - n) - A2 - A5 + A10

    return T

print(solve())

3. Code walkthrough

count_not_divisible

This is a standard Lucas digit-DP.

For each base-$p$ digit position:

  • the digit of $i$ must be at least the digit of $n$,
  • and must not exceed the digit of $m-1$.

The DP counts all valid $i<m$.


count_not_divisible_by_10

This handles the simultaneous $2$- and $5$-conditions.

The base-5 condition drastically restricts the low digits of $x=i-n$, leaving only $4800$ possibilities.

We then enumerate the higher block coefficient $y$, and test the binary no-carry condition using:

((ys + z) & n) == 0

which exactly encodes “no overlapping 1-bits”.


4. Verification

For the example in the statement:

$$T(10^9,10^7-10)=989697000,$$

the same program reproduces the given value exactly.

The final answer is slightly below $10^{18}$, which is expected because only about $2.4\times10^{11}$ coefficients fail divisibility by $2$, and about $1.3\times10^9$ fail divisibility by $5$.

Everything is numerically consistent.


Answer: 999998760323313995