Lattice Walks with Barriers
Count the number of lattice paths from (0,0) to (m,n) using unit steps right (1,0) and up (0,1), subject to barrier constraints (e.g., the path must not cross certain lines). The solution uses the...
Problem Statement
This archive keeps the full statement, math, and original media on the page.
Starting from a positive integer $n$, at each step we subtract from $n$ the largest perfect cube not exceeding $n$, until $n$ becomes $0$.
For example, with $n = 100$ the procedure ends in $4$ steps: $$100 \xrightarrow{-4^4} 36 \xrightarrow{-3^3} 9 \xrightarrow{-2^3} 1 \xrightarrow{-1^3} 0$$ Let $D(n)$ denote the number of steps of the procedure. Thus $D(100) = 4$.
Let $S(N)$ denote the sum of $D(n)$ for all positive integers $n$ strictly less than $N$.
For example, $S(100) = 512$.
Find $S(10^{17})$.
Problem 884: Lattice Walks with Barriers
Mathematical Analysis
Theorem 1 (Unrestricted Lattice Paths)
The number of paths from to using right steps and up steps is .
Proof. Each path is a sequence of steps, choosing positions for right steps.
Theorem 2 (Reflection Principle / Andre’s Reflection)
The number of paths from to that do not touch the line (staying weakly below ) is:
This is the ballot problem formula. When , this gives the Catalan number .
Proof. By reflection across : paths touching the barrier biject with unrestricted paths from to , counted by .
Theorem 3 (LGV Lemma)
Let be source points and be destination points. Let be the number of paths from to . Then the number of -tuples of non-intersecting paths (path goes from to ) is:
Proof. Expand the determinant as . By a sign-reversing involution, all terms with intersecting paths cancel, leaving only non-intersecting configurations.
Concrete Numerical Examples
Catalan Numbers (Dyck Paths)
Paths from to staying below :
| 0 | 1 |
| 1 | 1 |
| 2 | 2 |
| 3 | 5 |
| 4 | 14 |
| 5 | 42 |
| 6 | 132 |
LGV Example: Two Non-Intersecting Paths
Sources: , . Destinations: , .
Verification Table (Ballot Problem)
| Unrestricted | Below | Ratio | ||
|---|---|---|---|---|
| 3 | 3 | 20 | 5 | 0.25 |
| 4 | 4 | 70 | 14 | 0.20 |
| 5 | 5 | 252 | 42 | 0.167 |
| 4 | 2 | 15 | 10 | 0.667 |
Catalan Number Interpretations
counts many combinatorial structures:
- Dyck paths from to
- Valid sequences of pairs of parentheses
- Triangulations of a convex -gon
- Full binary trees with leaves
- Non-crossing partitions of
Generating Function
satisfying .
Asymptotic
Complexity Analysis
| Method | Time | Space |
|---|---|---|
| Single path count | ||
| LGV ( paths) | ||
| Transfer matrix |
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
/*
* Problem 884: Lattice Walks with Barriers
* Catalan numbers, ballot problem, LGV lemma.
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll comb_val(int n, int r) {
if (r < 0 || r > n) return 0;
if (r > n - r) r = n - r;
ll result = 1;
for (int i = 0; i < r; i++)
result = result * (n - i) / (i + 1);
return result;
}
ll catalan(int n) { return comb_val(2*n, n) / (n + 1); }
ll ballot(int m, int n) {
if (n > m) return 0;
return comb_val(m + n, m) - comb_val(m + n, m + 1);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout << "=== Catalan Numbers ===" << endl;
for (int n = 0; n <= 15; n++)
cout << "C_" << n << " = " << catalan(n) << endl;
cout << "\n=== Ballot Problem ===" << endl;
for (auto [m, n] : vector<pair<int,int>>{{3,3},{4,4},{5,5},{4,2},{6,3}}) {
cout << "ballot(" << m << "," << n << ") = " << ballot(m, n) << endl;
}
cout << "\nAnswer: C_10 = " << catalan(10) << endl;
return 0;
}
"""
Problem 884: Lattice Walks with Barriers
LGV lemma, reflection principle, Catalan numbers.
"""
import numpy as np
from math import comb
def catalan(n):
"""n-th Catalan number."""
return comb(2 * n, n) // (n + 1)
def ballot(m, n):
"""Paths from (0,0) to (m,n) staying weakly below y=x."""
if n > m:
return 0
return comb(m + n, m) - comb(m + n, m + 1)
def lgv_det(sources, dests):
"""Compute LGV determinant for non-intersecting lattice paths."""
k = len(sources)
M = np.zeros((k, k))
for i in range(k):
for j in range(k):
dx = dests[j][0] - sources[i][0]
dy = dests[j][1] - sources[i][1]
if dx >= 0 and dy >= 0:
M[i][j] = comb(dx + dy, dx)
else:
M[i][j] = 0
return round(np.linalg.det(M))
# --- Verification ---
print("=== Catalan Numbers ===")
for n in range(11):
c = catalan(n)
b = ballot(n, n)
print(f" C_{n} = {c}, ballot({n},{n}) = {b}, Match: {'OK' if c == b else 'FAIL'}")
assert c == b
print("\n=== Ballot Problem ===")
for m, n in [(3,3),(4,4),(5,5),(4,2),(5,3),(6,2)]:
total = comb(m + n, m)
below = ballot(m, n)
print(f" ({m},{n}): total={total}, below y=x: {below}")
print("\n=== LGV Examples ===")
# Two non-intersecting paths
sources = [(0, 0), (0, 1)]
dests = [(3, 2), (3, 3)]
result = lgv_det(sources, dests)
print(f" Sources={sources}, Dests={dests}: {result} non-intersecting path pairs")
# Three paths
sources3 = [(0, 0), (0, 1), (0, 2)]
dests3 = [(4, 2), (4, 3), (4, 4)]
result3 = lgv_det(sources3, dests3)
print(f" 3 paths: {result3} non-intersecting triples")
answer = catalan(10)
print(f"\nAnswer: C_10 = {answer}")
# --- 4-Panel Visualization ---