fractions add/sub fix

This commit is contained in:
2026-04-19 20:28:12 -04:00
parent 221997f2d9
commit 7db6fc0bab
5 changed files with 134 additions and 35 deletions

View File

@@ -15,6 +15,20 @@ export function parseStrictInt(input: string): number | null {
return parseInt(s, 10);
}
/** Parse a strict signed integer string. Reject decimals, scientific notation, and trailing text. */
export function parseStrictSignedInt(input: string): number | null {
const s = input.trim();
if (!/^-?\d+$/.test(s)) return null;
return parseInt(s, 10);
}
/** Parse a strict signed decimal string. Reject scientific notation and trailing text. */
export function parseStrictSignedDecimal(input: string): number | null {
const s = input.trim();
if (!/^-?\d+(\.\d+)?$/.test(s)) return null;
return parseFloat(s);
}
export type AnswerResult =
| { correct: true; simplified: boolean }
| { correct: false; message: string };
@@ -37,6 +51,11 @@ export function checkFractionAnswer(
return { correct: false, message: "That's not quite right. Try again!" };
}
// Any non-zero denominator gives the same value for zero, so don't force 0/1 in the UI.
if (userNum === 0) {
return { correct: true, simplified: true };
}
const isSimplified = gcd(Math.abs(userNum), Math.abs(userDen)) === 1;
if (requireSimplified && !isSimplified) {

View File

@@ -34,22 +34,51 @@ export function generateFractionAddSubtract(difficulty: Difficulty): MathProblem
n2 = randomInt(1, d2 - 1);
}
const [ansNum, ansDen] = operation === "add"
? frac.add(n1, d1, n2, d2)
: frac.subtract(n1, d1, n2, d2);
const prompt = `\\frac{${n1}}{${d1}} ${op} \\frac{${n2}}{${d2}}`;
const commonDen = frac.lcm(d1, d2);
const convertedN1 = n1 * (commonDen / d1);
const convertedN2 = n2 * (commonDen / d2);
const rawNum = operation === "add"
? convertedN1 + convertedN2
: convertedN1 - convertedN2;
const [ansNum, ansDen] = frac.simplify(rawNum, commonDen);
const steps = d1 === d2
? [
{ explanation: "Denominators are the same, so just " + (operation === "add" ? "add" : "subtract") + " the numerators" },
{ explanation: `${n1} ${op} ${n2} = ${operation === "add" ? n1 + n2 : n1 - n2}`, math: `\\frac{${operation === "add" ? n1 + n2 : n1 - n2}}{${d1}}` },
{
explanation: `The denominators already match, so keep ${d1} as the denominator.`,
math: `\\frac{${n1}}{${d1}} ${op} \\frac{${n2}}{${d2}}`,
},
{
explanation: `${operation === "add" ? "Add" : "Subtract"} the numerators and keep the denominator the same.`,
math: `\\frac{${n1}}{${d1}} ${op} \\frac{${n2}}{${d2}} = \\frac{${rawNum}}{${d1}}`,
},
...(ansNum !== rawNum || ansDen !== d1
? [{
explanation: "Simplify the fraction.",
math: `\\frac{${rawNum}}{${d1}} = \\frac{${ansNum}}{${ansDen}}`,
}]
: []),
]
: [
{ explanation: `Find the common denominator: LCM(${d1}, ${d2}) = ${commonDen}` },
{ explanation: `Convert: ${n1}×${commonDen / d1}/${d1}×${commonDen / d1} and ${n2}×${commonDen / d2}/${d2}×${commonDen / d2}` },
{ explanation: `${op === "+" ? "Add" : "Subtract"} numerators`, math: `\\frac{${ansNum}}{${ansDen}}` },
{
explanation: `Find the lowest common denominator: LCM(${d1}, ${d2}) = ${commonDen}.`,
math: `\\text{LCD} = ${commonDen}`,
},
{
explanation: "Rewrite both fractions with that denominator.",
math: `\\frac{${n1}}{${d1}} = \\frac{${convertedN1}}{${commonDen}} \\quad \\frac{${n2}}{${d2}} = \\frac{${convertedN2}}{${commonDen}}`,
},
{
explanation: `${operation === "add" ? "Add" : "Subtract"} the numerators and keep the common denominator.`,
math: `\\frac{${convertedN1}}{${commonDen}} ${op} \\frac{${convertedN2}}{${commonDen}} = \\frac{${rawNum}}{${commonDen}}`,
},
...(ansNum !== rawNum || ansDen !== commonDen
? [{
explanation: "Simplify the fraction.",
math: `\\frac{${rawNum}}{${commonDen}} = \\frac{${ansNum}}{${ansDen}}`,
}]
: []),
];
return {
@@ -58,7 +87,7 @@ export function generateFractionAddSubtract(difficulty: Difficulty): MathProblem
answer: { kind: "fraction", numerator: ansNum, denominator: ansDen },
hints: [
d1 === d2 ? "The denominators are already the same!" : "Find a common denominator first",
d1 !== d2 ? `Try using the Butterfly Method: cross multiply` : `Just ${operation} the numerators`,
d1 !== d2 ? "Rewrite both fractions using that denominator" : `Just ${operation} the numerators`,
],
steps,
};

View File

@@ -93,7 +93,7 @@ export function generateRatioWordProblem(difficulty: Difficulty): MathProblem {
return {
id: nextId(),
prompt: `\\text{${ctx.item.charAt(0).toUpperCase() + ctx.item.slice(1)} were shared between ${ctx.nameA} and ${ctx.nameB} in the ratio ${a}:${b}. If ${bigger} received ${extraAmount} more ${ctx.item}, find the total shared.}`,
prompt: `\\begin{array}{l}\\text{${ctx.item.charAt(0).toUpperCase() + ctx.item.slice(1)} were shared between ${ctx.nameA} and ${ctx.nameB}}\\\\\\text{in the ratio ${a}:${b}. If ${bigger} received ${extraAmount} more ${ctx.item}, find the total shared.}\\end{array}`,
answer: { kind: "integer", value: total },
hints: [
`The difference in ratio parts is ${biggerRatio} - ${smallerRatio} = ${diff}`,