I\'ve tried to solve the problem below for a coding challenge but could not finish it in 1 hour. I have an idea on how the algorithm works but I\'m not quite sure how to best im
First, you need a method where you can input the expression
3141 * 5 / 9 * 26 / 5 * 3 - 5 * 8
and get the answer:
27182
Next, you need to create a tree structure. Your first and second levels are complete.
3
31, 3 + 1, 3 - 1, 3 * 1, 3 / 1
Your third level lacks a few expressions.
31 -> 314, 31 + 4, 31 - 4, 31 * 4, 31 / 4
3 + 1 -> 3 + 14, 3 + 1 + 4, 3 + 1 - 4, 3 + 1 * 4, 3 + 1 / 4
3 - 1 -> 3 - 14, 3 - 1 + 4, 3 - 1 - 4, 3 - 1 * 4, 3 - 1 / 4
3 * 1 -> 3 * 14, 3 * 1 + 4, 3 * 1 - 4, 3 * 1 * 4, 3 * 1 / 4
3 / 1 -> 3 / 14, 3 / 1 + 4, 3 / 1 - 4, 3 / 1 * 4, 3 / 1 / 4
You can stop adding leaves to a branch of the tree when a division yields a non integer.
As you can see, the number of leaves at each level of your tree is going to increase at a rapid rate.
For each leaf, you have to append the next value, the next value added, subtracted, multiplied, and divided. As a final example, here are 5 of the fourth level leaves:
3 * 1 + 4 -> 3 * 1 + 41, 3 * 1 + 4 + 1, 3 * 1 + 4 - 1, 3 * 1 + 4 * 1,
3 * 1 + 4 / 1
Your code has to generate 5 expression leaves for each leaf until you've used all of the input digits.
When you've used all of the input digits, check each leaf equation to see if it equals the value.
My Javascript implementation:
Will improve the code using web worker later on
// was not allowed to use eval , so this is my replacement for the eval function.
function evaluate(expr) {
return new Function('return '+expr)();
}
function calc(expr,input,target) {
if (input.length==1) {
// I'm not allowed to use eval, so I will use my function evaluate
//if (eval(expr+input)==target) console.log(expr+input+"="+target);
if (evaluate(expr+input)==target) document.body.innerHTML+=expr+input+"="+target+"<br>";
}
else {
for(var i=1;i<=input.length;i++) {
var left=input.substring(0,i);
var right=input.substring(i);
['+','-','*','/'].forEach(function(oper) {
calc(expr+left+oper,right,target);
},this);
}
}
};
function f(input,total) {
calc("",input,total);
}
I don't think it's necessary to build a tree, you should be able to calculate as you go -- you just need to delay additions and subtractions slightly in order to be able take the precedence into account correctly:
static void check(double sum, double previous, String digits, double target, String expr) {
if (digits.length() == 0) {
if (sum + previous == target) {
System.out.println(expr + " = " + target);
}
} else {
for (int i = 1; i <= digits.length(); i++) {
double current = Double.parseDouble(digits.substring(0, i));
String remaining = digits.substring(i);
check(sum + previous, current, remaining, target, expr + " + " + current);
check(sum, previous * current, remaining, target, expr + " * " + current);
check(sum, previous / current, remaining, target, expr + " / " + current);
check(sum + previous, -current, remaining, target, expr + " - " + current);
}
}
}
static void f(String digits, double target) {
for (int i = 1; i <= digits.length(); i++) {
String current = digits.substring(0, i);
check(0, Double.parseDouble(current), digits.substring(i), target, current);
}
}