Given 4 digits [7, 6, 5, 1]. Find an expression(s) containing all those digits (once each) and
arithmetical operations: +, -, *, / and parentheses that evaluates to 21.
Example of possible expression: (7+6)*(5+1)
References:
| const nums = [7, 6, 5, 1]; | |
| const operations = new Set(['+', '-', '*', '/']); | |
| function permutations(nums, result = [], results = []) { | |
| if (nums.length === 0) { | |
| results.push([...result]); | |
| return; | |
| } | |
| for (let [index, num] of nums.entries()) { | |
| result.push(num); | |
| nums.splice(index, 1); | |
| permutations(nums, result, results); | |
| result.pop(); | |
| nums.splice(index, 0, num); | |
| } | |
| return results; | |
| } | |
| function combinations(operations, length, result = [], results = []) { | |
| if (result.length === length) { | |
| results.push([...result]); | |
| return; | |
| } | |
| for (let operation of operations) { | |
| result.push(operation); | |
| combinations(operations, length, result, results); | |
| result.pop(); | |
| } | |
| return results; | |
| } | |
| function solve(nums, operations, target) { | |
| const results = []; | |
| const operationCombinations = combinations(operations, 3); | |
| for (let numbers of permutations(nums)) { | |
| for (let ops of operationCombinations) { | |
| const tokens = [...numbers, ...ops]; | |
| if (evalRPN(tokens) === target) { | |
| results.push(tokens); | |
| } | |
| } | |
| } | |
| return results; | |
| } | |
| // Revers polish notation below | |
| const evalRPN = function(tokens) { | |
| const stack = []; | |
| for (let token of tokens) { | |
| if (!isOperation(token)) { | |
| stack.push(Number(token)); | |
| continue; | |
| } | |
| const b = stack.pop(); | |
| const a = stack.pop(); | |
| stack.push(evaluate(a, b, token)); | |
| } | |
| return stack.pop(); | |
| }; | |
| const isOperation = token => operations.has(token); | |
| function evaluate(a, b, operation) { | |
| switch (operation) { | |
| case '+': | |
| return a + b; | |
| case '-': | |
| return a - b; | |
| case '*': | |
| return a * b; | |
| case '/': | |
| return a / b; | |
| } | |
| } | |
| function rpnToString(tokens) { | |
| const stack = []; | |
| for (let token of tokens) { | |
| if (!isOperation(token)) { | |
| stack.push(token); | |
| continue; | |
| } | |
| const b = stack.pop(); | |
| const a = stack.pop(); | |
| stack.push(`(${a} ${token} ${b})`); | |
| } | |
| // unwrap top level brace | |
| return stack.pop().slice(1, -1); | |
| } | |
| function main() { | |
| const solutions = solve(nums, operations, 21); | |
| if (solutions.length === 0) { | |
| console.log('No solutions found...'); | |
| return; | |
| } | |
| console.log('Solutions:'); | |
| for (let solution of solutions) { | |
| console.log(' ', rpnToString(solution)); | |
| } | |
| } | |
| main(); |
Given 4 digits [7, 6, 5, 1]. Find an expression(s) containing all those digits (once each) and
arithmetical operations: +, -, *, / and parentheses that evaluates to 21.
Example of possible expression: (7+6)*(5+1)
References: