All Euler problems
Project Euler

Red, Green, and Blue Tiles

Using a combination of grey squares (length 1), red tiles (length 2), green tiles (length 3), and blue tiles (length 4), in how many ways can a row measuring fifty units in length be tiled? Note: T...

Source sync Apr 19, 2026
Problem #0117
Level Level 04
Solved By 12,712
Languages C++, Python
Answer 100808458960497
Length 393 words
sequenceanalytic_mathlinear_algebra

Problem Statement

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

Using a combination of grey square tiles and oblong tiles chosen from: red tiles (measuring two units), green tiles (measuring three units), and blue tiles (measuring four units), it is possible to tile a row measuring five units in length in exactly fifteen different ways.

Problem illustration

How many ways can a row measuring fifty units in length be tiled?

Note: This is related to
hrefhttps://projecteuler.net/problem=116Problem 116.

Problem 117: Red, Green, and Blue Tiles

Mathematical Foundation

Theorem 1 (Tetranacci recurrence). Let f(n)f(n) denote the number of distinct tilings of a row of length nn using tiles of lengths 1, 2, 3, and 4. Then:

f(n)=f(n1)+f(n2)+f(n3)+f(n4),n4f(n) = f(n-1) + f(n-2) + f(n-3) + f(n-4), \quad n \geq 4

with initial conditions f(0)=1f(0) = 1, f(1)=1f(1) = 1, f(2)=2f(2) = 2, f(3)=4f(3) = 4.

Proof. Every tiling of a row of length n1n \geq 1 ends with exactly one tile of length L{1,2,3,4}L \in \{1, 2, 3, 4\} (provided LnL \leq n). Removing this last tile yields a valid tiling of the prefix of length nLn - L. Conversely, appending any tile of length LnL \leq n to a valid tiling of length nLn - L produces a valid tiling of length nn. This establishes a bijection between tilings of length nn and the disjoint union L=1min(4,n)T(nL)\bigsqcup_{L=1}^{\min(4,n)} \mathcal{T}(n-L), where T(k)\mathcal{T}(k) is the set of tilings of length kk. Therefore:

f(n)=L=1min(4,n)f(nL)f(n) = \sum_{L=1}^{\min(4,n)} f(n-L)

For n4n \geq 4, min(4,n)=4\min(4, n) = 4, giving the stated four-term recurrence.

The initial conditions are verified by enumeration: f(0)=1f(0) = 1 (empty row), f(1)=1f(1) = 1 (grey), f(2)=2f(2) = 2 (grey-grey, red), f(3)=4f(3) = 4 (grey-grey-grey, red-grey, grey-red, green). \square

Theorem 2 (Generating function). The ordinary generating function for f(n)f(n) is:

n=0f(n)xn=11xx2x3x4\sum_{n=0}^{\infty} f(n) x^n = \frac{1}{1 - x - x^2 - x^3 - x^4}

Proof. A tiling of length nn is a sequence of tiles (t1,t2,,tk)(t_1, t_2, \ldots, t_k) with i=1kti=n\sum_{i=1}^{k} |t_i| = n and ti{1,2,3,4}|t_i| \in \{1, 2, 3, 4\}. The generating function for a single tile is g(x)=x+x2+x3+x4g(x) = x + x^2 + x^3 + x^4. Since tiles are placed sequentially and independently, the generating function for all tilings is:

G(x)=k=0g(x)k=11g(x)=11xx2x3x4G(x) = \sum_{k=0}^{\infty} g(x)^k = \frac{1}{1 - g(x)} = \frac{1}{1 - x - x^2 - x^3 - x^4}

This is valid for x<1/α|x| < 1/\alpha where α\alpha is the dominant root. \square

Theorem 3 (Asymptotic growth). f(n)Cαnf(n) \sim C \cdot \alpha^n as nn \to \infty, where α1.92756\alpha \approx 1.92756 is the unique real root greater than 1 of:

x4x3x2x1=0x^4 - x^3 - x^2 - x - 1 = 0

and C=α/(4α33α22α1)0.5876C = \alpha / (4\alpha^3 - 3\alpha^2 - 2\alpha - 1) \approx 0.5876.

Proof. The characteristic polynomial of the recurrence f(n)=f(n1)+f(n2)+f(n3)+f(n4)f(n) = f(n-1) + f(n-2) + f(n-3) + f(n-4) is p(x)=x4x3x2x1p(x) = x^4 - x^3 - x^2 - x - 1. Since p(1)=3<0p(1) = -3 < 0 and p(2)=168421=1>0p(2) = 16 - 8 - 4 - 2 - 1 = 1 > 0, there is a root α(1,2)\alpha \in (1, 2). By Descartes’ rule, p(x)p(x) has exactly one positive real root.

The remaining three roots have modulus less than α\alpha (they form a complex-conjugate pair and possibly a negative real root, all inside the circle z=α|z| = \alpha). By the general theory of linear recurrences with constant coefficients, f(n)=C1αn+C2βn+C3γn+C4δnf(n) = C_1 \alpha^n + C_2 \beta^n + C_3 \gamma^n + C_4 \delta^n where β,γ,δ<α|\beta|, |\gamma|, |\delta| < \alpha, so the dominant term is C1αnC_1 \alpha^n.

The constant C1=α/p(α)C_1 = \alpha / p'(\alpha) where p(x)=4x33x22x1p'(x) = 4x^3 - 3x^2 - 2x - 1. \square

Lemma 1 (Verification). f(5)=15f(5) = 15, f(7)=56f(7) = 56, f(10)=401f(10) = 401.

Proof. Direct computation from the recurrence:

  • f(4)=1+2+1+1=8f(4) = 1 + 2 + 1 + 1 = 8 (but actually f(4)=f(3)+f(2)+f(1)+f(0)=4+2+1+1=8f(4) = f(3) + f(2) + f(1) + f(0) = 4 + 2 + 1 + 1 = 8)
  • f(5)=f(4)+f(3)+f(2)+f(1)=8+4+2+1=15f(5) = f(4) + f(3) + f(2) + f(1) = 8 + 4 + 2 + 1 = 15
  • f(6)=15+8+4+2=29f(6) = 15 + 8 + 4 + 2 = 29
  • f(7)=29+15+8+4=56f(7) = 29 + 15 + 8 + 4 = 56
  • f(8)=56+29+15+8=108f(8) = 56 + 29 + 15 + 8 = 108
  • f(9)=108+56+29+15=208f(9) = 108 + 56 + 29 + 15 = 208
  • f(10)=208+108+56+29=401f(10) = 208 + 108 + 56 + 29 = 401 \square

Editorial

Count ways to tile a row of 50 units using grey (1), red (2), green (3), and blue (4) tiles, with colors freely mixed. Recurrence: f(n) = f(n-1) + f(n-2) + f(n-3) + f(n-4) (tetranacci).

Pseudocode

    if n == 0: return 1
    if n == 1: return 1
    if n == 2: return 2
    if n == 3: return 4
    a, b, c, d = 1, 1, 2, 4 # f(0), f(1), f(2), f(3)
    For i from 4 to n:
        e = a + b + c + d
        a, b, c, d = b, c, d, e
    Return d

Complexity Analysis

  • Time: O(n)O(n) using the iterative approach with a rolling window of 4 values. Alternatively, O(logn)O(\log n) via matrix exponentiation of the 4×44 \times 4 companion matrix.
  • Space: O(1)O(1) for the rolling window (4 integer variables).

Answer

100808458960497\boxed{100808458960497}

Code

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

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

/*
 * Problem 117: Red, Green, and Blue Tiles
 * Tetranacci recurrence: f(n) = f(n-1) + f(n-2) + f(n-3) + f(n-4)
 * f(0) = 1, f(1) = 1, f(2) = 2, f(3) = 4.
 * Answer: f(50) = 100808458960497.
 */

int main() {
    const int N = 50;
    vector<long long> f(N + 1, 0);
    f[0] = 1;
    for (int i = 1; i <= N; i++) {
        for (int L = 1; L <= 4 && L <= i; L++) {
            f[i] += f[i - L];
        }
    }

    // Cross-checks
    assert(f[0] == 1);
    assert(f[1] == 1);
    assert(f[2] == 2);
    assert(f[3] == 4);
    assert(f[4] == 8);
    assert(f[N] == 100808458960497LL);

    cout << f[N] << endl;
    return 0;
}