Project Euler Problem 117
Using a combination of grey square tiles and oblong tiles chosen from: red tiles (measuring two units), green tiles (mea
Solution
Answer: 100808458960497
Let $F(n)$ denote the number of ways to tile a row of length $n$ using:
- grey squares of length $1$,
- red oblongs of length $2$,
- green oblongs of length $3$,
- blue oblongs of length $4$.
We want $F(50)$.
Mathematical analysis
Step 1: Build the recurrence
Consider the leftmost tile in a valid tiling of length $n$.
There are four possibilities:
- A grey square of length $1$
Remaining length: $n-1$ 2. A red tile of length $2$
Remaining length: $n-2$ 3. A green tile of length $3$
Remaining length: $n-3$ 4. A blue tile of length $4$
Remaining length: $n-4$
Therefore,
$$F(n)=F(n-1)+F(n-2)+F(n-3)+F(n-4)$$
This is a generalized Fibonacci recurrence.
Step 2: Determine base cases
We define:
$$F(0)=1$$
Why? Because there is exactly one way to tile a row of length $0$: use no tiles.
Now compute small values:
$n=1$
Only one possibility:
- $1$
So:
$$F(1)=1$$
$n=2$
Possibilities:
- $1+1$
- $2$
Thus:
$$F(2)=2$$
$n=3$
Possibilities:
- $1+1+1$
- $1+2$
- $2+1$
- $3$
Hence:
$$F(3)=4$$
$n=4$
Possibilities:
- $1+1+1+1$
- $2+1+1$
- $1+2+1$
- $1+1+2$
- $2+2$
- $3+1$
- $1+3$
- $4$
So:
$$F(4)=8$$
The recurrence now generates all later values.
Step 3: Verify the example $n=5$
Using the recurrence:
$$F(5)=F(4)+F(3)+F(2)+F(1)$$
$$F(5)=8+4+2+1=15$$
which matches the problem statement.
Python implementation
def count_tilings(n):
# dp[i] = number of tilings of length i
dp = [0] * (n + 1)
# Base case:
# one way to tile an empty row
dp[0] = 1
for i in range(1, n + 1):
# Place a grey tile of length 1
dp[i] += dp[i - 1]
# Place a red tile of length 2
if i >= 2:
dp[i] += dp[i - 2]
# Place a green tile of length 3
if i >= 3:
dp[i] += dp[i - 3]
# Place a blue tile of length 4
if i >= 4:
dp[i] += dp[i - 4]
return dp[n]
print(count_tilings(50))
Code walkthrough
Function definition
def count_tilings(n):
Defines a function that computes the number of tilings for length $n$.
DP array
dp = [0] * (n + 1)
Creates an array where:
$$dp[i] = F(i)$$
Base case
dp[0] = 1
There is one way to tile an empty row.
Main loop
for i in range(1, n + 1):
Compute values from smaller lengths upward.
Add contributions from each tile type
Grey tile
dp[i] += dp[i - 1]
If the first tile has length $1$, the remainder has length $i-1$.
Red tile
if i >= 2:
dp[i] += dp[i - 2]
Similarly for length $2$.
Green tile
if i >= 3:
dp[i] += dp[i - 3]
Blue tile
if i >= 4:
dp[i] += dp[i - 4]
Return result
return dp[n]
Returns the desired count.
Small-value verification
The recurrence generates:
$$\begin{aligned} F(0)&=1\ F(1)&=1\ F(2)&=2\ F(3)&=4\ F(4)&=8\ F(5)&=15 \end{aligned}$$
The problem explicitly states there are $15$ tilings for length $5$, so our recurrence is correct.
Continuing the recurrence up to $50$ gives:
$$F(50)=100808458960497$$
Final verification
The sequence grows exponentially, so a $15$-digit answer for $n=50$ is reasonable.
The recurrence is exhaustive and non-overlapping:
- every tiling begins with exactly one of the four tile types,
- and each choice reduces to a smaller independent subproblem.
Thus the computation is correct.
Answer: 100808458960497