"use client"; import { useState, useMemo, useCallback } from "react"; import { Card } from "@/components/ui/card"; const PRESETS = ["3", "12", "23", "33", "123", "213", "321", "1230", "3333"]; interface Column { exponent: number; placeValue: number; digit: string; contrib: number; isOn: boolean; } function powerOfFour(n: number) { let v = 1; for (let i = 0; i < n; i++) v *= 4; return v; } function buildColumnsFor(quaternaryStr: string): Column[] { const n = quaternaryStr.length; const cols: Column[] = []; for (let i = 0; i < n; i++) { const exponent = n - 1 - i; const digit = quaternaryStr[i]; const placeValue = powerOfFour(exponent); const value = parseInt(digit, 10); cols.push({ exponent, placeValue, digit, contrib: value * placeValue, isOn: value > 0, }); } return cols; } function emptyColumns(): Column[] { const cols: Column[] = []; for (let exp = 4; exp >= 0; exp--) { cols.push({ exponent: exp, placeValue: powerOfFour(exp), digit: "_", contrib: 0, isOn: false, }); } return cols; } export function QuaternaryToDenaryExplorer() { const [input, setInput] = useState(""); const [submitted, setSubmitted] = useState(null); const [error, setError] = useState(""); const [answerHidden, setAnswerHidden] = useState(false); const [chartHidden, setChartHidden] = useState(false); const handleInputChange = (value: string) => { setInput(value.replace(/[^0-3]/g, "")); setError(""); }; const convert = useCallback((raw?: string) => { const source = (raw ?? input).trim(); if (source.length === 0) { setError("Type a quaternary number first (digits 0-3 only)."); setSubmitted(null); return; } if (!/^[0-3]+$/.test(source)) { setError("Quaternary numbers use only digits 0, 1, 2 and 3."); setSubmitted(null); return; } if (source.length > 5) { setError("Keep it to 5 digits or fewer (largest is 33333₄ = 1023)."); return; } setError(""); setSubmitted(source); }, [input]); const applyPreset = (value: string) => { setInput(value); convert(value); }; const handleClear = () => { setInput(""); setSubmitted(null); setError(""); }; const handleRandom = () => { const len = 2 + Math.floor(Math.random() * 3); const first = 1 + Math.floor(Math.random() * 3); let s = String(first); for (let i = 1; i < len; i++) { s += String(Math.floor(Math.random() * 4)); } setInput(s); convert(s); }; const columns = useMemo(() => { if (!submitted) return emptyColumns(); return buildColumnsFor(submitted); }, [submitted]); const total = useMemo(() => { if (!submitted) return 0; return columns.reduce((acc, c) => acc + c.contrib, 0); }, [columns, submitted]); const fullExpansion = submitted ? columns.map((c) => `${c.digit}×${c.placeValue}`).join(" + ") : ""; const onesOnly = submitted ? columns.filter((c) => c.isOn).length > 0 ? columns.filter((c) => c.isOn).map((c) => `${c.digit}×${c.placeValue}`).join(" + ") + " = " + total : "0" : ""; return (
{/* Input Card */}

Type a Quaternary Number (digits 0-3)

handleInputChange(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") convert(); }} className="w-44 rounded-lg border-2 border-unit-6 bg-surface px-3 py-2 text-center font-mono text-2xl font-bold tracking-[0.3em] text-unit-6 outline-none focus:border-unit-6-dark" aria-label="Quaternary number input" />
{PRESETS.map((p) => ( ))}
{error && (

{error}

)}
{/* Place value chart */}

Place Value Chart (powers of 4)

{!chartHidden && (
{columns.map((c) => ( ))} {columns.map((c) => ( ))} {columns.map((c, i) => ( ))} {columns.map((c, i) => ( ))}
4{c.exponent}
{c.placeValue}
{c.digit}
{submitted ? c.contrib : "_"}
)} {submitted && (
{fullExpansion}
= {onesOnly}
)}
{/* Answer banner */} {!submitted ? (

Type a quaternary number above and press Convert.

) : answerHidden ? (

{submitted}4 = ? (press Show Answer)

) : (

{submitted}4 = {total} in denary

)}
{/* Footer note */}

For students: right-align your base-4 number to the 1s column. Multiply each digit by its place value and add. Solve on paper first, then check here. Digits 4-9 are illegal in base 4 — the input box rejects them.

); }