'Trouble simplifying conditional
I'm having trouble simplifying a conditional statement. It looks like this:
There is an array of arrays like this, dice = [ [a, b], [c, d] ].
a, b, c, and d representing random numbers on a dice 1 > 6.
Every array in the array represents a roll of two dice where the last roll is [c, d] = [2, 5] for example,
and the second-last roll is [a, b] = [3, 6] for example.
Now if you roll 2 x 1 in a row or 2 x 6 in a row something happens.
so, a + c || a + d and b + c || b + d may not be 2 or 12.
The conditional below works but I think if you open the door to hell it looks prettier.
dice = last roll = [c, d]
prev = second last roll = [a, b]
if (dice[0] + prev[0] === 2 || dice[1] + prev[1] === 2 || dice[1] + prev[0] === 2 || dice[0] +
prev[1] === 2 &&
dice[0] + prev[0] === 12 || dice[1] + prev[1] === 12 || dice[1] + prev[0] === 12 || dice[0] +
prev[1] === 12){
//something happens here
}
Solution 1:[1]
I would do something like this:
var combinations = dice.reduce(function(acc, curr) {
return acc.concat(prev.map(function(curr2) {
return curr + curr2;
}));
}, []);
if (combinations.indexOf(2) !== -1 && combinations.indexOf(12) !== -1) {
//something happens here
}
In ES6 it is a little bit shorter:
const combinations = dice.reduce((acc, curr) => acc.concat(prev.map(curr2 => curr + curr2)), []);
if (combinations.indexOf(2) !== -1 && combinations.indexOf(12) !== -1) {
//something happens here
}
What this actually does is calculate all combinations (additions) and then check whether one is 2 and one is 12.
Solution 2:[2]
The condition can only happens when both dice
and prev
contain 1 or 6. So, we can just check that.
let throws = [[5,3],[1,6]];
let prev = throws[0];
let dice = throws[1];
if ((prev.includes(1) && dice.includes(1)) || (prev.includes(6) && dice.includes(6))){
console.log("2 or 12 occurs")
}
else {
console.log("2 and 12 do not occur")
}
Solution 3:[3]
What about something like the following?:
const one_and_six_found = (roll) => roll.includes(1) && roll.includes(6);
const two_rolls_have_one_and_six = (roll1, roll2) =>
one_and_six_found(roll1) && one_and_six_found(roll2);
console.log(two_rolls_have_one_and_six( [1, 6], [1, 6] ));
console.log(two_rolls_have_one_and_six( [6, 1], [1, 6] ));
console.log(two_rolls_have_one_and_six( [5, 1], [1, 6] ));
Solution 4:[4]
I came out with a simpler solution more fitted to your need
const throws1 = [[1, 2], [3, 4]]
const throws2 = [[1, 2], [3, 1]]
const throws3 = [[1, 6], [6, 1]]
const checkCondition = (prev, dice) => [1, 6].every(res => prev.includes(res) && dice.includes(res))
console.log(checkCondition(...throws1))
console.log(checkCondition(...throws2))
console.log(checkCondition(...throws3))
Solution 5:[5]
Here's the conditional simplified:
2*(a + b + c + d) == a*b + c*d + 16
Solution 6:[6]
I wasn't 100% sure about a couple of these answers so I thought I'd test them:
const orig = ([a, b], [c, d]) =>
((a + c === 2 || b + d === 2 || b + c === 2 || a + d === 2) && (a + c === 12 || b + d === 12 || b + c === 12 || a + d === 12));
const A = ([a, b], [c, d]) => 2*(a + b + c + d) == a*b + c*d + 16;
const B = (prev, dice) => [1, 6].every(res => prev.includes(res) && dice.includes(res));
const one_and_six_found = (roll) => roll.includes(1) && roll.includes(6);
const C = (roll1, roll2) => one_and_six_found(roll1) && one_and_six_found(roll2);
const D = (prev, dice) => (prev.includes(1) && dice.includes(1)) || (prev.includes(6) && dice.includes(6));
const E = (prev, dice) => {
const combinations = dice.reduce((acc, curr) => acc.concat(prev.map(curr2 => curr + curr2)), []);
return (combinations.indexOf(2) !== -1 && combinations.indexOf(12) !== -1);
};
const test = (fn) => {
for(let i = 1; i <= 6; i++)
for(let j = 1; j <= 6; j++)
for(let k = 1; k <= 6; k++)
for(let l = 1; l <= 6; l++)
if(fn([i, j], [k, l]) !== orig([i, j], [k, l])) {
console.log('failed on ' + [i, j, k, l].join(', '));
return false;
}
return true;
};
console.log('A', test(A) ? 'success' : 'failed');
console.log('B', test(B) ? 'success' : 'failed');
console.log('C', test(C) ? 'success' : 'failed');
console.log('D', test(D) ? 'success' : 'failed');
console.log('E', test(E) ? 'success' : 'failed');
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Stefan Jelner |
Solution 2 | holydragon |
Solution 3 | Ben Stephens |
Solution 4 | |
Solution 5 | |
Solution 6 |