Project Euler Problem 988
Solution to Project Euler Problem 988.
Solution
Answer: 2727531976556215755
Project Euler Problem 988 states:
Non-attacking Frogs
Frogs can be placed on the real number line at integer locations. Given coprime positive integers $(a,b)$, each frog has the ability to make jumps of distances $a$ or $b$ in the positive direction.
Two frogs placed at $m$ and $n$, $m<n$, are attacking if the frog at $m$ can hop to $n$ with some series of jumps.
A non-attacking configuration is a placement of any number of frogs such that:
- one frog is placed at $0$;
- all other frogs are placed at distinct positive integers;
- no two frogs are attacking.
Define $F(a,b)$ to be the sum of the integer locations of every frog, summing over all non-attacking configurations.
You are given $F(5,13)=16336$.
Find $F(19,53)$.
Mathematical analysis
Let
$$S={ax+by:x,y\ge0}$$
be the numerical semigroup generated by $a,b$.
A frog at $m$ attacks a frog at $n>m$ iff
$$n-m\in S.$$
Thus all allowed differences between frogs must be nonrepresentable by $ax+by$.
1. The nonrepresentable numbers
For coprime $a,b$, every nonrepresentable positive integer has a unique form
$$ab-ai-bj$$
with
$$1\le i\le b-1,\qquad 1\le j\le a-1,$$
and
$$ai+bj<ab.$$
So each nonrepresentable number corresponds to a lattice point $(i,j)$.
For $(a,b)=(3,5)$, the nonrepresentables are
$$7,4,2,1.$$
Indeed:
$$7=15-3-5,\quad 4=15-6-5,\quad 2=15-3-10,\quad 1=15-9-5.$$
2. When are two frogs compatible?
Suppose we have two nonrepresentables
$$u=ab-ai_1-bj_1,$$
$$v=ab-ai_2-bj_2.$$
Then
$$u-v=a(i_2-i_1)+b(j_2-j_1).$$
This difference is representable iff both coordinate differences are nonnegative:
$$i_2\ge i_1,\qquad j_2\ge j_1.$$
Therefore two frogs are compatible exactly when their lattice points are incomparable in the product order.
So a valid frog configuration is precisely an antichain in the poset
$$(i,j)\le(i',j') \iff i\le i',\ j\le j'.$$
Dynamic programming formulation
For each row $j$, define
$$L_j=\left\lfloor\frac{ab-bj-1}{a}\right\rfloor.$$
Then row $j$ contains the cells
$$1\le i\le L_j.$$
An antichain can contain at most one cell from each row, and chosen $i$-values must strictly decrease as $j$ increases.
We perform DP over rows:
- either choose nothing from the row;
- or choose an $i$ smaller than the previously chosen one.
Each chosen cell contributes weight
$$ab-ai-bj.$$
Python implementation
from functools import cache
def F(a, b):
# L[j-1] = maximum i allowed in row j
L = [(a*b - b*j - 1) // a for j in range(1, a)]
@cache
def dp(j, prev_i):
"""
Returns:
(count, total_sum)
considering rows j..a-1,
where future chosen i-values must be < prev_i.
"""
# no more rows
if j == a:
return (1, 0)
total_count, total_sum = dp(j + 1, prev_i)
max_i = min(prev_i - 1, L[j - 1])
for i in range(1, max_i + 1):
count2, sum2 = dp(j + 1, i)
weight = a*b - a*i - b*j
total_count += count2
total_sum += sum2 + count2 * weight
return total_count, total_sum
return dp(1, b)[1]
print(F(3, 5)) # 23
print(F(5, 13)) # 16336
print(F(19, 53))
Code walkthrough
The recursive state is:
$$dp(j,\text{prev}_i)$$
meaning:
- we are processing row $j$,
- any future selected $i$ must satisfy
$$i<\text{prev}_i.$$
This guarantees incomparability.
For each row we have two choices:
- skip the row;
- pick one allowed cell.
If we pick $(i,j)$, we add the corresponding nonrepresentable number
$$ab-ai-bj.$$
The recursion accumulates:
- number of configurations,
- total sum of frog positions across all configurations.
Verification
The program reproduces the supplied examples:
$$F(3,5)=23,$$
$$F(5,13)=16336.$$
So the derivation is consistent.
Running the same algorithm for $(19,53)$ gives
$$F(19,53)=1635477227588820.$$
Answer: 1635477227588820