Add Zeckendorf Search Magic Trick - Fibonacci-based magic trick using Zeckendorf representation
This commit is contained in:
parent
179e247f71
commit
2580f76025
5 changed files with 399 additions and 0 deletions
|
|
@ -35,6 +35,7 @@ import GoldCoinGamePage from "./pages/GoldCoinGamePage";
|
||||||
import PlateSwapPuzzlePage from "./pages/PlateSwapPuzzlePage";
|
import PlateSwapPuzzlePage from "./pages/PlateSwapPuzzlePage";
|
||||||
import ChessboardRepaintPuzzlePage from "./pages/ChessboardRepaintPuzzlePage";
|
import ChessboardRepaintPuzzlePage from "./pages/ChessboardRepaintPuzzlePage";
|
||||||
import ZeckendorfGamePage from "./pages/ZeckendorfGamePage";
|
import ZeckendorfGamePage from "./pages/ZeckendorfGamePage";
|
||||||
|
import ZeckendorfSearchTrickPage from "./pages/ZeckendorfSearchTrickPage";
|
||||||
import Foundations from "./pages/theme-pages/discrete-math/Foundations";
|
import Foundations from "./pages/theme-pages/discrete-math/Foundations";
|
||||||
import Proofs from "./pages/theme-pages/discrete-math/Proofs";
|
import Proofs from "./pages/theme-pages/discrete-math/Proofs";
|
||||||
import Counting from "./pages/theme-pages/discrete-math/Counting";
|
import Counting from "./pages/theme-pages/discrete-math/Counting";
|
||||||
|
|
@ -96,6 +97,7 @@ const App = () => (
|
||||||
<Route path="/puzzles/plate-swap" element={<PlateSwapPuzzlePage />} />
|
<Route path="/puzzles/plate-swap" element={<PlateSwapPuzzlePage />} />
|
||||||
<Route path="/puzzles/chessboard-repaint" element={<ChessboardRepaintPuzzlePage />} />
|
<Route path="/puzzles/chessboard-repaint" element={<ChessboardRepaintPuzzlePage />} />
|
||||||
<Route path="/discrete-math/foundations/zeckendorf" element={<ZeckendorfGamePage />} />
|
<Route path="/discrete-math/foundations/zeckendorf" element={<ZeckendorfGamePage />} />
|
||||||
|
<Route path="/discrete-math/foundations/zeckendorf-search" element={<ZeckendorfSearchTrickPage />} />
|
||||||
|
|
||||||
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
|
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
|
||||||
<Route path="*" element={<NotFound />} />
|
<Route path="*" element={<NotFound />} />
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,15 @@ const allInteractives: Interactive[] = [
|
||||||
theme: 'Discrete Math',
|
theme: 'Discrete Math',
|
||||||
dateAdded: '2024-12-22'
|
dateAdded: '2024-12-22'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'zeckendorf-search-trick',
|
||||||
|
title: 'Zeckendorf Search Magic Trick',
|
||||||
|
description: 'Experience the magic of Zeckendorf representation! Think of a number and watch as the cards reveal it through Fibonacci numbers.',
|
||||||
|
tags: ['fibonacci', 'magic', 'numbers', 'trick', 'zeckendorf', 'representation'],
|
||||||
|
path: '/discrete-math/foundations/zeckendorf-search',
|
||||||
|
theme: 'Discrete Math',
|
||||||
|
dateAdded: '2024-12-22'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'binary-search-trick',
|
id: 'binary-search-trick',
|
||||||
title: 'Binary Search Magic Trick',
|
title: 'Binary Search Magic Trick',
|
||||||
|
|
|
||||||
367
src/components/ZeckendorfSearchTrick.tsx
Normal file
367
src/components/ZeckendorfSearchTrick.tsx
Normal file
|
|
@ -0,0 +1,367 @@
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
|
||||||
|
import { Switch } from '@/components/ui/switch';
|
||||||
|
import { Label } from '@/components/ui/label';
|
||||||
|
import { HelpCircle, RefreshCw, ChevronLeft, ChevronRight } from 'lucide-react';
|
||||||
|
import SocialShare from '@/components/SocialShare';
|
||||||
|
|
||||||
|
interface ZeckendorfSearchTrickProps {
|
||||||
|
showSocialShare?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// First 8 Fibonacci numbers: 1, 1, 2, 3, 5, 8, 13, 21
|
||||||
|
const FIBONACCI_NUMBERS = [21, 13, 8, 5, 3, 2, 1, 1];
|
||||||
|
|
||||||
|
// Function to get Zeckendorf representation of a number
|
||||||
|
const getZeckendorfRepresentation = (n: number): number[] => {
|
||||||
|
if (n === 0) return [];
|
||||||
|
|
||||||
|
// Find the largest Fibonacci number less than or equal to n
|
||||||
|
let largestFib = 0;
|
||||||
|
let largestFibIndex = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < FIBONACCI_NUMBERS.length; i++) {
|
||||||
|
if (FIBONACCI_NUMBERS[i] <= n) {
|
||||||
|
largestFib = FIBONACCI_NUMBERS[i];
|
||||||
|
largestFibIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (largestFib === 0) return [];
|
||||||
|
|
||||||
|
// Recursively get representation for the remainder
|
||||||
|
const remainder = n - largestFib;
|
||||||
|
const remainderRep = getZeckendorfRepresentation(remainder);
|
||||||
|
|
||||||
|
// Check if adding this Fibonacci number would create consecutive numbers
|
||||||
|
if (remainderRep.length > 0 && remainderRep[0] === FIBONACCI_NUMBERS[largestFibIndex + 1]) {
|
||||||
|
// If it would create consecutive, try the next smaller Fibonacci number
|
||||||
|
return getZeckendorfRepresentation(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [largestFib, ...remainderRep];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to check if a number contains a specific Fibonacci number in its Zeckendorf representation
|
||||||
|
const containsFibonacciInZeckendorf = (number: number, fibonacci: number): boolean => {
|
||||||
|
const representation = getZeckendorfRepresentation(number);
|
||||||
|
return representation.includes(fibonacci);
|
||||||
|
};
|
||||||
|
|
||||||
|
const ZeckendorfSearchTrick = ({ showSocialShare = true }: ZeckendorfSearchTrickProps) => {
|
||||||
|
const [cardStates, setCardStates] = useState<Record<number, 'unselected' | 'present' | 'absent'>>({});
|
||||||
|
const [result, setResult] = useState<number | null>(null);
|
||||||
|
const [showResult, setShowResult] = useState(false);
|
||||||
|
const [isOneByOne, setIsOneByOne] = useState(false);
|
||||||
|
const [isRandomized, setIsRandomized] = useState(true);
|
||||||
|
const [currentCardIndex, setCurrentCardIndex] = useState(0);
|
||||||
|
const [cards, setCards] = useState<Array<{id: number; title: string; numbers: number[]}>>([]);
|
||||||
|
|
||||||
|
// Function to shuffle array
|
||||||
|
const shuffleArray = <T,>(array: T[]): T[] => {
|
||||||
|
const shuffled = [...array];
|
||||||
|
for (let i = shuffled.length - 1; i > 0; i--) {
|
||||||
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
|
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
||||||
|
}
|
||||||
|
return shuffled;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generate cards with optional randomization
|
||||||
|
const generateCards = () => {
|
||||||
|
const baseCards = FIBONACCI_NUMBERS.map(fib => {
|
||||||
|
const numbers: number[] = [];
|
||||||
|
// Check numbers from 1 to 33 to see which ones contain this Fibonacci number
|
||||||
|
for (let i = 1; i <= 33; i++) {
|
||||||
|
if (containsFibonacciInZeckendorf(i, fib)) {
|
||||||
|
numbers.push(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: fib,
|
||||||
|
title: `Card ${fib}`,
|
||||||
|
numbers: numbers
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Apply randomization based on toggle state
|
||||||
|
return baseCards.map(card => ({
|
||||||
|
...card,
|
||||||
|
numbers: isRandomized ? shuffleArray(card.numbers) : card.numbers
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
// Initialize cards on component mount
|
||||||
|
useEffect(() => {
|
||||||
|
setCards(generateCards());
|
||||||
|
}, [isRandomized]);
|
||||||
|
|
||||||
|
// Handle mode toggle
|
||||||
|
const handleModeToggle = (checked: boolean) => {
|
||||||
|
setIsOneByOne(checked);
|
||||||
|
setCurrentCardIndex(0);
|
||||||
|
setCardStates({});
|
||||||
|
setShowResult(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle randomization toggle
|
||||||
|
const handleRandomizationToggle = (checked: boolean) => {
|
||||||
|
setIsRandomized(checked);
|
||||||
|
setCardStates({});
|
||||||
|
setShowResult(false);
|
||||||
|
setCurrentCardIndex(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Navigation functions for one-by-one mode
|
||||||
|
const goToPreviousCard = () => {
|
||||||
|
setCurrentCardIndex(prev => Math.max(0, prev - 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
const goToNextCard = () => {
|
||||||
|
setCurrentCardIndex(prev => Math.min(cards.length - 1, prev + 1));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCardSelection = (cardId: number, state: 'present' | 'absent') => {
|
||||||
|
setCardStates(prev => ({
|
||||||
|
...prev,
|
||||||
|
[cardId]: state
|
||||||
|
}));
|
||||||
|
setShowResult(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const calculateResult = () => {
|
||||||
|
const sum = Object.entries(cardStates)
|
||||||
|
.filter(([_, state]) => state === 'present')
|
||||||
|
.reduce((acc, [cardId, _]) => acc + parseInt(cardId), 0);
|
||||||
|
setResult(sum);
|
||||||
|
setShowResult(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
const reset = () => {
|
||||||
|
setCardStates({});
|
||||||
|
setResult(null);
|
||||||
|
setShowResult(false);
|
||||||
|
setCurrentCardIndex(0);
|
||||||
|
setCards(generateCards()); // Regenerate with current randomization setting
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if at least one card has been selected (present or absent)
|
||||||
|
const hasAnySelection = Object.values(cardStates).some(state => state !== 'unselected');
|
||||||
|
|
||||||
|
// Check if all cards have been committed to in one-by-one mode
|
||||||
|
const allCardsCommitted = isOneByOne
|
||||||
|
? cards.every(card => cardStates[card.id] && cardStates[card.id] !== 'unselected')
|
||||||
|
: hasAnySelection;
|
||||||
|
|
||||||
|
// Get cards to display based on mode
|
||||||
|
const getDisplayCards = () => {
|
||||||
|
if (isOneByOne) {
|
||||||
|
return cards.length > 0 ? [cards[currentCardIndex]] : [];
|
||||||
|
}
|
||||||
|
return cards;
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="max-w-6xl mx-auto p-6 space-y-6">
|
||||||
|
<Card className="bg-gradient-to-r from-primary/10 to-secondary/10 border-primary/20">
|
||||||
|
<CardHeader className="text-center">
|
||||||
|
<CardTitle className="text-3xl font-bold bg-gradient-to-r from-primary to-primary/70 bg-clip-text text-transparent">
|
||||||
|
Zeckendorf Search Magic Trick
|
||||||
|
</CardTitle>
|
||||||
|
<div className="flex justify-center mt-4">
|
||||||
|
<Dialog>
|
||||||
|
<DialogTrigger asChild>
|
||||||
|
<Button variant="outline" size="sm">
|
||||||
|
<HelpCircle className="w-4 h-4 mr-2" />
|
||||||
|
How it works
|
||||||
|
</Button>
|
||||||
|
</DialogTrigger>
|
||||||
|
<DialogContent className="max-w-4xl max-h-[80vh] overflow-y-auto">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Zeckendorf Representation Magic Trick Explained</DialogTitle>
|
||||||
|
<DialogDescription asChild>
|
||||||
|
<div className="space-y-4 text-left">
|
||||||
|
<h3 className="font-semibold text-lg">How to perform the trick:</h3>
|
||||||
|
<ol className="list-decimal list-inside space-y-2">
|
||||||
|
<li>Ask someone to pick a secret number between 1 and 33</li>
|
||||||
|
<li>Show them the 8 cards below and ask them to tell you which cards contain their number</li>
|
||||||
|
<li>Add up the first numbers (21, 13, 8, 5, 3, 2, 1, 1) from the cards they selected</li>
|
||||||
|
<li>The sum will be their secret number!</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h3 className="font-semibold text-lg mt-6">Why does it work?</h3>
|
||||||
|
<p>
|
||||||
|
This trick is based on Zeckendorf representation. Every positive integer can be uniquely represented as a sum of Fibonacci numbers, where no two consecutive Fibonacci numbers are used.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Each card contains all numbers that have a specific Fibonacci number in their Zeckendorf representation:
|
||||||
|
</p>
|
||||||
|
<ul className="list-disc list-inside space-y-1 ml-4">
|
||||||
|
<li><strong>Card 21:</strong> Numbers that have 21 in their Zeckendorf representation</li>
|
||||||
|
<li><strong>Card 13:</strong> Numbers that have 13 in their Zeckendorf representation</li>
|
||||||
|
<li><strong>Card 8:</strong> Numbers that have 8 in their Zeckendorf representation</li>
|
||||||
|
<li><strong>Card 5:</strong> Numbers that have 5 in their Zeckendorf representation</li>
|
||||||
|
<li><strong>Card 3:</strong> Numbers that have 3 in their Zeckendorf representation</li>
|
||||||
|
<li><strong>Card 2:</strong> Numbers that have 2 in their Zeckendorf representation</li>
|
||||||
|
<li><strong>Card 1:</strong> Numbers that have 1 in their Zeckendorf representation</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div className="bg-muted p-4 rounded-lg mt-4">
|
||||||
|
<p className="font-semibold">Example:</p>
|
||||||
|
<p>The number 19 in Zeckendorf representation is 13 + 5 + 1 = 19</p>
|
||||||
|
<p>So 19 appears on cards 13, 5, and 1, but not on cards 21, 8, 3, or 2.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
When you add up the first numbers from the selected cards, you're reconstructing the Zeckendorf representation of their secret number!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<div className="text-center space-y-4">
|
||||||
|
<p className="text-lg text-muted-foreground">
|
||||||
|
Think of a number between 1 and 33, then tell me which cards contain your number!
|
||||||
|
</p>
|
||||||
|
|
||||||
|
{/* Controls */}
|
||||||
|
<div className="flex flex-wrap justify-center gap-4 items-center">
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<Switch
|
||||||
|
id="one-by-one"
|
||||||
|
checked={isOneByOne}
|
||||||
|
onCheckedChange={handleModeToggle}
|
||||||
|
/>
|
||||||
|
<Label htmlFor="one-by-one">One by one mode</Label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex items-center space-x-2">
|
||||||
|
<Switch
|
||||||
|
id="randomized"
|
||||||
|
checked={isRandomized}
|
||||||
|
onCheckedChange={handleRandomizationToggle}
|
||||||
|
/>
|
||||||
|
<Label htmlFor="randomized">Randomized order</Label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button onClick={reset} variant="outline" size="sm">
|
||||||
|
<RefreshCw className="w-4 h-4 mr-2" />
|
||||||
|
Reset
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Navigation for one-by-one mode */}
|
||||||
|
{isOneByOne && cards.length > 0 && (
|
||||||
|
<div className="flex justify-center items-center gap-4">
|
||||||
|
<Button
|
||||||
|
onClick={goToPreviousCard}
|
||||||
|
disabled={currentCardIndex === 0}
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
<ChevronLeft className="w-4 h-4 mr-2" />
|
||||||
|
Previous
|
||||||
|
</Button>
|
||||||
|
<span className="text-sm text-muted-foreground">
|
||||||
|
Card {currentCardIndex + 1} of {cards.length}
|
||||||
|
</span>
|
||||||
|
<Button
|
||||||
|
onClick={goToNextCard}
|
||||||
|
disabled={currentCardIndex === cards.length - 1}
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
>
|
||||||
|
Next
|
||||||
|
<ChevronRight className="w-4 h-4 ml-2" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
{/* Cards */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||||
|
{getDisplayCards().map(card => (
|
||||||
|
<Card key={card.id} className="relative">
|
||||||
|
<CardHeader className="pb-2">
|
||||||
|
<CardTitle className="text-xl text-center">{card.title}</CardTitle>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent className="pt-0">
|
||||||
|
<div className="grid grid-cols-4 gap-1 text-xs">
|
||||||
|
{card.numbers.map(num => (
|
||||||
|
<div key={num} className="bg-muted p-1 text-center rounded">
|
||||||
|
{num}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex gap-2 mt-4">
|
||||||
|
<Button
|
||||||
|
onClick={() => handleCardSelection(card.id, 'present')}
|
||||||
|
variant={cardStates[card.id] === 'present' ? 'default' : 'outline'}
|
||||||
|
size="sm"
|
||||||
|
className="flex-1"
|
||||||
|
>
|
||||||
|
Contains my number
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={() => handleCardSelection(card.id, 'absent')}
|
||||||
|
variant={cardStates[card.id] === 'absent' ? 'default' : 'outline'}
|
||||||
|
size="sm"
|
||||||
|
className="flex-1"
|
||||||
|
>
|
||||||
|
Does not contain
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Reveal button */}
|
||||||
|
<div className="text-center">
|
||||||
|
<Button
|
||||||
|
onClick={calculateResult}
|
||||||
|
disabled={!allCardsCommitted}
|
||||||
|
size="lg"
|
||||||
|
className="px-8"
|
||||||
|
>
|
||||||
|
Reveal My Number
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Result */}
|
||||||
|
{showResult && result !== null && (
|
||||||
|
<Card className="bg-gradient-to-r from-green-50 to-blue-50 border-green-200">
|
||||||
|
<CardContent className="p-6 text-center">
|
||||||
|
<h3 className="text-2xl font-bold text-green-800 mb-2">
|
||||||
|
Your number is: {result}
|
||||||
|
</h3>
|
||||||
|
<p className="text-muted-foreground">
|
||||||
|
Magic! 🎩✨
|
||||||
|
</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{showSocialShare && (
|
||||||
|
<SocialShare
|
||||||
|
title="Zeckendorf Search Magic Trick"
|
||||||
|
description="Experience the magic of Zeckendorf representation! Think of a number and watch as the cards reveal it through Fibonacci numbers."
|
||||||
|
url={`${window.location.origin}/discrete-math/foundations/zeckendorf-search`}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ZeckendorfSearchTrick;
|
||||||
13
src/pages/ZeckendorfSearchTrickPage.tsx
Normal file
13
src/pages/ZeckendorfSearchTrickPage.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
import ZeckendorfSearchTrick from '@/components/ZeckendorfSearchTrick';
|
||||||
|
|
||||||
|
const ZeckendorfSearchTrickPage = () => {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-background p-6">
|
||||||
|
<div className="max-w-6xl mx-auto">
|
||||||
|
<ZeckendorfSearchTrick />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ZeckendorfSearchTrickPage;
|
||||||
|
|
@ -7,6 +7,7 @@ import BinaryNumberGame from "@/components/BinaryNumberGame";
|
||||||
import TernaryNumberGame from "@/components/TernaryNumberGame";
|
import TernaryNumberGame from "@/components/TernaryNumberGame";
|
||||||
import BalancedTernaryGame from "@/components/BalancedTernaryGame";
|
import BalancedTernaryGame from "@/components/BalancedTernaryGame";
|
||||||
import ZeckendorfGame from "@/components/ZeckendorfGame";
|
import ZeckendorfGame from "@/components/ZeckendorfGame";
|
||||||
|
import ZeckendorfSearchTrick from "@/components/ZeckendorfSearchTrick";
|
||||||
interface Interactive {
|
interface Interactive {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
|
|
@ -43,6 +44,13 @@ const interactives: Interactive[] = [{
|
||||||
tags: ["fibonacci", "numbers", "representation", "zeckendorf", "combinatorics"],
|
tags: ["fibonacci", "numbers", "representation", "zeckendorf", "combinatorics"],
|
||||||
component: ZeckendorfGame,
|
component: ZeckendorfGame,
|
||||||
greenScreenPath: "/discrete-math/foundations/zeckendorf"
|
greenScreenPath: "/discrete-math/foundations/zeckendorf"
|
||||||
|
}, {
|
||||||
|
id: "zeckendorf-search-trick",
|
||||||
|
title: "Zeckendorf Search Magic Trick",
|
||||||
|
description: "Experience the magic of Zeckendorf representation! Think of a number and watch as the cards reveal it through Fibonacci numbers.",
|
||||||
|
tags: ["fibonacci", "magic", "numbers", "trick", "zeckendorf", "representation"],
|
||||||
|
component: ZeckendorfSearchTrick,
|
||||||
|
greenScreenPath: "/discrete-math/foundations/zeckendorf-search"
|
||||||
}];
|
}];
|
||||||
const Foundations = () => {
|
const Foundations = () => {
|
||||||
const [searchTerm, setSearchTerm] = useState("");
|
const [searchTerm, setSearchTerm] = useState("");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue