diff --git a/src/components/FerrersRogersRamanujan.tsx b/src/components/FerrersRogersRamanujan.tsx index 99b9c7c..8ba6cc3 100644 --- a/src/components/FerrersRogersRamanujan.tsx +++ b/src/components/FerrersRogersRamanujan.tsx @@ -12,6 +12,7 @@ const FerrersRogersRamanujan = () => { const [rrPartition, setRRPartition] = useState([]); const [animatingHook, setAnimatingHook] = useState<{ row: number; col: number } | null>(null); const [animationStep, setAnimationStep] = useState(0); + const [isAnimating, setIsAnimating] = useState(false); useEffect(() => { // Initialize sliders with all zeros @@ -43,6 +44,7 @@ const FerrersRogersRamanujan = () => { setRRPartition([]); setAnimatingHook(null); setAnimationStep(0); + setIsAnimating(false); }; const generateRRPartition = () => { @@ -53,83 +55,69 @@ const FerrersRogersRamanujan = () => { setRRPartition([]); setAnimationStep(0); - - // Start animation - animateHooks(); + setIsAnimating(true); }; - const animateHooks = () => { - const hooks: number[] = []; + // Animation effect + useEffect(() => { + if (!isAnimating || committedPartition.length === 0) return; + const partition = committedPartition; - // We need to traverse the L-shaped hooks - // Start from position (0, 0) and go around the perimeter - let step = 0; + // Find the hook at current animation step + let found = false; + let hookCount = 0; + let targetRow = 0, targetCol = 0; + const maxRow = partition.length; const maxCol = partition[0] || 0; - const processNextHook = () => { - // Determine which hook to process - // We traverse diagonally: (0,0), (1,0), (0,1), (2,0), (1,1), (0,2), ... - let row = 0, col = 0; - let diag = 0; - let found = false; - - // Find the step-th valid hook - let hookCount = 0; - for (let d = 0; d < maxRow + maxCol; d++) { - for (let r = 0; r <= d; r++) { - const c = d - r; - if (r < partition.length && c < partition[r]) { - if (hookCount === step) { - row = r; - col = c; - found = true; - break; - } - hookCount++; + for (let d = 0; d < maxRow + maxCol && !found; d++) { + for (let r = 0; r <= d; r++) { + const c = d - r; + if (r < partition.length && c < partition[r]) { + if (hookCount === animationStep) { + targetRow = r; + targetCol = c; + found = true; + break; } - } - if (found) break; - } - - if (!found) { - // Animation complete - setAnimatingHook(null); - return; - } - - setAnimatingHook({ row, col }); - - // Calculate hook size: boxes to the right + boxes below + 1 (the box itself) - const boxesRight = partition[row] - col - 1; - let boxesBelow = 0; - for (let r = row + 1; r < partition.length; r++) { - if (partition[r] > col) { - boxesBelow++; - } else { - break; + hookCount++; } } - const hookSize = boxesRight + boxesBelow + 1; + } - hooks.push(hookSize); - setRRPartition([...hooks]); + if (!found) { + // Animation complete + setIsAnimating(false); + setAnimatingHook(null); + return; + } - setTimeout(() => { - setAnimationStep(step + 1); - }, 500); - }; + setAnimatingHook({ row: targetRow, col: targetCol }); - const interval = setInterval(() => { - processNextHook(); - if (animatingHook === null && step > 0) { - clearInterval(interval); + // Calculate hook size + const boxesRight = partition[targetRow] - targetCol - 1; + let boxesBelow = 0; + for (let r = targetRow + 1; r < partition.length; r++) { + if (partition[r] > targetCol) { + boxesBelow++; + } else { + break; } + } + const hookSize = boxesRight + boxesBelow + 1; + + // Update RR partition + setRRPartition(prev => [...prev, hookSize]); + + // Schedule next step + const timeout = setTimeout(() => { + setAnimationStep(prev => prev + 1); }, 500); - processNextHook(); - }; + return () => clearTimeout(timeout); + }, [isAnimating, animationStep, committedPartition]); const renderFerrersDiagram = (partition: number[], highlightHook?: { row: number; col: number }) => { if (partition.length === 0) return null; @@ -247,10 +235,10 @@ const FerrersRogersRamanujan = () => { {/* RR Partition Display */}