JSFiddle - React, Tailwind, and code Playground
by Josh Pullen
HTML
To see the results, open this page on your computer and open the console by pressing Cmd + Option + J (on Mac) or Ctrl+Shift+J (on Windows).
JavaScript
const oneDie = [
{ value: 1, waysToRoll: 1 },
{ value: 2, waysToRoll: 1 },
{ value: 3, waysToRoll: 1 },
{ value: 4, waysToRoll: 1 },
{ value: 5, waysToRoll: 1 },
{ value: 6, waysToRoll: 1 }
];
console.log("Set for one die: ", oneDie);
const twoDice = addSets(oneDie, oneDie);
console.log("Set for two dice: ", twoDice);
let turnSets = [
[{ value: 0, waysToRoll: 1 }]
];
for (let i = 0; i < 11; i++) {
turnSets.push(addSets(turnSets[i], twoDice));
}
console.log("List of sets for 0 turns -> 11 turns: ", turnSets);
// Get number of ways to hit target position (18, 20, or 21) during first 11 turns:
const hits = targetPosition => turnSets.reduce(
(total, set) => {
const targetItem = set.find(({ value }) => value === targetPosition);
if (!targetItem) return total + 0; // There are zero ways to roll 18 in this many turns
return total + targetItem.waysToRoll;
},
0
);
for (let i = 1; i <= 133; i++) {
console.log(`Number of ways to land on space ${i} in (up to) 11 turns: `, hits(i));
}
// Merge items in a set that have equal values by summing their "waysToRoll"
function mergeEqual(set) {
return set.reduce((newSet, item) => {
const matchingValueIndex = newSet.findIndex(newItem => newItem.value === item.value);
if (matchingValueIndex === -1) return [...newSet, item];
return [
...newSet.slice(0, matchingValueIndex),
{ ...item, waysToRoll: newSet[matchingValueIndex].waysToRoll + item.waysToRoll },
...newSet.slice(matchingValueIndex + 1)
];
}, []);
}
function addSets(setA, setB) {
return mergeEqual(setA.flatMap(itemA => (
setB.map(itemB => ({
value: itemA.value + itemB.value,
waysToRoll: itemA.waysToRoll * itemB.waysToRoll
}))
)));
}