import type { MathProblem, Difficulty } from "../types"; import { randomInt, randomChoice } from "@/lib/utils"; let counter = 0; function nextId() { return `np-${++counter}-${Date.now()}`; } export function generateIdentityInverse(difficulty: Difficulty): MathProblem { const kind = randomChoice( difficulty === 1 ? (["identity-add", "zero", "inverse-add"] as const) : (["identity-add", "identity-mul", "zero", "inverse-add"] as const), ); if (kind === "identity-add") { const n = randomInt(-20, 20); return { id: nextId(), prompt: `${n} + 0`, answer: { kind: "integer", value: n }, hints: ["0 is the identity for addition.", "Adding 0 changes nothing."], steps: [{ explanation: "Adding the identity 0 leaves the number unchanged.", math: `${n} + 0 = ${n}` }], }; } if (kind === "identity-mul") { const n = randomInt(-20, 20); return { id: nextId(), prompt: `${n} \\times 1`, answer: { kind: "integer", value: n }, hints: ["1 is the identity for multiplication.", "Multiplying by 1 changes nothing."], steps: [{ explanation: "Multiplying by the identity 1 leaves the number unchanged.", math: `${n} \\times 1 = ${n}` }], }; } if (kind === "zero") { const n = randomInt(1, 30); return { id: nextId(), prompt: `${n} \\times 0`, answer: { kind: "integer", value: 0 }, hints: ["Anything multiplied by zero is zero."], steps: [{ explanation: "Any number times zero is zero.", math: `${n} \\times 0 = 0` }], }; } // inverse-add: additive inverse const n = randomInt(-20, 20) || 5; return { id: nextId(), prompt: `\\text{The additive inverse of } ${n} \\text{ is?}`, answer: { kind: "integer", value: -n }, hints: ["The additive inverse adds up to 0.", "Flip the sign."], steps: [{ explanation: "The additive inverse flips the sign so the sum is 0.", math: `${n} + (${-n}) = 0` }], }; } export function generateExponentEvaluate(difficulty: Difficulty): MathProblem { if (difficulty === 3) { // index law: find the resulting exponent const base = randomInt(2, 6); const op = randomChoice(["\\times", "\\div"] as const); if (op === "\\times") { const m = randomInt(1, 5); const n = randomInt(1, 5); return { id: nextId(), prompt: `${base}^{${m}} \\times ${base}^{${n}} = ${base}^{x}`, answer: { kind: "integer", value: m + n }, hints: ["Same base, multiplying → add the powers.", `${m} + ${n} = ?`], steps: [{ explanation: "When multiplying powers of the same base, add the exponents.", math: `${base}^{${m}} \\times ${base}^{${n}} = ${base}^{${m + n}}` }], }; } const m = randomInt(3, 7); const n = randomInt(1, m - 1); return { id: nextId(), prompt: `${base}^{${m}} \\div ${base}^{${n}} = ${base}^{x}`, answer: { kind: "integer", value: m - n }, hints: ["Same base, dividing → subtract the powers.", `${m} - ${n} = ?`], steps: [{ explanation: "When dividing powers of the same base, subtract the exponents.", math: `${base}^{${m}} \\div ${base}^{${n}} = ${base}^{${m - n}}` }], }; } if (difficulty === 2 && Math.random() < 0.5) { // difference of two powers, e.g. 2^3 - 2^1 const base = randomInt(2, 4); const a = randomInt(2, 3); const b = 1; const value = Math.pow(base, a) - Math.pow(base, b); return { id: nextId(), prompt: `${base}^{${a}} - ${base}^{${b}}`, answer: { kind: "integer", value }, hints: [`${base}^${a} = ${Math.pow(base, a)}`, `${base}^${b} = ${Math.pow(base, b)}`], steps: [{ explanation: "Work out each power, then subtract.", math: `${Math.pow(base, a)} - ${Math.pow(base, b)} = ${value}` }], }; } // evaluate a single power (includes n^0 and n^1) const base = randomInt(2, difficulty === 1 ? 6 : 9); const exp = difficulty === 1 ? randomChoice([0, 1, 2, 2, 3]) : randomChoice([0, 1, 2, 3]); const value = Math.pow(base, exp); const note = exp === 0 ? "Any number to the power 0 is 1." : exp === 1 ? "Any number to the power 1 is itself." : `Multiply ${base} by itself ${exp} times.`; return { id: nextId(), prompt: `${base}^{${exp}}`, answer: { kind: "integer", value }, hints: [note], steps: [{ explanation: note, math: `${base}^{${exp}} = ${value}` }], }; } export function generateDistributive(difficulty: Difficulty): MathProblem { const a = randomInt(2, difficulty === 1 ? 6 : 9); const b = randomInt(1, difficulty === 1 ? 6 : 9); const c = randomInt(1, difficulty === 1 ? 6 : 9); const value = a * (b + c); return { id: nextId(), prompt: `${a} \\times (${b} + ${c})`, answer: { kind: "integer", value }, hints: [ "Add inside the bracket first, then multiply.", "Or multiply the outside number by each number inside.", `${a} × ${b} + ${a} × ${c}`, ], steps: [ { explanation: `Add inside the bracket: ${b} + ${c} = ${b + c}` }, { explanation: `Multiply: ${a} × ${b + c} = ${value}` }, { explanation: `Check by distributing: ${a * b} + ${a * c} = ${value}` }, ], }; }