examples/money.mod
changeset 1 c445c931472f
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/examples/money.mod	Mon Dec 06 13:09:21 2010 +0100
     1.3 @@ -0,0 +1,62 @@
     1.4 +/* MONEY, a crypto-arithmetic puzzle */
     1.5 +
     1.6 +/* Written in GNU MathProg by Andrew Makhorin <mao@gnu.org> */
     1.7 +
     1.8 +/* This is the classic example of a crypto-arithmetic puzzle published
     1.9 +   in the Strand Magazine by Henry Dudeney:
    1.10 +
    1.11 +        S E N D
    1.12 +      +
    1.13 +        M O R E
    1.14 +      ---------
    1.15 +      M O N E Y
    1.16 +
    1.17 +   In this puzzle the same letters mean the same digits. The question
    1.18 +   is: how to replace all the letters with the respective digits that
    1.19 +   makes the calculation correct?
    1.20 +
    1.21 +   The solution to this puzzle is:
    1.22 +   O = 0, M = 1, Y = 2, E = 5, N = 6, D = 7, R = 8, and S = 9.
    1.23 +
    1.24 +   References:
    1.25 +   H. E. Dudeney, in Strand Magazine vol. 68 (July 1924), pp. 97, 214.
    1.26 +
    1.27 +   (From Wikipedia, the free encyclopedia.) */
    1.28 +
    1.29 +set LETTERS := { 'D', 'E', 'M', 'N', 'O', 'R', 'S', 'Y' };
    1.30 +/* set of letters */
    1.31 +
    1.32 +set DIGITS := 0..9;
    1.33 +/* set of digits */
    1.34 +
    1.35 +var x{i in LETTERS, d in DIGITS}, binary;
    1.36 +/* x[i,d] = 1 means that letter i is digit d */
    1.37 +
    1.38 +s.t. one{i in LETTERS}: sum{d in DIGITS} x[i,d] = 1;
    1.39 +/* each letter must correspond exactly to one digit */
    1.40 +
    1.41 +s.t. alldiff{d in DIGITS}: sum{i in LETTERS} x[i,d] <= 1;
    1.42 +/* different letters must correspond to different digits; note that
    1.43 +   some digits may not correspond to any letters at all */
    1.44 +
    1.45 +var dig{i in LETTERS};
    1.46 +/* dig[i] is a digit corresponding to letter i */
    1.47 +
    1.48 +s.t. map{i in LETTERS}: dig[i] = sum{d in DIGITS} d * x[i,d];
    1.49 +
    1.50 +var carry{1..3}, binary;
    1.51 +/* carry bits */
    1.52 +
    1.53 +s.t. sum1: dig['D'] + dig['E']            = dig['Y'] + 10 * carry[1];
    1.54 +s.t. sum2: dig['N'] + dig['R'] + carry[1] = dig['E'] + 10 * carry[2];
    1.55 +s.t. sum3: dig['E'] + dig['O'] + carry[2] = dig['N'] + 10 * carry[3];
    1.56 +s.t. sum4: dig['S'] + dig['M'] + carry[3] = dig['O'] + 10 * dig['M'];
    1.57 +s.t. note: dig['M'] >= 1; /* M must not be 0 */
    1.58 +
    1.59 +solve;
    1.60 +/* solve the puzzle */
    1.61 +
    1.62 +display dig;
    1.63 +/* and display its solution */
    1.64 +
    1.65 +end;