All Euler problems
Project Euler

Fibonacci Words

Let A and B be the two given 100 -digit strings from pi, and define F(1)=A, F(2)=B, F(n)=F(n-2) F(n-1) (n>2). For a positive integer k, let D(k) be the k th digit of the first Fibonacci word long e...

Source sync May 21, 2026
Problem #0230
Level Level 08
Solved By 3,238
Languages C++, Python
Answer 850481152593119296
Length 247 words
sequencerecursionbrute_force

Problem Statement

This archive keeps the full statement, math, and original media on the page.

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 is the concatenation of the previous two.

Further, we define $D_{A, B}(n)$ to be the $n^{th}$ digit in the first term of $F_{A, B}$ that contains at least $n$ digits.

Example:

Let $A=1415926535$, $B=8979323846$. We wish to find $D_{A, B}(35)$, say.

The first few terms of $F_{A, B}$ are:

$1415926535$

$8979323846$

$14159265358979323846$

$897932384614159265358979323846$

$1415926535897932384689793238461415{\color{red}\mathbf 9}265358979323846$

Then $D_{A, B}(35)$ is the $35^{th}$ digit in the fifth term, which is $9$.

Now we use for $A$ the first $100$ digits of $\pi$ behind the decimal point:

$14159265358979323846264338327950288419716939937510$

$58209749445923078164062862089986280348253421170679$

and for $B$ the next hundred digits:

$82148086513282306647093844609550582231725359408128$

$48111745028410270193852110555964462294895493038196$.

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

Problem 230: Fibonacci Words

Mathematical Development

Let

L(n)=∣F(n)∣.L(n)=|F(n)|.

Because F(n)F(n) is the concatenation of F(n−2)F(n-2) and F(n−1)F(n-1),

L(1)=L(2)=100,L(n)=L(n−2)+L(n−1).L(1)=L(2)=100, \qquad L(n)=L(n-2)+L(n-1).

So the lengths follow the Fibonacci recurrence and grow exponentially. This means we can reach any queried position by precomputing only a short table of lengths.

Now suppose nn is the smallest index with L(n)≥kL(n)\ge k. Since

F(n)=F(n−2) F(n−1),F(n)=F(n-2)\,F(n-1),

the first L(n−2)L(n-2) digits come from F(n−2)F(n-2) and the remaining digits come from F(n−1)F(n-1). Therefore

Dn(k)={Dn−2(k),k≤L(n−2),Dn−1(k−L(n−2)),k>L(n−2).D_n(k)= \begin{cases} D_{n-2}(k), & k \le L(n-2),\\[4pt] D_{n-1}(k-L(n-2)), & k > L(n-2). \end{cases}

This reduces the query to a smaller Fibonacci word without ever constructing the actual string.

Editorial

The strings themselves are a red herring. By the time the index reaches (127+19n)7n(127+19n)7^n for n=17n=17, the relevant Fibonacci word is astronomically long, so building it explicitly is impossible. But the only thing the concatenation rule preserves is length, and length is exactly the information needed to walk a position backwards through the recursion.

So the program does two tiny pieces of precomputation. First it builds the length table until the entries are safely larger than every requested index. Then, for each query position, it repeatedly asks whether the digit lies in the left block F(n−2)F(n-2) or the right block F(n−1)F(n-1). Every step replaces one huge word by a smaller one and eventually lands in either AA or BB, where the digit is read directly.

Pseudocode

Store the two 100-digit base strings A and B.

Precompute the Fibonacci-style length table L(n)
until it is larger than every queried position.

To answer one query k:
    find the first n with L(n) >= k
    while n > 2:
        if k <= L(n - 2):
            move to F(n - 2)
            n = n - 2
        otherwise:
            subtract L(n - 2) from k
            move to F(n - 1)
            n = n - 1
    read the kth digit from A or B

Evaluate the 18 queries and accumulate digit * 10^n.

Complexity Analysis

  • Time: O(log⁡k)O(\log k) per digit lookup, so the whole sum is tiny.
  • Space: O(log⁡k)O(\log k) for the length table.

Answer

850481152593119296\boxed{850481152593119296}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_230/solution.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    // Problem 230: Fibonacci Words
    // F(1) = A (100 digits of pi), F(2) = B (next 100 digits of pi)
    // F(n) = F(n-2) . F(n-1) (concatenation, older first)
    // Find sum of D((127+19n)*7^n) * 10^n for n=0..17

    string A = "1415926535897932384626433832795028841971"
               "6939937510582097494459230781640628620899"
               "86280348253421170679";
    string B = "8214808651328230664709384460955058223172"
               "5359408128481117450284102701938521105559"
               "64462294895493038196";

    const int MAXN = 200;
    unsigned long long L[MAXN + 1];
    L[1] = L[2] = 100;
    const unsigned long long cap = 1000000000000000000ULL;
    for (int i = 3; i <= MAXN; i++) {
        L[i] = L[i-1] + L[i-2];
        if (L[i] > cap) {
            for (int j = i + 1; j <= MAXN; j++) L[j] = cap;
            break;
        }
    }

    auto power7 = [](int n) -> unsigned long long {
        unsigned long long result = 1;
        for (int i = 0; i < n; i++) result *= 7;
        return result;
    };

    // Find the k-th digit (1-indexed) of the Fibonacci word
    // F(n) = F(n-2) . F(n-1): first L[n-2] chars from F(n-2), rest from F(n-1)
    auto find_digit = [&](unsigned long long k) -> int {
        int n = 1;
        while (L[n] < k) n++;
        while (n > 2) {
            if (k <= L[n-2]) {
                n -= 2;
            } else {
                k -= L[n-2];
                n -= 1;
            }
        }
        if (n == 1) return A[(int)(k - 1)] - '0';
        else return B[(int)(k - 1)] - '0';
    };

    // Compute the answer
    long long answer = 0;
    long long pow10 = 1;
    for (int n = 0; n <= 17; n++) {
        unsigned long long k = (unsigned long long)(127 + 19 * n) * power7(n);
        int digit = find_digit(k);
        answer += pow10 * digit;
        pow10 *= 10;
    }

    printf("%lld\n", answer);
    return 0;
}