From b594759095adf4b3674286b8eda17f008c992eaa Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 23 Feb 2026 07:49:42 +0000 Subject: [PATCH] Add new problem categories split by year based on Slovenian curriculum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New categories added: - Grade 3: Addition/Subtraction of Hundreds (stotice) - Grade 4: Addition/Subtraction up to 1000 (with/without carry/borrow), Comparison up to 1000 - Grade 5 (new): Multiplication/Division up to 100 (2-digit × 1-digit) Year groups reorganized so Grade 4 now includes 1000-range arithmetic alongside existing multiplication/division up to 20, and Grade 5 is introduced for larger multiplication and division problems. Carry/borrow detection generalized to work with step-based generation for 3-digit number categories. https://claude.ai/code/session_01CGiFofzMUvj7issSHSwndn --- src/addition.ts | 41 ++++++++++++++++++++++++++++++++++++++++- src/common.ts | 41 +++++++++++++++++++++++++++++++++++++++++ src/comparison.ts | 8 +++++--- src/division.ts | 6 ++++++ src/multiplication.ts | 6 ++++++ src/subtraction.ts | 37 ++++++++++++++++++++++++++++++++++++- src/translations.ts | 37 +++++++++++++++++++++++++++++++++++++ 7 files changed, 171 insertions(+), 5 deletions(-) diff --git a/src/addition.ts b/src/addition.ts index d0f31e8..b0ef4f0 100644 --- a/src/addition.ts +++ b/src/addition.ts @@ -94,6 +94,43 @@ const generateProps: Record< step: 10, maxResult: 100, }, + [Category.Addition_ThousandWithoutCarry]: { + xMax: 990, + yMax: 990, + xMin: 100, + yMin: 100, + step: 10, + maxResult: 1000, + carryAllowed: false, + }, + [Category.Addition_ThousandWithCarry]: { + xMax: 990, + yMax: 990, + xMin: 100, + yMin: 100, + step: 10, + maxResult: 1000, + carryAllowed: true, + carryForced: true, + }, + [Category.Addition_Thousand]: { + xMax: 990, + yMax: 990, + xMin: 100, + yMin: 100, + step: 10, + maxResult: 1000, + carryAllowed: true, + carryForced: false, + }, + [Category.Addition_Hundreds]: { + xMax: 900, + yMax: 900, + xMin: 100, + yMin: 100, + step: 100, + maxResult: 1000, + }, }; export function generate(category: Category): Problem[] { @@ -123,7 +160,9 @@ export function generate(category: Category): Problem[] { for (let i = xMin; i <= xMax; i += step) { for (let j = yMin; j <= yMax; j += step) { - const hasCarry = carryAllowed && (i % 10) + (j % 10) >= 10; + const digitI = Math.floor(i / step) % 10; + const digitJ = Math.floor(j / step) % 10; + const hasCarry = carryAllowed && digitI + digitJ >= 10; if (hasCarry && !carryForced) { continue; } diff --git a/src/common.ts b/src/common.ts index 34dcf88..117480f 100644 --- a/src/common.ts +++ b/src/common.ts @@ -17,6 +17,10 @@ export enum Category { Addition_Hundred = "Addition: 100", Addition_Hundred_Missing = "Addition: 100 (missing facts)", Addition_Tens = "Addition: Tens", + Addition_ThousandWithoutCarry = "Addition: 1000 (without carry)", + Addition_ThousandWithCarry = "Addition: 1000 (with carry)", + Addition_Thousand = "Addition: 1000", + Addition_Hundreds = "Addition: Hundreds", Subtraction_Ten = "Subtraction: 10", Subtraction_Ten_Missing = "Subtraction: 10 (missing facts)", Subtraction_Twenty = "Subtraction: 20", @@ -26,6 +30,10 @@ export enum Category { Subtraction_Hundred = "Subtraction: 100", Subtraction_Hundred_Missing = "Subtraction: 100 (missing facts)", Subtraction_Tens = "Subtraction: Tens", + Subtraction_ThousandWithoutBorrow = "Subtraction: 1000 (without borrow)", + Subtraction_ThousandWithBorrow = "Subtraction: 1000 (with borrow)", + Subtraction_Thousand = "Subtraction: 1000", + Subtraction_Hundreds = "Subtraction: Hundreds", Multiplication_Ten = "Multiplication: 10", Multiplication_Ten_Missing = "Multiplication: 10 (missing facts)", Multiplication_Twenty = "Multiplication: 20", @@ -34,9 +42,14 @@ export enum Category { Division_Ten_Missing = "Division: 10 (missing facts)", Division_Twenty = "Division: 20", Division_Twenty_Missing = "Division: 20 (missing facts)", + Division_Hundred = "Division: 100", + Division_Hundred_Missing = "Division: 100 (missing facts)", + Multiplication_Hundred = "Multiplication: 100", + Multiplication_Hundred_Missing = "Multiplication: 100 (missing facts)", Comparison_Ten = "Comparison: 10", Comparison_Twenty = "Comparison: 20", Comparison_Hundred = "Comparison: 100", + Comparison_Thousand = "Comparison: 1000", Test = "test", } @@ -53,6 +66,10 @@ export const categoryGroups: Record = { Category.Addition_Hundred, Category.Addition_Hundred_Missing, Category.Addition_Tens, + Category.Addition_ThousandWithoutCarry, + Category.Addition_ThousandWithCarry, + Category.Addition_Thousand, + Category.Addition_Hundreds, ], Subtraction: [ Category.Subtraction_Ten, @@ -64,23 +81,32 @@ export const categoryGroups: Record = { Category.Subtraction_Hundred, Category.Subtraction_Hundred_Missing, Category.Subtraction_Tens, + Category.Subtraction_ThousandWithoutBorrow, + Category.Subtraction_ThousandWithBorrow, + Category.Subtraction_Thousand, + Category.Subtraction_Hundreds, ], Multiplication: [ Category.Multiplication_Ten, Category.Multiplication_Ten_Missing, Category.Multiplication_Twenty, Category.Multiplication_Twenty_Missing, + Category.Multiplication_Hundred, + Category.Multiplication_Hundred_Missing, ], Division: [ Category.Division_Ten, Category.Division_Ten_Missing, Category.Division_Twenty, Category.Division_Twenty_Missing, + Category.Division_Hundred, + Category.Division_Hundred_Missing, ], Comparison: [ Category.Comparison_Ten, Category.Comparison_Twenty, Category.Comparison_Hundred, + Category.Comparison_Thousand, ], Test: [Category.Test], }; @@ -109,10 +135,12 @@ export const yearGroupsSl: Record = { Category.Addition_HundredWithCarry, Category.Addition_Hundred, Category.Addition_Hundred_Missing, + Category.Addition_Hundreds, Category.Subtraction_HundredWithoutBorrow, Category.Subtraction_HundredWithBorrow, Category.Subtraction_Hundred, Category.Subtraction_Hundred_Missing, + Category.Subtraction_Hundreds, Category.Multiplication_Ten, Category.Multiplication_Ten_Missing, Category.Division_Ten, @@ -120,10 +148,23 @@ export const yearGroupsSl: Record = { Category.Comparison_Hundred, ], "4. razred": [ + Category.Addition_ThousandWithoutCarry, + Category.Addition_ThousandWithCarry, + Category.Addition_Thousand, + Category.Subtraction_ThousandWithoutBorrow, + Category.Subtraction_ThousandWithBorrow, + Category.Subtraction_Thousand, Category.Multiplication_Twenty, Category.Multiplication_Twenty_Missing, Category.Division_Twenty, Category.Division_Twenty_Missing, + Category.Comparison_Thousand, + ], + "5. razred": [ + Category.Multiplication_Hundred, + Category.Multiplication_Hundred_Missing, + Category.Division_Hundred, + Category.Division_Hundred_Missing, ], }; diff --git a/src/comparison.ts b/src/comparison.ts index 2cd8a84..cca3d9b 100644 --- a/src/comparison.ts +++ b/src/comparison.ts @@ -5,11 +5,13 @@ const generateProps: Record< { max: number; min?: number; + step?: number; } > = { [Category.Comparison_Ten]: { max: 10 }, [Category.Comparison_Twenty]: { max: 20 }, [Category.Comparison_Hundred]: { max: 100, min: 10 }, + [Category.Comparison_Thousand]: { max: 1000, min: 100, step: 10 }, }; const comparisonOptions: Problem["options"] = [ @@ -20,12 +22,12 @@ const comparisonOptions: Problem["options"] = [ export function generate(category: Category): Problem[] { const props = generateProps[category]!; - const { max, min = 0 } = props; + const { max, min = 0, step = 1 } = props; const allProblems: Problem[] = []; - for (let x = min; x <= max; x++) { - for (let y = min; y <= max; y++) { + for (let x = min; x <= max; x += step) { + for (let y = min; y <= max; y += step) { const answer = x < y ? -1 : x === y ? 0 : 1; allProblems.push({ id: `${category}_${x}_${y}`, diff --git a/src/division.ts b/src/division.ts index af7b740..312afc7 100644 --- a/src/division.ts +++ b/src/division.ts @@ -22,6 +22,12 @@ const generateProps: Record< divisorMax: 20, missingField: ["dividend", "divisor"], }, + [Category.Division_Hundred]: { answerMax: 100, divisorMax: 9 }, + [Category.Division_Hundred_Missing]: { + answerMax: 100, + divisorMax: 9, + missingField: ["dividend", "divisor"], + }, }; export function generate(category: Category): Problem[] { diff --git a/src/multiplication.ts b/src/multiplication.ts index c85a787..3b11bd3 100644 --- a/src/multiplication.ts +++ b/src/multiplication.ts @@ -22,6 +22,12 @@ const generateProps: Record< yMax: 20, missingField: ["first", "second"], }, + [Category.Multiplication_Hundred]: { xMax: 100, yMax: 9 }, + [Category.Multiplication_Hundred_Missing]: { + xMax: 100, + yMax: 9, + missingField: ["first", "second"], + }, }; export function generate(category: Category): Problem[] { diff --git a/src/subtraction.ts b/src/subtraction.ts index c4c6c2d..9650f4b 100644 --- a/src/subtraction.ts +++ b/src/subtraction.ts @@ -65,6 +65,39 @@ const generateProps: Record< yMin: 10, step: 10, }, + [Category.Subtraction_ThousandWithoutBorrow]: { + xMax: 1000, + yMax: 990, + xMin: 100, + yMin: 100, + step: 10, + borrowAllowed: false, + }, + [Category.Subtraction_ThousandWithBorrow]: { + xMax: 1000, + yMax: 990, + xMin: 100, + yMin: 100, + step: 10, + borrowAllowed: true, + borrowForced: true, + }, + [Category.Subtraction_Thousand]: { + xMax: 1000, + yMax: 990, + xMin: 100, + yMin: 100, + step: 10, + borrowAllowed: true, + borrowForced: false, + }, + [Category.Subtraction_Hundreds]: { + xMax: 1000, + yMax: 900, + xMin: 100, + yMin: 100, + step: 100, + }, }; export function generate(category: Category): Problem[] { @@ -94,7 +127,9 @@ export function generate(category: Category): Problem[] { for (let i = xMin; i <= xMax; i += step) { for (let j = yMin; j <= yMax; j += step) { if (i < j) continue; // Can't subtract to get negative - const hasBorrow = borrowAllowed && i % 10 < j % 10; + const digitI = Math.floor(i / step) % 10; + const digitJ = Math.floor(j / step) % 10; + const hasBorrow = borrowAllowed && digitI < digitJ; if (hasBorrow && !borrowForced) { continue; } diff --git a/src/translations.ts b/src/translations.ts index 41caff0..b4830b2 100644 --- a/src/translations.ts +++ b/src/translations.ts @@ -45,6 +45,11 @@ export const translations = { [Category.Addition_Hundred]: "Addition: 100", [Category.Addition_Hundred_Missing]: "Addition: 100 (missing facts)", [Category.Addition_Tens]: "Addition: Tens", + [Category.Addition_ThousandWithoutCarry]: + "Addition: 1000 (without carry)", + [Category.Addition_ThousandWithCarry]: "Addition: 1000 (with carry)", + [Category.Addition_Thousand]: "Addition: 1000", + [Category.Addition_Hundreds]: "Addition: Hundreds", [Category.Subtraction_Ten]: "Subtraction: 10", [Category.Subtraction_Ten_Missing]: "Subtraction: 10 (missing facts)", @@ -59,6 +64,12 @@ export const translations = { [Category.Subtraction_Hundred_Missing]: "Subtraction: 100 (missing facts)", [Category.Subtraction_Tens]: "Subtraction: Tens", + [Category.Subtraction_ThousandWithoutBorrow]: + "Subtraction: 1000 (without borrow)", + [Category.Subtraction_ThousandWithBorrow]: + "Subtraction: 1000 (with borrow)", + [Category.Subtraction_Thousand]: "Subtraction: 1000", + [Category.Subtraction_Hundreds]: "Subtraction: Hundreds", [Category.Multiplication_Ten]: "Multiplication: 10", [Category.Multiplication_Ten_Missing]: @@ -71,10 +82,17 @@ export const translations = { [Category.Division_Ten_Missing]: "Division: 10 (missing facts)", [Category.Division_Twenty]: "Division: 20", [Category.Division_Twenty_Missing]: "Division: 20 (missing facts)", + [Category.Division_Hundred]: "Division: 100", + [Category.Division_Hundred_Missing]: "Division: 100 (missing facts)", + + [Category.Multiplication_Hundred]: "Multiplication: 100", + [Category.Multiplication_Hundred_Missing]: + "Multiplication: 100 (missing facts)", [Category.Comparison_Ten]: "Comparison: 10", [Category.Comparison_Twenty]: "Comparison: 20", [Category.Comparison_Hundred]: "Comparison: 100", + [Category.Comparison_Thousand]: "Comparison: 1000", // Group Names group_Addition: "Addition", @@ -137,6 +155,11 @@ export const translations = { [Category.Addition_Hundred]: "Seštevanje: 100", [Category.Addition_Hundred_Missing]: "Seštevanje: 100 (neznani člen)", [Category.Addition_Tens]: "Seštevanje: desetice", + [Category.Addition_ThousandWithoutCarry]: + "Seštevanje: 1000 (brez prehoda)", + [Category.Addition_ThousandWithCarry]: "Seštevanje: 1000 (s prehodom)", + [Category.Addition_Thousand]: "Seštevanje: 1000", + [Category.Addition_Hundreds]: "Seštevanje: stotice", [Category.Subtraction_Ten]: "Odštevanje: 10", [Category.Subtraction_Ten_Missing]: "Odštevanje: 10 (neznani člen)", @@ -150,6 +173,12 @@ export const translations = { [Category.Subtraction_Hundred_Missing]: "Odštevanje: 100 (neznani člen)", [Category.Subtraction_Tens]: "Odštevanje: desetice", + [Category.Subtraction_ThousandWithoutBorrow]: + "Odštevanje: 1000 (brez prehoda)", + [Category.Subtraction_ThousandWithBorrow]: + "Odštevanje: 1000 (s prehodom)", + [Category.Subtraction_Thousand]: "Odštevanje: 1000", + [Category.Subtraction_Hundreds]: "Odštevanje: stotice", [Category.Multiplication_Ten]: "Množenje: 10", [Category.Multiplication_Ten_Missing]: "Množenje: 10 (neznani člen)", @@ -160,10 +189,17 @@ export const translations = { [Category.Division_Ten_Missing]: "Deljenje: 10 (neznani člen)", [Category.Division_Twenty]: "Deljenje: 20", [Category.Division_Twenty_Missing]: "Deljenje: 20 (neznani člen)", + [Category.Division_Hundred]: "Deljenje: 100", + [Category.Division_Hundred_Missing]: "Deljenje: 100 (neznani člen)", + + [Category.Multiplication_Hundred]: "Množenje: 100", + [Category.Multiplication_Hundred_Missing]: + "Množenje: 100 (neznani člen)", [Category.Comparison_Ten]: "Primerjanje: 10", [Category.Comparison_Twenty]: "Primerjanje: 20", [Category.Comparison_Hundred]: "Primerjanje: 100", + [Category.Comparison_Thousand]: "Primerjanje: 1000", // Group Names group_Addition: "Seštevanje", @@ -177,6 +213,7 @@ export const translations = { "group_2. razred": "2. razred", "group_3. razred": "3. razred", "group_4. razred": "4. razred", + "group_5. razred": "5. razred", // Grouping toggle grouping_by_type: "Po vrsti",