Reputation: 137
What number between 1 and 7 do the following equal? A=, B=, C=, D=, E=, F=, G=
Given that:
The rules are:
Upvotes: 1
Views: 643
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
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
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
Reputation: 75426
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
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
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