-4

I found a article online about a 3rd grade math in Vietnam. I guess it would be interesting to see how we can solve this problem. In mathematical or programmatic way.

I wrote a test function for this, feel free to adapt it into any programming language you are comfortable with :

var answer = [1,1,1,1,1,1,1,1,1,1];
var isCorrect = function (answer) {
    return ((((((((((((a[0]+13)*a[1])/a[2])+a[3])+12)*a[4])-a[5])-11)+a[6])*a[7])/a[8])-10) === 66;
};

The rule is there should be no repeatable number in the array. Numbers accepted are 1-9.

DucDigital
  • 4,580
  • 9
  • 49
  • 97

4 Answers4

1
from constraint import *

def formula(a, b, c, d, e, f, g, h, i):
    return abs(a + (13 * (b / c)) + d + (12 * e) - f -
               11 + ((g * h) / i) - 10 - 66) < 0.001

if __name__ == '__main__':
    all_vals = [float(i) for i in xrange(1, 10)]
    p = Problem()
    [p.addVariable(l, all_vals) for l in 'abcdefghi']

    p.addConstraint(AllDifferentConstraint())
    p.addConstraint(FunctionConstraint(formula), 'abcdefghi')
    result = p.getSolution()
    print [s for s in sorted(result.items(), key=lambda (k,v): k)]

The answers are:

[('a', 9.0), ('b', 8.0), ('c', 6.0), 
 ('d', 2.0), ('e', 4.0), ('f', 1.0), 
 ('g', 5.0), ('h', 7.0), ('i', 3.0)]
  • This is still incorrect. The question imply that you need to follow the flow. So the actual math formular is: ((((((((((((a+13)*b)/c)+d)+12)*e)-f)-11)+g)*h)/i)-10) = 66 – DucDigital May 22 '15 at 22:54
1

Maraca, your MATLAB code works well, except the S line should be changed to obtain the correct arithmetic results. The new code is:

p = perms(1:9);
S = p(:,1)+(13.*p(:,2)./p(:,3))+p(:,4)+(12.*p(:,5))-p(:,6)-11+(p(:,7).*p(:,8)./p(:,9))-10 == 66;
sum(S)
p(S,:)

For example, one test solution is (a b c d e f g h i) = (3 2 1 5 4 7 9 8 6)

Using this change in the code, there are 128 unique solutions.

See the link.

0

Matlab / Octave (brute force):

p = perms(1:9) ;
S = (((((((((((p(:,1)+13).*p(:,2))./p(:,3)+p(:,4))+12).*p(:,5))-p(:,6))-11)+p(:,7)).*p(:,8))./p(:,9))-10) == 66 ;
sum(S)
p(S,:)

I executed it on octave online and it suggests that there are 144 solutions which took just a small fraction of a second to calculate. (http://octave-online.net the initial pop-up looks scary, but it is just trying to help, click it away and copy the whole program code into the console line at the bottom and hit [return] to see all 144 solutions, sometimes you get errors "payload too large" but it's only display, the math is working fine in the background.)

Explanation

For a math problem obviously a programming language designed to solve those is a good choice and can take off a lot of work from your shoulders, so I've used Octave although I'm a Java programmer, here is what the program does:

  1. 1:9 gives a vector with the numbers 1 to 9 (1 x 9)
  2. perms() calculates all permutations of this vector and returns it as matrix (9! x 9)
  3. ; suppresses the output
  4. p = the permutation matrix is stored in p
  5. p(:,n) accesses the nth column of p, so all solutions are calculated at once
  6. .* and ./ ensure cell-wise multiplication and not standard matrix multiplication
  7. the comparison of the resulting vector with 66 returns a vector of logicals which is stored in S and is like a vector that is 1 when the equation is true and 0 otherwise (9! x 1)
  8. sum(S) outputs the number of solutions
  9. p(S,:) returns all rows where the equation from before was true, the solutions (144 x 9)
maraca
  • 8,468
  • 3
  • 23
  • 45
0

I guess there could be a more efficient way approach to the problem but, scince there are only 9 variables with 9 possibile values and we have computers, brute force.

The idea is to try the check() function for every permutation, i.e. ways you can put the numbers 1 through 9 in the array a[]. That means 9! iterations = 362880 wwich my laptop can handle in a couple of seconds.

I build the recursove permutate(): For each level It's in, the permutate function cycles the numbers 1 through 9, puts each of them in the level- position of the array( but only if the number is not already in the previous positions) and than calls itself for teh next level. When in level 9, the array is full so It can call the check function.

here's the code in java:

public class Test {
    static float[] a = { 0, 0, 0, 0, 0, 0, 0, 0, 0};
private static int countSolutions = 0;
public static void main(String[] args){
    permutate(0);
    System.out.println(countSolutions);
}

public static boolean permutate( int level){
    boolean isCorrect = false;
    if(level == 9){
        isCorrect = check();
        if(!isCorrect){
        }
    }
    else 
        for(int i = 1; i <= 9; i++){
            int j = 0;
            for(; j < level && a[j]!=i; j++);
            if( j == level){
                a[level] = i;
                isCorrect = permutate( level + 1);
            }
        }
    return isCorrect;
}

private static boolean check() {
    float result = ((((((((((((a[0]+13)*a[1])/a[2])+a[3])+12)*a[4])-a[5])-11)+a[6])*a[7])/a[8])-10);
    if ( result == 66){
        countSolutions ++;
        for (int i = 0; i < 9; i++) {
            System.out.print(a[i]+",");
        }
        System.out.println();
        return true;
    }else{
        return false;
    }
}

}

Results (144):

1.0 2.0 4.0 7.0 5.0 8.0 3.0 6.0 9.0

1.0 2.0 7.0 5.0 3.0 4.0 9.0 8.0 6.0

....

....

ppDemo
  • 36
  • 3