Initial Commit

This commit is contained in:
2026-03-01 18:50:29 -04:00
parent 261c52d602
commit 364facd9f0
69 changed files with 7829 additions and 87 deletions

94
lib/math/validation.ts Normal file
View File

@@ -0,0 +1,94 @@
import { gcd } from "./fractions";
import { simplifyRatio } from "./ratios";
export type AnswerResult =
| { correct: true; simplified: boolean }
| { correct: false; message: string };
export function checkFractionAnswer(
userNum: number,
userDen: number,
expectedNum: number,
expectedDen: number,
requireSimplified: boolean = true,
): AnswerResult {
if (userDen === 0) {
return { correct: false, message: "Denominator cannot be zero" };
}
// Check mathematical equivalence
const isEquivalent = userNum * expectedDen === expectedNum * userDen;
if (!isEquivalent) {
return { correct: false, message: "That's not quite right. Try again!" };
}
const isSimplified = gcd(Math.abs(userNum), Math.abs(userDen)) === 1;
if (requireSimplified && !isSimplified) {
return { correct: true, simplified: false };
}
return { correct: true, simplified: true };
}
export function checkDecimalAnswer(
userValue: number,
expectedValue: number,
tolerance: number = 0.001,
): AnswerResult {
if (Math.abs(userValue - expectedValue) <= tolerance) {
return { correct: true, simplified: true };
}
return { correct: false, message: "That's not quite right. Try again!" };
}
export function checkRatioAnswer(
userParts: number[],
expectedParts: number[],
requireSimplified: boolean = true,
): AnswerResult {
if (userParts.length !== expectedParts.length) {
return { correct: false, message: "Check the number of parts in your ratio" };
}
const userSimplified = simplifyRatio(userParts);
const expectedSimplified = simplifyRatio(expectedParts);
const isEquivalent = userSimplified.every((v, i) => v === expectedSimplified[i]);
if (!isEquivalent) {
return { correct: false, message: "That's not quite right. Try again!" };
}
if (requireSimplified) {
const isAlreadySimplified = userParts.every((v, i) => v === userSimplified[i]);
return { correct: true, simplified: isAlreadySimplified };
}
return { correct: true, simplified: true };
}
export function checkIntegerAnswer(
userValue: number,
expectedValue: number,
): AnswerResult {
if (userValue === expectedValue) {
return { correct: true, simplified: true };
}
return { correct: false, message: "That's not quite right. Try again!" };
}
export function checkOrderingAnswer(
userOrder: number[],
expectedOrder: number[],
): AnswerResult {
if (userOrder.length !== expectedOrder.length) {
return { correct: false, message: "Make sure you've ordered all the numbers" };
}
const isCorrect = userOrder.every((v, i) => v === expectedOrder[i]);
if (isCorrect) {
return { correct: true, simplified: true };
}
return { correct: false, message: "Check your ordering. Try again!" };
}