toy
toy

Reputation: 137

How do I write a program to solve multiple questions?

What number between 1 and 7 do the following equal? A=, B=, C=, D=, E=, F=, G=

Given that:

  1. A !=ᅠ 2
  2. A + B = F
  3. C - D = G
  4. D + E = 2F
  5. E + G = F

The rules are:

Upvotes: 1

Views: 643

Answers (6)

Dr. belisarius
Dr. belisarius

Reputation: 61056

In Mathematica:

 Reduce[ a != 2 && f == a + b && g == c - d && f == (d + e)/2 && f == e + g && 
        First[And @@@ {0 < # < 8 & /@ {a, b, c, d, e, f, g}}], 
        {a, b, c, d, e, f, g}, Integers]  

Solutions:

(a == 1 && b == 1 && c == 4 && d == 3 && e == 1 && f == 2 && g == 1) || 
(a == 1 && b == 2 && c == 5 && d == 4 && e == 2 && f == 3 && g == 1) || 
(a == 1 && b == 2 && c == 7 && d == 5 && e == 1 && f == 3 && g == 2) || 
(a == 1 && b == 3 && c == 6 && d == 5 && e == 3 && f == 4 && g == 1) || 
(a == 1 && b == 4 && c == 7 && d == 6 && e == 4 && f == 5 && g == 1) || 
(a == 3 && b == 1 && c == 6 && d == 5 && e == 3 && f == 4 && g == 1) ||
(a == 3 && b == 2 && c == 7 && d == 6 && e == 4 && f == 5 && g == 1) || 
(a == 4 && b == 1 && c == 7 && d == 6 && e == 4 && f == 5 && g == 1) 

And so the only solution with seven different values is:

 (a == 3 && b == 2 && c == 7 && d == 6 && e == 4 && f == 5 && g == 1) 

Edit

A little more work is needed if you want to get the answer straight from Mathematica, as the condition "all values are different" is usually awful to write down. Here it is:

k = {a, b, c, d, e, f, g}; 
Reduce[
  a != 2 && f == a + b && g == c - d && f == (d + e)/2 && f == e + g && 
  First[And @@@ {0 < # < 8 & /@ k}] && 
  Times@(Sequence @@ (Subsets[k, {2}] /. {x_, y_} -> (x - y))) != 0, k, Integers]

Result

 (a == 3 && b == 2 && c == 7 && d == 6 && e == 4 && f == 5 && g == 1) 

Upvotes: 5

Sven
Sven

Reputation: 166

For a good solution you should at Apache Commons Math library for solving equation systems. For a simple solution brute force does the job. Mine looks like this:

public class Test {

    private static Value A = new Value("A");
    private static Value B = new Value("B");
    private static Value C = new Value("C");
    private static Value D = new Value("D");
    private static Value E = new Value("E");
    private static Value F = new Value("F");
    private static Value G = new Value("G");

    private static List<Value> VALUES = new ArrayList<Value>(Arrays.asList(
            A,B,C,D,E,F,G
    ));

    private static Rule RESULT = new CombinedRule(
            new Rule(){
                public boolean isValid() {
                    return A.getValue() != 2;
                };
            },
            new Rule(){
                public boolean isValid() {
                    return A.getValue() + B.getValue() == F.getValue();
                }
            },
            new Rule(){
                public boolean isValid() {
                    return C.getValue() - D.getValue() == G.getValue();
                }
            },
            new Rule(){
                public boolean isValid() {
                    return D.getValue() + E.getValue() == 2 * F.getValue();
                }
            },
            new Rule(){
                public boolean isValid() {
                    return E.getValue() + G.getValue() == F.getValue();
                }
            },
            new Rule(){
                public boolean isValid() {
                    return A.getValue() != B.getValue()
                        && A.getValue() != C.getValue()
                        && A.getValue() != D.getValue()
                        && A.getValue() != E.getValue()
                        && A.getValue() != F.getValue()
                        && A.getValue() != G.getValue()
                        && B.getValue() != C.getValue()
                        && B.getValue() != D.getValue()
                        && B.getValue() != E.getValue()
                        && B.getValue() != F.getValue()
                        && B.getValue() != G.getValue()
                        && C.getValue() != D.getValue()
                        && C.getValue() != E.getValue()
                        && C.getValue() != F.getValue()
                        && C.getValue() != G.getValue()
                        && D.getValue() != E.getValue()
                        && D.getValue() != F.getValue()
                        && D.getValue() != G.getValue()
                        && E.getValue() != F.getValue()
                        && E.getValue() != G.getValue()
                        && F.getValue() != G.getValue();
                }
            }

    );

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        iterateOn(0);
        System.out.println(System.currentTimeMillis()-start+" millis.");
    }

    private static void iterateOn(int valueNo){
        if(valueNo < VALUES.size()){
            Value v = VALUES.get(valueNo);
            for(int value = 1; value < 8; value++){
                v.setValue(value);
                if(RESULT.isValid()) System.out.println(VALUES);
                iterateOn(valueNo+1);
            }
        }
    }

}

To improve performance you can use a list of all possible values and simply permutate this. This reduces the total amount of loops from about 960000 to about 13000 but introduces some list creation costs. Here is the code change:

public static void main(String[] args) {
    List<Integer> possibleValues = new ArrayList<Integer>();
    for(int value = 1; value < 8; value++){
        possibleValues.add(Integer.valueOf(value));
    }
    long start = System.currentTimeMillis();
    iterateOn(0, possibleValues);
    System.out.println((System.currentTimeMillis()-start)+" millis.");
}

private static void iterateOn(int valueIndex, List<Integer> possibleValues){
    Value v = VALUES.get(valueIndex);
    for(int i = 0; i < possibleValues.size(); i++){
        Integer currentValue = possibleValues.get(i);
        v.setValue(currentValue);
        if(RESULT.isValid()) System.out.println(VALUES);
        if(possibleValues.size() > 1){
            List<Integer> remainingValues = new ArrayList<Integer>(possibleValues);
            remainingValues.remove(currentValue);
            iterateOn(valueIndex+1, remainingValues);
        }
    }
}

Upvotes: 0

Michael Konietzka
Michael Konietzka

Reputation: 5499

You need to define to the rules in an appropriate way in java code and make all valid permutations of {1,2,3,4,5,6,7} and check, which permutations fit into this rules. I have done this already here for an other permutation question: How to write an "all these numbers are different" condition in Java?

Adapted on your rules, the code can look like this:

import java.util.Arrays;

class Graph26 {
    private static final int A = 0;
    private static final int B = 1;
    private static final int C = 2;
    private static final int D = 3;
    private static final int E = 4;
    private static final int F = 5;
    private static final int G = 6;

    private final static boolean rule1(final int[] n) {
        return n[A] != 2;
    }

    private final static boolean rule2(final int[] n) {
        return n[A] + n[B]  == n[F];
    }

    private final static boolean rule3(final int[] n) {
        return n[C] - n[D]  == n[G];
    }

    private final static boolean rule4(final int[] n) {
        return n[D] + n[E] == 2*n[F];
    }

    private final static boolean rule5(final int[] n) {
        return n[E] + n[G]  == n[F];
    }


    private final static boolean isValid(final int[] nodes) {
        return rule1(nodes) && rule2(nodes) && rule3(nodes) && rule4(nodes)
                && rule5(nodes);
    }

    class Permutation {
        private final int[] o;
        private boolean perms = true;

        public boolean hasPerms() {
            return perms;
        }

        Permutation(final int[] obj) {
            o = obj.clone();
        }

        private int[] nextPerm() {
            int temp;
            int j = o.length - 2;
            while (o[j] > o[j + 1]) {
            j--;
            if (j < 0) {
            perms = false;
            break;
            }
            }
            if (perms) {
            int k = o.length - 1;
            while (o[j] > o[k]) {
            k--;
            }
            temp = o[k];
            o[k] = o[j];
            o[j] = temp;
            int r = o.length - 1;
            int s = j + 1;
            while (r > s) {
            temp = o[s];
            o[s] = o[r];
            o[r] = temp;
            r--;
            s++;
            }
            }
            return o.clone();
        }
    }

    public static void main(final String[] args) {
        int[] nodes = new int[] { 1, 2, 3, 4, 5, 6, 7};
        final Graph26 graph = new Graph26();
        final Permutation p = graph.new Permutation(nodes);
        int i = 0;
        while (p.hasPerms()) {
        if (isValid(nodes)) {
        System.out.println(Arrays.toString(nodes));
        }
        i++;
        nodes = p.nextPerm();
        }
        System.out.println(i);
    }
}

This will define rules1..5 regarding the rules defined in the question and perform a check on all !7=5040 permutations of {1,2,3,4,5,6,7}. You can see this in action here: https://ideone.com/wwxG0

which results in (A,B,C,D,E,F,G): [3, 2, 7, 6, 4, 5, 1]

Upvotes: 2

The simplest approach is to have 7 nested loops:

for(int a = 1; a < 8 ; a++) {
  for(int b = 1; b < 8; b++) {
    same for c, d, e, f, g
    ....
    see if all conditions hold, and if yes, print out all values.
  }
}

Remember it is a condition that all variables have different value.

Upvotes: 1

Lou Franco
Lou Franco

Reputation: 89232

There a 7! ways to arrange the numbers, which aren't that many -- use brute force, and it will probably be fast enough. Even if you don't want to generate the permutations, you can use 7 nested for loops and it will be 7^7 iterations. You can check A!=2 at the first for loop, move F to the third level, and you can check A+B=F at level 3, D+E=2F at level 5. That will cut iterations.

Not an appropriate answer for homework or interview -- but if you just need the answer, you'll have it faster with brute force.

Upvotes: 2

Kevin Sylvestre
Kevin Sylvestre

Reputation: 38062

You are best off to select a linear programming library to do the heavy lifting. Try:

http://www.gnu.org/software/glpk/

Upvotes: 0

Related Questions