diff --git a/src/components/NeighborSumAvoidance.tsx b/src/components/NeighborSumAvoidance.tsx index fbcd5b4..6aee214 100644 --- a/src/components/NeighborSumAvoidance.tsx +++ b/src/components/NeighborSumAvoidance.tsx @@ -3,6 +3,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com import { Button } from '@/components/ui/button'; import { Switch } from '@/components/ui/switch'; import { Label } from '@/components/ui/label'; +import { Slider } from '@/components/ui/slider'; import { Timer, RotateCcw } from 'lucide-react'; import confetti from 'canvas-confetti'; import { toast } from 'sonner'; @@ -13,10 +14,13 @@ interface NeighborSumAvoidanceProps { } const NeighborSumAvoidance = ({ showSocialShare = false }: NeighborSumAvoidanceProps) => { + const [numberCount, setNumberCount] = useState(9); const [mode, setMode] = useState<'default' | 'guided'>('default'); const [isActive, setIsActive] = useState(false); - const [slots, setSlots] = useState<(number | null)[]>(Array(9).fill(null)); - const [availableNumbers, setAvailableNumbers] = useState([1, 2, 3, 4, 5, 6, 7, 8, 9]); + const [slots, setSlots] = useState<(number | null)[]>(Array(numberCount).fill(null)); + const [availableNumbers, setAvailableNumbers] = useState( + Array.from({ length: numberCount }, (_, i) => i + 1) + ); const [draggedNumber, setDraggedNumber] = useState(null); const [draggedFrom, setDraggedFrom] = useState(null); const [draggedSlot, setDraggedSlot] = useState(null); @@ -45,9 +49,9 @@ const NeighborSumAvoidance = ({ showSocialShare = false }: NeighborSumAvoidanceP const getViolations = () => { const violations: number[] = []; - for (let i = 0; i < 9; i++) { + for (let i = 0; i < numberCount; i++) { const current = slots[i]; - const next = slots[(i + 1) % 9]; + const next = slots[(i + 1) % numberCount]; if (current !== null && next !== null && isDivisible(current, next)) { violations.push(i); } @@ -87,11 +91,11 @@ const NeighborSumAvoidance = ({ showSocialShare = false }: NeighborSumAvoidanceP setIsComplete(false); if (selectedMode === 'default') { - setSlots(Array(9).fill(null)); - setAvailableNumbers([1, 2, 3, 4, 5, 6, 7, 8, 9]); + setSlots(Array(numberCount).fill(null)); + setAvailableNumbers(Array.from({ length: numberCount }, (_, i) => i + 1)); } else { // Guided mode: random arrangement - const shuffled = [...Array(9)].map((_, i) => i + 1).sort(() => Math.random() - 0.5); + const shuffled = Array.from({ length: numberCount }, (_, i) => i + 1).sort(() => Math.random() - 0.5); setSlots(shuffled); setAvailableNumbers([]); } @@ -100,8 +104,8 @@ const NeighborSumAvoidance = ({ showSocialShare = false }: NeighborSumAvoidanceP const restart = () => { setIsActive(false); setIsComplete(false); - setSlots(Array(9).fill(null)); - setAvailableNumbers([1, 2, 3, 4, 5, 6, 7, 8, 9]); + setSlots(Array(numberCount).fill(null)); + setAvailableNumbers(Array.from({ length: numberCount }, (_, i) => i + 1)); setTime(0); setSwaps(0); }; @@ -164,20 +168,24 @@ const NeighborSumAvoidance = ({ showSocialShare = false }: NeighborSumAvoidanceP }; const renderCircle = () => { - const radius = 150; - const centerX = 200; - const centerY = 200; + // Dynamic radius based on number count + const baseRadius = 120; + const radiusIncrement = (numberCount - 5) * 5; + const radius = baseRadius + radiusIncrement; + const svgSize = (radius + 50) * 2; + const centerX = svgSize / 2; + const centerY = svgSize / 2; const violations = getViolations(); return ( - + {/* Draw circle */} {/* Draw violation arcs */} {violations.map(i => { - const angle1 = (i * 360 / 9 - 90) * Math.PI / 180; - const angle2 = ((i + 1) * 360 / 9 - 90) * Math.PI / 180; + const angle1 = (i * 360 / numberCount - 90) * Math.PI / 180; + const angle2 = ((i + 1) * 360 / numberCount - 90) * Math.PI / 180; const x1 = centerX + radius * Math.cos(angle1); const y1 = centerY + radius * Math.sin(angle1); const x2 = centerX + radius * Math.cos(angle2); @@ -199,15 +207,15 @@ const NeighborSumAvoidance = ({ showSocialShare = false }: NeighborSumAvoidanceP return slots.slice(i + 1).map((num2, j) => { const idx2 = i + j + 1; if (num1 !== null && num2 !== null && !isDivisible(num1, num2)) { - const angle1 = (i * 360 / 9 - 90) * Math.PI / 180; - const angle2 = (idx2 * 360 / 9 - 90) * Math.PI / 180; + const angle1 = (i * 360 / numberCount - 90) * Math.PI / 180; + const angle2 = (idx2 * 360 / numberCount - 90) * Math.PI / 180; const x1 = centerX + radius * Math.cos(angle1); const y1 = centerY + radius * Math.sin(angle1); const x2 = centerX + radius * Math.cos(angle2); const y2 = centerY + radius * Math.sin(angle2); // Check if this forms part of the cycle (adjacent positions on circle) - const isAdjacentOnCircle = Math.abs(i - idx2) === 1 || Math.abs(i - idx2) === 8; + const isAdjacentOnCircle = Math.abs(i - idx2) === 1 || Math.abs(i - idx2) === numberCount - 1; return ( { - const angle = (i * 360 / 9 - 90) * Math.PI / 180; + const angle = (i * 360 / numberCount - 90) * Math.PI / 180; const x = centerX + radius * Math.cos(angle); const y = centerY + radius * Math.sin(angle); @@ -273,20 +281,35 @@ const NeighborSumAvoidance = ({ showSocialShare = false }: NeighborSumAvoidanceP Neighbor Sum Avoidance - Can you arrange the numbers 1-9 in a circle so that the sum of two neighbors is never divisible by 3, 5, or 7? + Can you arrange the numbers 1-{numberCount} in a circle so that the sum of two neighbors is never divisible by 3, 5, or 7? {!isActive ? (
-
- - setMode(checked ? 'guided' : 'default')} - /> - +
+
+ + setMode(checked ? 'guided' : 'default')} + /> + +
+ +
+ + setNumberCount(value[0])} + className="w-24" + /> +