Skip to content

Commit

Permalink
feat: more unique problem generation
Browse files Browse the repository at this point in the history
  • Loading branch information
asartalo committed Aug 12, 2021
1 parent eda6758 commit 8009068
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 39 deletions.
3 changes: 2 additions & 1 deletion src/components/WorksheetHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from 'react';
const headerStyles = makeStyles(() => ({
header: {
display: 'flex',
marginTop: 20,
},
headerName: {
flexGrow: 4,
Expand All @@ -26,7 +27,7 @@ const headerStyles = makeStyles(() => ({
instructions: {
marginBottom: 0,
marginTop: '10mm',
fontSize: '16px',
fontSize: 16,
},
}));

Expand Down
92 changes: 92 additions & 0 deletions src/lib/roundRobinRange.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import roundRobinRange from './roundRobinRange';

type Range = { from: number, to: number };
type PairOfRange = [aRange: Range, bRange: Range];
type NumberPair = [a: number, b: number];
interface TestData {
args: PairOfRange;
pairs: NumberPair[]
}

describe('roundRobinRange()', () => {
const testTable = new Map<string, TestData>([
['only zeroes', {
args: [{ from: 0, to: 0 }, { from: 0, to: 0 }],
pairs: [[0, 0]],
}],
['1 vs 1', {
args: [{ from: 1, to: 1 }, { from: 2, to: 2 }],
pairs: [
[1, 2],
[2, 1],
],
}],
['2 vs 1', {
args: [{ from: 0, to: 1 }, { from: 2, to: 2 }],
pairs: [
[0, 2],
[1, 2],
[2, 0],
[2, 1],
],
}],
['2 vs 2', {
args: [{ from: 0, to: 1 }, { from: 2, to: 3 }],
pairs: [
[0, 2],
[0, 3],
[1, 2],
[1, 3],
[2, 0],
[2, 1],
[3, 0],
[3, 1],
],
}],
['2 vs 2 with overlap', {
args: [{ from: 0, to: 1 }, { from: 1, to: 2 }],
pairs: [
[0, 1],
[0, 2],
[1, 1],
[1, 2],
[1, 0],
[2, 0],
[2, 1],
],
}],
['3 vs 3 with overlap', {
args: [{ from: 0, to: 2 }, { from: 1, to: 3 }],
pairs: [
[0, 1],
[0, 2],
[0, 3],
[1, 1],
[1, 2],
[1, 3],
[2, 1],
[2, 2],
[2, 3],
[1, 0],
[2, 0],
[3, 0],
[3, 1],
[3, 2],
],
}],
]);

testTable.forEach((testData, note) => {
describe(`When ${note}`, () => {
let pairings: NumberPair[];

beforeEach(() => {
pairings = roundRobinRange(...testData.args);
});

it('contains only possible range', () => {
expect(new Set(pairings)).toEqual(new Set(testData.pairs));
});
});
});
});
21 changes: 21 additions & 0 deletions src/lib/roundRobinRange.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
type Pair = [a: number, b: number];
type Range = { from: number, to: number };
export default function roundRobinRange(aRange: Range, bRange: Range): Pair[] {
const pairs: Pair[] = [];
const found = new Set<string>();
for (let i = aRange.from; i <= aRange.to; i++) {
for (let j = bRange.from; j <= bRange.to; j++) {
const keyA = `${i}:${j}`;
if (!found.has(keyA)) {
pairs.push([i, j]);
found.add(keyA);
}
const keyB = `${j}:${i}`;
if (!found.has(keyB)) {
pairs.push([j, i]);
found.add(keyB);
}
}
}
return pairs;
}
53 changes: 17 additions & 36 deletions src/pages/additionFillTheBlanks/AdditionSentence.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,33 @@
import React from 'react';
import ModRandomNumberGenerator from '../../lib/ModRandomNumberGenerator';
import { randomGenerator } from '../../lib/RandomNumberGenerator';
import roundRobinRange from '../../lib/roundRobinRange';
import Addition from './Addition';
import AftbData from './AftbData';

function shuffle<T>(array: T[]): T[] {
let currentIndex = array.length;
let randomIndex: number;

// While there remain elements to shuffle...
while (currentIndex !== 0) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;

// And swap it with the current element.
// eslint-disable-next-line no-param-reassign
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}

return array;
}
type Range = { from: number, to: number };

export function generateAdditionSentences(
{
rangeFrom, rangeTo, problems, customAddendsA, customAddendsB, problemGeneration,
}: AftbData,
): Addition[] {
const generated: Addition[] = [];
let rangeA: Range;
let rangeB: Range;
if (problemGeneration === 'custom addends') {
const generatorA = new ModRandomNumberGenerator();
const generatorB = new ModRandomNumberGenerator();
for (let index = 0; index < problems; index++) {
const addendA = generatorA.integer(customAddendsA.to, customAddendsA.from);
const addendB = generatorB.integer(customAddendsB.to, customAddendsB.from);
generated.push(Addition.create.apply(
null,
shuffle([addendA, addendB]) as [addendA: number, addendB: number],
));
}
rangeA = customAddendsA;
rangeB = customAddendsB;
} else {
const generatorA = new ModRandomNumberGenerator();
const generatorB = new ModRandomNumberGenerator();
for (let index = 0; index < problems; index++) {
generated.push(new Addition(
generatorA.integer(rangeTo, rangeFrom),
generatorB.integer(rangeTo, rangeFrom),
));
rangeA = { from: rangeFrom, to: rangeTo };
rangeB = rangeA;
}

const possiblePairs = roundRobinRange(rangeA, rangeB);
while (generated.length < problems) {
const pairBag = possiblePairs.slice(0);
for (let i = 0; i < pairBag.length && generated.length < problems; i++) {
const pair = pairBag.splice(randomGenerator.integer(pairBag.length - 1), 1)[0];
generated.push(Addition.create(...pair));
}
}
return generated;
Expand Down
2 changes: 0 additions & 2 deletions src/pages/additionFillTheBlanks/CustomizeAftbForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ const CustomizeAftbForm = ({
};

const updateData = (updated: AftbData): void => {
// eslint-disable-next-line no-debugger
debugger;
const error = validate(updated);
if (error !== errorMessage) {
setErrorMessage(error);
Expand Down

0 comments on commit 8009068

Please sign in to comment.