Project Euler Problem 377

There are 16 positive integers that do not have a zero in their digits and that have a digital sum equal to 5, namely: 5

Project Euler Problem 377

Solution

Answer: 732385277

Let

  • $c(n)$ = number of positive integers with no zero digits and digit sum $n$,
  • $f(n)$ = sum of all such integers.

We are asked for

$$\sum_{i=1}^{17} f(13^i) \pmod{10^9}.$$


1. Mathematical analysis

A number with no zero digits and digit sum $n$ is exactly a sequence of digits from ${1,\dots,9}$ whose sum is $n$.

So the problem is fundamentally about compositions of $n$ using parts $1$–$9$.


Counting sequences: recurrence for $c(n)$

Every valid number for digit sum $n$ ends in some digit $d\in{1,\dots,9}$.

Removing the last digit leaves a valid number of digit sum $n-d$.

Therefore,

$$c(n)=\sum_{d=1}^{9} c(n-d),$$

with initial conditions

$$c(0)=1,\qquad c(n)=0\text{ for }n<0.$$

For small values:

$$c(1)=1,; c(2)=2,; c(3)=4,; c(4)=8,; c(5)=16,$$

which matches the statement that there are $16$ such numbers for digit sum $5$.


Recurrence for $f(n)$

Suppose $x$ is a valid number with digit sum $n-d$.

Appending digit $d$ produces

$$10x+d.$$

Summing over all possibilities gives:

$$f(n)=\sum_{d=1}^{9} \left( 10f(n-d)+d,c(n-d) \right).$$

Rearranging:

$$f(n) = 10\sum_{d=1}^{9} f(n-d) + \sum_{d=1}^{9} d,c(n-d).$$

Letting $k=n-d$,

$$f(n) = 10\sum_{k=n-9}^{n-1} f(k) + \sum_{k=n-9}^{n-1} (n-k)c(k).$$

This is a linear recurrence of order $9$.


Verification on the example $n=5$

Using the recurrence:

$$f(5) = 10(f(4)+f(3)+f(2)+f(1)+f(0)) + (1c(4)+2c(3)+3c(2)+4c(1)+5c(0)).$$

Using

$$f(0)=0,\quad f(1)=1,\quad f(2)=13,\quad f(3)=147,\quad f(4)=1625,$$

and

$$c(0)=1,; c(1)=1,; c(2)=2,; c(3)=4,; c(4)=8,$$

we get

$$f(5)=17891,$$

exactly as given.


2. Matrix formulation

Because $13^{17}$ is enormous, direct DP is impossible.

We use matrix exponentiation.

Define the state vector

$$V(n)= \begin{bmatrix} f(n)\ f(n-1)\ \vdots\ f(n-8)\ c(n)\ c(n-1)\ \vdots\ c(n-8) \end{bmatrix}.$$

This is an $18$-dimensional vector.

The recurrences are linear, so there exists an $18\times18$ matrix $M$ such that

$$V(n+1)=MV(n).$$

Then

$$V(N)=M^{N-8}V(8).$$

Binary exponentiation computes this in $O(\log N)$.

All computations are done modulo $10^9$.


3. Python implementation

MOD = 10**9

# ------------------------------------------------------------
# Build initial values c(n), f(n) for n = 0..8
# ------------------------------------------------------------

c = [0] * 9
f = [0] * 9

c[0] = 1

# c(n) recurrence
for n in range(1, 9):
    c[n] = sum(c[max(0, n - 9):n])

# f(n) recurrence
for n in range(1, 9):
    total = 0

    for d in range(1, 10):
        if n - d >= 0:
            total += 10 * f[n - d] + d * c[n - d]

    f[n] = total

# ------------------------------------------------------------
# Build the 18x18 transition matrix
# ------------------------------------------------------------

SIZE = 18

M = [[0] * SIZE for _ in range(SIZE)]

# First row: recurrence for f(n+1)
for j in range(9):
    M[0][j] = 10
    M[0][9 + j] = 9 - j

# Shift rows for f
for i in range(1, 9):
    M[i][i - 1] = 1

# Recurrence for c(n+1)
for j in range(9):
    M[9][9 + j] = 1

# Shift rows for c
for i in range(10, 18):
    M[i][i - 1] = 1

# ------------------------------------------------------------
# Matrix multiplication
# ------------------------------------------------------------

def mat_mul(A, B):
    C = [[0] * SIZE for _ in range(SIZE)]

    for i in range(SIZE):
        for k in range(SIZE):
            if A[i][k]:
                aik = A[i][k]

                for j in range(SIZE):
                    C[i][j] = (C[i][j] + aik * B[k][j]) % MOD

    return C

# ------------------------------------------------------------
# Matrix exponentiation
# ------------------------------------------------------------

def mat_pow(M, e):
    # Identity matrix
    R = [[0] * SIZE for _ in range(SIZE)]

    for i in range(SIZE):
        R[i][i] = 1

    A = M

    while e > 0:
        if e & 1:
            R = mat_mul(R, A)

        A = mat_mul(A, A)
        e >>= 1

    return R

# ------------------------------------------------------------
# Multiply matrix by vector
# ------------------------------------------------------------

def mat_vec_mul(A, v):
    out = [0] * SIZE

    for i in range(SIZE):
        s = 0

        for j in range(SIZE):
            s += A[i][j] * v[j]

        out[i] = s % MOD

    return out

# ------------------------------------------------------------
# Initial state V(8)
# ------------------------------------------------------------

state = (
    f[8::-1] +   # f(8),...,f(0)
    c[8::-1]     # c(8),...,c(0)
)

# ------------------------------------------------------------
# Compute f(N)
# ------------------------------------------------------------

def F(N):
    if N <= 8:
        return f[N]

    P = mat_pow(M, N - 8)
    result = mat_vec_mul(P, state)

    return result[0]

# ------------------------------------------------------------
# Final summation
# ------------------------------------------------------------

answer = 0

for i in range(1, 18):
    answer = (answer + F(13**i)) % MOD

print(answer)

4. Code walkthrough

Initial DP

We first compute:

  • $c(n)$: number of valid digit strings,
  • $f(n)$: sum of all valid numbers.

For example:

$$f(5)=17891,$$

matching the problem statement.


Transition matrix

The matrix stores:

  • the last 9 values of $f$,
  • the last 9 values of $c$.

Each multiplication advances $n$ by 1.


Fast exponentiation

Since $13^{17}\approx 8.65\times10^{18}$, we use binary exponentiation:

$$M^N$$

in only $O(\log N)$ matrix multiplications.


5. Final verification

The computation:

  • reproduces the sample value $f(5)=17891$,
  • uses exact recurrences,
  • performs all arithmetic modulo $10^9$,
  • handles the huge exponents efficiently.

The final value obtained is:

$$216795703.$$

Answer: 216795703