+ {/* Header */}
+
+
+
+ The Erdős Discrepancy Problem
+
+
+ Can you write instructions to survive the tunnel forever?
+
+
+
+ setShowRules(!showRules)}
+ >
+ {showRules ? : }
+ {showRules ? 'Hide' : 'Rules'}
+
+
+
+
+ {/* Rules Panel */}
+ {showRules && (
+
+
+
+
+
+ The Prisoner's Dilemma
+
+
+ You're trapped in a tunnel with a deadly cliff {discrepancyBound} step{discrepancyBound > 1 ? 's' : ''} to your LEFT and
+ a pit of vipers {discrepancyBound} step{discrepancyBound > 1 ? 's' : ''} to your RIGHT .
+
+
+ Write a list of instructions: each is either LEFT or RIGHT .
+
+
+ The evil captor then picks a step size d and you follow every d-th instruction.
+
+
+
+
+ The Impossible Task
+
+
+ C = 1: Maximum possible sequence length is 11
+
+
+ C = 2: Maximum possible sequence length is 1,160
+
+
+ Terence Tao proved in 2015: No infinite sequence can survive!
+
+
+
+
+
+ )}
+
+ {/* Game Phase: Intro */}
+ {gamePhase === 'intro' && (
+
+
+
+
+
The Prisoner's Walk
+
+ You wake up in a dark tunnel. There's a cliff to your left and vipers to your right.
+ Your captor demands you write a sequence of LEFT/RIGHT instructions...
+ but they get to choose which instructions you follow.
+
+
+
+
+ Discrepancy Bound (C): {discrepancyBound}
+
+
+ 1
+ setDiscrepancyBound(v[0])}
+ min={1}
+ max={3}
+ step={1}
+ className="flex-1"
+ />
+ 3
+
+
+ C=1: Max 11 steps | C=2: Max 1,160 steps | C=3: Unknown (very large)
+
+
+
+
+
+
+ Start Writing
+
+ {discrepancyBound === 1 && (
+
+
+ Load Optimal (11)
+
+ )}
+
+
+ {bestLength && (
+
+ Your best: {bestLength} steps with C={discrepancyBound}
+
+ )}
+
+
+
+ )}
+
+ {/* Main Game UI */}
+ {gamePhase !== 'intro' && (
+
+ {/* Status Bar */}
+
+
+ Length: {sequence.length}
+
+
+ Filled: {filledCount}/{sequence.length}
+
+
+ Max Discrepancy: {maxDiscrepancy.value}
+ {maxDiscrepancy.result && ` (d=${maxDiscrepancy.result.d}, k=${maxDiscrepancy.result.k})`}
+
+
+ Bound: C = {discrepancyBound}
+
+ {bestLength && (
+
+
+ Best: {bestLength}
+
+ )}
+
+
+ {/* Violation Alert */}
+ {hasViolation && gamePhase === 'writing' && (
+
+
+ Bound Exceeded!
+
+ The subsequence with d={maxDiscrepancy.result?.d}, k={maxDiscrepancy.result?.k} has
+ discrepancy {maxDiscrepancy.value}, which exceeds your bound of {discrepancyBound}.
+
+
+ )}
+
+
+
+
+
+ Sequence
+
+
+
+ Walk
+
+
+
+ Heatmap
+
+
+
+ {/* Sequence Builder Tab */}
+
+
+
+
+ Write Your Instructions
+ {gamePhase === 'writing' && (
+ Click to toggle
+ )}
+
+
+
+ {/* Sequence Grid */}
+
+
+ {sequence.map((val, idx) => {
+ const pos = idx + 1;
+ const isHighlighted = highlightedSubsequence.includes(pos) || selectedPositions.includes(pos);
+ const isViolationPart = maxDiscrepancy.result?.positions.includes(pos) && hasViolation;
+
+ return (
+
togglePosition(idx)}
+ disabled={gamePhase !== 'writing'}
+ className={`
+ relative w-10 h-14 rounded-lg border-2 flex flex-col items-center justify-center
+ transition-all duration-200
+ ${val === 1 ? 'bg-blue-500/20 border-blue-500 text-blue-600 dark:text-blue-400' : ''}
+ ${val === -1 ? 'bg-rose-500/20 border-rose-500 text-rose-600 dark:text-rose-400' : ''}
+ ${val === null ? 'bg-muted/50 border-muted-foreground/30 text-muted-foreground' : ''}
+ ${isHighlighted ? 'ring-2 ring-amber-400 ring-offset-1' : ''}
+ ${isViolationPart ? 'ring-2 ring-destructive ring-offset-1' : ''}
+ ${gamePhase === 'writing' ? 'hover:scale-105 cursor-pointer' : 'cursor-default'}
+ `}
+ >
+ {pos}
+ {val === 1 && }
+ {val === -1 && }
+ {val === null && ? }
+
+ );
+ })}
+
+ {gamePhase === 'writing' && (
+
+ +
+
+ )}
+
+
+
+ {/* Controls */}
+
+ {gamePhase === 'writing' && (
+ <>
+
+
+ Face the Captor
+
+
+
+ Reset
+
+ >
+ )}
+
+
+
+
+
+ {/* Walk Visualization Tab */}
+
+
+
+ Walk Visualization
+
+
+ {/* Step size selector */}
+
+
+
Step size (d):
+
+ {Array.from({ length: Math.min(sequence.length, 8) }, (_, i) => i + 1).map(d => (
+ {
+ setSelectedD(d);
+ setWalkPosition(0);
+ setWalkStep(0);
+ setIsWalking(false);
+ }}
+ className="w-8 h-8 p-0"
+ >
+ {d}
+
+ ))}
+
+
+
+
+ Speed:
+ setWalkSpeed(1000 - v[0])}
+ min={0}
+ max={900}
+ step={100}
+ className="w-24"
+ />
+
+
+
+ {/* Number line visualization */}
+
+ {/* Danger zones */}
+
+ CLIFF
+
+
+ VIPERS
+
+
+ {/* Safe zone markers */}
+
+ {Array.from({ length: discrepancyBound * 2 + 1 }, (_, i) => i - discrepancyBound).map(pos => (
+
+ {pos}
+
+ ))}
+
+
+ {/* Walker position */}
+
+
+
+ {/* Walk info */}
+
+ Position: {walkPosition}
+ Steps taken: {walkStep}
+ Following: positions {selectedPositions.slice(0, 5).join(', ')}{selectedPositions.length > 5 ? '...' : ''}
+
+
+ {/* Walk controls */}
+
+
+ {isWalking ? : }
+ {isWalking ? 'Pause' : 'Walk d=' + selectedD}
+
+
{
+ setWalkPosition(0);
+ setWalkStep(0);
+ setIsWalking(false);
+ }}
+ >
+
+
+
+
+
+
+
+ {/* Heatmap Tab */}
+
+ {/* This is actually handled in the walk tab above */}
+
+
+
+
+
+ Discrepancy Heatmap
+
+
+
+ Each cell shows the sum of values at positions d, 2d, 3d, ..., kd.
+ Red cells exceed the bound.
+
+
+
+
+
+
+ d \ k
+ {Array.from({ length: Math.min(12, sequence.length) }, (_, i) => i + 1).map(k => (
+ {k}
+ ))}
+
+
+
+ {Array.from({ length: Math.min(8, sequence.length) }, (_, i) => i + 1).map(d => (
+
+ {d}
+ {Array.from({ length: Math.min(12, sequence.length) }, (_, i) => i + 1).map(k => {
+ const discrepancy = getDiscrepancy(d, k);
+ const isValid = d * k <= sequence.length;
+
+ return (
+ {
+ if (isValid) {
+ setHoveredCell({ d, k });
+ const result = allDiscrepancies.find(r => r.d === d && r.k === k);
+ if (result) {
+ setHighlightedSubsequence(result.positions);
+ }
+ }
+ }}
+ onMouseLeave={() => {
+ setHoveredCell(null);
+ setHighlightedSubsequence([]);
+ }}
+ >
+ {isValid && discrepancy !== null ? discrepancy : ''}
+
+ );
+ })}
+
+ ))}
+
+
+
+
+ {hoveredCell && (
+
+ d={hoveredCell.d}, k={hoveredCell.k}: Looking at positions{' '}
+ {Array.from({ length: hoveredCell.k }, (_, i) => (i + 1) * hoveredCell.d).join(', ')}
+
+ )}
+
+
+
+
+
+ {/* Captor Reveal Phase */}
+ {gamePhase === 'captor-reveal' && captorChosenD !== null && (
+
+
+
+ The Captor Speaks...
+
+ "Interesting sequence... Let me see... I choose d = {captorChosenD} !"
+
+
+ You will follow every {captorChosenD === 1 ? '' : captorChosenD === 2 ? '2nd' : captorChosenD === 3 ? '3rd' : `${captorChosenD}th`} instruction:
+ positions {Array.from({ length: Math.floor(sequence.length / captorChosenD) }, (_, i) => (i + 1) * captorChosenD).slice(0, 8).join(', ')}...
+
+
+
+ Begin Walking
+
+
+
+ )}
+
+ {/* Walking Phase */}
+ {gamePhase === 'walking' && captorChosenD !== null && (
+
+
+
+
Walking with d = {captorChosenD}...
+
+ Step {prisonerStep} | Position: {prisonerPosition}
+
+
+
+ {/* Tunnel visualization */}
+
+
+ 🏔️
+
+
+ 🐍
+
+
+
+ 🚶
+
+
+
+
+ )}
+
+ {/* Fallen Phase */}
+ {gamePhase === 'fallen' && (
+
+
+ You Fell!
+
+ After {prisonerStep} steps with d={captorChosenD}, you ended up at position {prisonerPosition}.
+ The captor found your weakness! Your sequence lasted {sequence.length} instructions.
+
+
+ Try Again
+
+
+
+ Reset
+
+
+
+
+ )}
+
+ {/* Survived Phase (temporary - sequence ended) */}
+ {gamePhase === 'survived' && (
+
+
+ Sequence Complete!
+
+ Your {sequence.length}-instruction sequence survived d={captorChosenD}!
+ But remember: no sequence can survive forever. Try making it longer!
+
+ setGamePhase('writing')} variant="outline" size="sm">
+ Extend Sequence
+
+
+
+ New Game
+
+
+
+
+ )}
+
+ )}
+
+ {/* Acknowledgement */}
+
+
+ Credits & History
+
+ This puzzle is based on the Erdős Discrepancy Problem, posed by Paul Erdős in the 1930s
+ (with a $500 prize!). The "Prisoner's Walk" framing comes from various mathematical expositions,
+ popularized by James Grime's singingbanana video.
+
+
+ 2014: Boris Konev & Alexei Lisitsa proved C=2 has maximum length 1,160 using SAT solvers
+ (generating a 13GB proof!). 2015: Terence Tao proved that NO infinite sequence
+ can have bounded discrepancy, settling the problem completely.
+
+
+
+
+ {/* Social Share */}
+ {showSocialShare !== false && (
+
+ )}
+
+ );
+};
+
+export default ErdosDiscrepancyPuzzle;
diff --git a/src/components/InteractiveIndex.tsx b/src/components/InteractiveIndex.tsx
index a9ce43c..d2dbe67 100644
--- a/src/components/InteractiveIndex.tsx
+++ b/src/components/InteractiveIndex.tsx
@@ -288,6 +288,15 @@ const allInteractives: Interactive[] = [
path: '/puzzles/ladybug-clock',
theme: 'Puzzles',
dateAdded: '2025-01-21'
+ },
+ {
+ id: 'erdos-discrepancy',
+ title: 'The Erdős Discrepancy Problem',
+ description: 'Can you write instructions to survive the tunnel forever? Explore this famous mathematical puzzle through the Prisoner\'s Walk game.',
+ tags: ['erdos', 'discrepancy', 'sequences', 'game-theory', 'impossibility', 'puzzle', 'number-theory'],
+ path: '/puzzles/erdos-discrepancy',
+ theme: 'Puzzles',
+ dateAdded: '2025-01-22'
}
];
diff --git a/src/pages/ErdosDiscrepancyPuzzlePage.tsx b/src/pages/ErdosDiscrepancyPuzzlePage.tsx
new file mode 100644
index 0000000..cb323f8
--- /dev/null
+++ b/src/pages/ErdosDiscrepancyPuzzlePage.tsx
@@ -0,0 +1,16 @@
+import Layout from "@/components/Layout";
+import ErdosDiscrepancyPuzzle from "@/components/ErdosDiscrepancyPuzzle";
+
+const ErdosDiscrepancyPuzzlePage = () => {
+ return (
+