/*

  For more information about this file, see 
  "Choco: Constraint Programming i Java"
  http://www.hakank.org/webblogg/archives/001113.html
  


  This Choco program solves the following puzzle:

  Which is the smallest difference between two numbers X - Y 
  if you must use all the numbers exactly once.

*/

import choco.Problem;
import choco.*;
import choco.integer.*;

public class LeastDiff2 {

  public static void main(String[] args) {
    new LeastDiff2().puzzle();
  }

  public void puzzle () {
    Problem pb = new Problem();

    IntDomainVar A = pb.makeEnumIntVar("A", 0, 9);
    IntDomainVar B = pb.makeEnumIntVar("B", 0, 9);
    IntDomainVar C = pb.makeEnumIntVar("C", 0, 9);
    IntDomainVar D = pb.makeEnumIntVar("D", 0, 9);
    IntDomainVar E = pb.makeEnumIntVar("E", 0, 9);
    IntDomainVar F = pb.makeEnumIntVar("F", 0, 9);
    IntDomainVar G = pb.makeEnumIntVar("G", 0, 9);
    IntDomainVar H = pb.makeEnumIntVar("H", 0, 9);
    IntDomainVar I = pb.makeEnumIntVar("I", 0, 9);
    IntDomainVar J = pb.makeEnumIntVar("J", 0, 9);

    IntDomainVar[] letters = {A,B,C,D,E,F,G,H,I,J};
    
    IntDomainVar Diff = pb.makeBoundIntVar("Diff", 0, 10000);

    // temporary variables
    IntDomainVar X = pb.makeBoundIntVar("X", 0, 100000);
    IntDomainVar Y = pb.makeBoundIntVar("Y", 0, 100000);

    // all different
    for (int i = 1; i <= 9; i++) {
      for (int j = 0; j <= 9; j++) {
        if (i==j) {
          continue;
        }
        pb.post(pb.neq(letters[i], letters[j]));
      }
    }

    // X = 10000*A + 1000*B + 100*C + 10*D + 1*E
    pb.post(pb.eq(X, pb.scalar(new int[]{10000, 1000, 100, 10, 1},
                               new IntDomainVar[]{A,B,C,D,E})));
    // Y = 10000*F + 1000*G + 100*H + 10*I + J
    pb.post(pb.eq(Y, pb.scalar(new int[]{10000, 1000, 100, 10, 1},
                               new IntDomainVar[]{F,G,H,I,J})));

    // Diff = X - Y
    pb.post(pb.eq(pb.minus(X, Y), Diff));

    // minmize the difference
    pb.minimize(Diff,false);

    // solve the problem
    Solver s = pb.getSolver();
    pb.solve(true);

      // Print the solutions
      System.out.println("Result: "+ A.getVal() + B.getVal() + C.getVal() +D.getVal() + E.getVal() + " - " + F.getVal() + G.getVal() + H.getVal() + I.getVal() + J.getVal() + " = " + Diff.getVal() );

  } // end puzzle


} // end class
