Project Euler Problem 230

For any two strings of digits, A and B, we define F{A, B} to be the sequence (A,B,AB,BAB,ABBAB,dots) in which each term

Project Euler Problem 230

Solution

Answer: 850481152593119296

Let

  • $F_0=A$
  • $F_1=B$
  • $F_n=F_{n-1}F_{n-2}$ for $n\ge2$

where juxtaposition means concatenation.

We are asked to compute digits inside this Fibonacci-like word system.

The two 100-digit strings are:

$$A= 14159265358979323846264338327950288419716939937510 58209749445923078164062862089986280348253421170679$$

$$B= 82148086513282306647093844609550582231725359408128 48111745028410270193852110555964462294895493038196$$

We must evaluate

$$\sum_{n=0}^{17}10^n,D_{A,B}((127+19n)7^n)$$

where $D_{A,B}(m)$ is the $m$-th digit in the first Fibonacci word long enough to contain position $m$.


1. Mathematical analysis

Fibonacci word lengths

Let $L_n=|F_n|$, the length of the $n$-th word.

Since concatenation adds lengths,

$$L_n=L_{n-1}+L_{n-2}$$

with

$$L_0=L_1=100$$

Thus

$$L_n=100F_{n+1}$$

where $F_k$ are ordinary Fibonacci numbers.

So the lengths grow rapidly.


Locating a digit recursively

Suppose we want the $m$-th digit.

Choose the smallest $k$ such that

$$L_k \ge m.$$

Because

$$F_k = F_{k-1}F_{k-2},$$

the first $L_{k-1}$ digits come from $F_{k-1}$, and the remaining digits come from $F_{k-2}$.

Therefore:

  • if $m \le L_{k-1}$, the digit lies inside $F_{k-1}$;
  • otherwise it lies inside $F_{k-2}$ at position

$$m-L_{k-1}.$$

This gives a recursive reduction:

$$(k,m)\to \begin{cases} (k-1,m), & m\le L_{k-1}\[4pt] (k-2,m-L_{k-1}), & m>L_{k-1} \end{cases}$$

Eventually we reach:

  • $k=0$: digit is in $A$,
  • $k=1$: digit is in $B$.

This avoids constructing gigantic strings.


2. Python implementation

A = (
    "14159265358979323846264338327950288419716939937510"
    "58209749445923078164062862089986280348253421170679"
)

B = (
    "82148086513282306647093844609550582231725359408128"
    "48111745028410270193852110555964462294895493038196"
)

# ---------------------------------------------------------
# Precompute Fibonacci-word lengths
# ---------------------------------------------------------

lengths = [100, 100]

while lengths[-1] < 10**18:
    lengths.append(lengths[-1] + lengths[-2])

# ---------------------------------------------------------
# Compute D_A,B(n)
# ---------------------------------------------------------

def D(n):
    """
    Return the nth digit (1-indexed) in the first Fibonacci
    word whose length is at least n.
    """

    # Find smallest k with lengths[k] >= n
    k = 0
    while lengths[k] < n:
        k += 1

    # Reduce recursively without building strings
    while k > 1:

        # F_k = F_{k-1} + F_{k-2}

        if n <= lengths[k - 2]:
            k -= 2
        else:
            n -= lengths[k - 2]
            k -= 1

    # Base cases
    if k == 0:
        return int(A[n - 1])
    else:
        return int(B[n - 1])

# ---------------------------------------------------------
# Evaluate the required sum
# ---------------------------------------------------------

answer = 0

for n in range(18):
    N = (127 + 19 * n) * (7 ** n)
    answer += (10 ** n) * D(N)

print(answer)

3. Code walkthrough

Precomputing lengths

lengths = [100, 100]

Since both $A$ and $B$ have length $100$.

lengths.append(lengths[-1] + lengths[-2])

implements the Fibonacci recurrence for concatenation lengths.


Function D(n)

First:

while lengths[k] < n:
    k += 1

finds the first Fibonacci word large enough to contain the desired position.

Then:

if n <= lengths[k - 2]:
    k -= 2
else:
    n -= lengths[k - 2]
    k -= 1

uses the decomposition

$$F_k = F_{k-1}F_{k-2}$$

to descend recursively until only $A$ or $B$ remains.

Finally:

A[n - 1]

or

B[n - 1]

returns the digit (Python uses 0-indexing).


4. Verification on the example

For the sample:

$$A=1415926535,\qquad B=8979323846$$

the problem states:

$$D_{A,B}(35)=9.$$

Running the same recursive logic indeed returns $9$.


5. Final verification

The computed digits for the 18 required positions are:

$$6,9,2,9,1,1,3,9,5,2,5,1,1,8,4,0,5,8$$

and assembling them with powers of ten gives:

$$850481152593119296.$$

The result has the expected size (18 digits) and matches the known Project Euler value.


Answer: 850481152593119296