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 BinarySearchTrickProps { showSocialShare?: boolean; } const BinarySearchTrick = ({ showSocialShare = true }: BinarySearchTrickProps) => { const [cardStates, setCardStates] = useState>({}); const [result, setResult] = useState(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>([]); // Function to shuffle array const shuffleArray = (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 = [ { id: 16, title: "Card 16", numbers: [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31] }, { id: 8, title: "Card 8", numbers: [8, 9, 10, 11, 12, 13, 14, 15, 24, 25, 26, 27, 28, 29, 30, 31] }, { id: 4, title: "Card 4", numbers: [4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31] }, { id: 2, title: "Card 2", numbers: [2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31] }, { id: 1, title: "Card 1", numbers: [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31] } ]; // 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 (
Binary Search Magic Trick
Binary Numbers Magic Trick Explained

How to perform the trick:

  1. Ask someone to pick a secret number between 1 and 31
  2. Show them the 5 cards below and ask them to tell you which cards contain their number
  3. Add up the first numbers (16, 8, 4, 2, 1) from the cards they selected
  4. The sum will be their secret number!

Why does it work?

This trick is based on binary number representation. Every number from 1 to 31 can be expressed as a sum of powers of 2: 16, 8, 4, 2, and 1.

Each card contains all numbers that have a "1" in a specific binary position:

  • Card 16: Numbers with 1 in the 16's place (binary position 4)
  • Card 8: Numbers with 1 in the 8's place (binary position 3)
  • Card 4: Numbers with 1 in the 4's place (binary position 2)
  • Card 2: Numbers with 1 in the 2's place (binary position 1)
  • Card 1: Numbers with 1 in the 1's place (binary position 0)

Example:

The number 19 in binary is 10011, which means 16 + 2 + 1 = 19

So 19 appears on cards 16, 2, and 1, but not on cards 8 or 4.

When you add up the first numbers from the selected cards, you're reconstructing the binary representation of their secret number!

Think of a number between 1 and 31, then select all the cards that contain your number:

{/* Navigation controls for one-by-one mode */} {isOneByOne && cards.length > 0 && (
Card {currentCardIndex + 1} of {cards.length}
)}
{getDisplayCards().map((card) => { const cardState = cardStates[card.id] || 'unselected'; return (
{card.id}
{card.numbers.map((num) => (
{num}
))}
); })}
{showResult && result !== null && (

Your number is: {result}

{result === 0 ? "Please select at least one card!" : "Amazing, right? ✨"}

)} {showSocialShare && (
)}
); }; export default BinarySearchTrick;