|
// To run the code, uncomment the following: |
|
// console.log(generateGrid()); |
|
// console.log(test(50)); |
|
|
|
// -------------------------------------------------------------------------------- |
|
// helper functions |
|
// -------------------------------------------------------------------------------- |
|
|
|
export const sum = (...arr) => arr.reduce((acc, curr) => { |
|
acc += curr; |
|
return acc; |
|
}, 0); |
|
|
|
export const generateRandomNum = (start, end, whitelistArr = []) => { |
|
const rand = Math.floor(Math.random() * end) + start; |
|
const _whitelistArr = Array.isArray(whitelistArr) ? whitelistArr : []; |
|
|
|
return _whitelistArr.includes(rand) |
|
? generateRandomNum(start, end, whitelistArr) |
|
: rand; |
|
}; |
|
|
|
export const hasDuplicates = (arr) => { |
|
let temp = {}; |
|
|
|
return arr.reduce((acc, x) => { |
|
if (temp[x]) { |
|
acc = true; |
|
} |
|
|
|
temp[x] = 'anything :)'; |
|
return acc; |
|
}, false); |
|
}; |
|
|
|
export const isInRange = (arr, start, end) => arr.reduce((acc, x) => { |
|
if (acc && (x < start || x > end)) { |
|
acc = false; |
|
} |
|
|
|
return acc; |
|
}, true); |
|
|
|
// -------------------------------------------------------------------------------- |
|
// grid functions |
|
// -------------------------------------------------------------------------------- |
|
|
|
export const generateRow1 = () => { |
|
const x11 = generateRandomNum(1, 9); |
|
const x12 = generateRandomNum(1, 9, [x11]); |
|
const x13 = 15 - (x11 + x12); |
|
|
|
const row1 = [x11, x12, x13]; |
|
|
|
if (hasDuplicates(row1) || !isInRange(row1, 1, 9) || sum(x11, x12) >= 15) { |
|
return generateRow1(); |
|
} else { |
|
return row1; |
|
} |
|
}; |
|
|
|
export const generateRow2 = (row1) => { |
|
const x21 = generateRandomNum(1, 9, row1); |
|
const x22 = generateRandomNum(1, 9, [...row1, x21]); |
|
const x23 = 15 - (x21 + x22); |
|
|
|
const row2 = [x21, x22, x23]; |
|
const [x11, x12, x13] = row1; |
|
|
|
if ( |
|
hasDuplicates(row2) || |
|
!isInRange(row2, 1, 9) || |
|
sum(x21, x22) >= 15 || |
|
sum(x11, x21) >= 15 || |
|
sum(x12, x22) >= 15 || |
|
(15 - sum(x11, x21) === x13) || |
|
(15 - sum(x12, x22) === x13) |
|
) { |
|
return generateRow2(row1); |
|
} else { |
|
return row2; |
|
} |
|
}; |
|
|
|
export const generateRow3 = (row1, row2) => { |
|
const [x11, x12, x13] = row1; |
|
const [x21, x22, x23] = row2; |
|
|
|
const x31 = 15 - sum(x11, x21); |
|
const x32 = 15 - sum(x12, x22); |
|
const x33 = 15 - sum(x13, x23); // const x33 = 15 - sum(x31, x32); |
|
|
|
const row3 = [x31, x32, x33]; |
|
|
|
if ( |
|
hasDuplicates(row3) || |
|
hasDuplicates([...row1, ...row2, ...row3]) || |
|
!isInRange(row3, 1, 9) || |
|
sum(x31, x32) >= 15 || |
|
sum(x11, x21, x31) > 15 || |
|
sum(x12, x22, x32) > 15 || |
|
sum(x13, x23, x33) > 15 || |
|
sum(x31, x32, x33) > 15 |
|
) { |
|
return false; |
|
} else { |
|
return row3; |
|
} |
|
}; |
|
|
|
export const generateGrid = () => { |
|
const row1 = generateRow1(); |
|
const row2 = generateRow2(row1); |
|
const row3 = generateRow3(row1, row2); |
|
|
|
if (!row3) { |
|
return generateGrid(); |
|
} |
|
|
|
return [ row1, row2, row3 ]; |
|
}; |
|
|
|
// -------------------------------------------------------------------------------- |
|
// test functions |
|
// -------------------------------------------------------------------------------- |
|
|
|
export const test = (count) => { |
|
let testHasFailed = false; |
|
|
|
for (let i = 0; i < count; i++) { |
|
const [row1, row2, row3] = generateGrid(); |
|
|
|
const rowSum = [ |
|
sum(...row1), |
|
sum(...row2), |
|
sum(...row3) |
|
]; |
|
const columnSum = [ |
|
sum(row1[0], row2[0], row3[0]), |
|
sum(row1[1], row2[1], row3[1]), |
|
sum(row1[2], row2[2], row3[2]), |
|
]; |
|
|
|
const gridHasDuplicates = hasDuplicates([...row1, ...row2, ...row3]); |
|
const gridContainsValuesNotEqualTo15 = [...rowSum, ...columnSum].reduce((acc, x) => { |
|
if (x !== 15) { |
|
acc = true; |
|
} |
|
return acc; |
|
}, false); |
|
|
|
const _testHasFailed = testHasFailed = gridHasDuplicates && gridContainsValuesNotEqualTo15; |
|
|
|
console.log(` |
|
Test ${i+1}: [${_testHasFailed ? 'FAIL' : 'PASS'}] |
|
|
|
No Duplicates: [${gridHasDuplicates ? 'FAIL' : 'PASS'}] |
|
Sum Equal To 15: [${gridContainsValuesNotEqualTo15 ? 'FAIL' : 'PASS'}] |
|
|
|
-- |
|
| ${row1[0]} | ${row1[1]} | ${row1[2]} | |
|
| ${row2[0]} | ${row2[1]} | ${row2[2]} | |
|
| ${row3[0]} | ${row3[1]} | ${row3[2]} | |
|
`); |
|
} |
|
|
|
console.log(` |
|
OVERALL |
|
|
|
${count} Tests: [${testHasFailed ? 'FAIL' : 'PASS'}] |
|
`); |
|
}; |