Enigmatic Code

Programming Enigma Puzzles

Enigma 494: Look blank

From New Scientist #1646, 7th January 1989 [link]

In the following long division sum I’ve marked the position of each digit. I can tell you that there were no 1s and no 0s but that all other digits occurred at least twice. Also (although you don’t actually need this information) all four digits of the answer were different.

Enigma 494

What is the six-figure dividend?

[enigma494]

4 responses to “Enigma 494: Look blank

  1. Jim Randell 8 April 2019 at 7:58 am

    We can use the [[ SubstitutedDivision() ]] solver from the enigma.py library to solve this puzzle.

    We can use the [[ --extra ]] parameter to include the additional check that all digits between 2 and 9 occur at least twice in the completed sum.

    This run file executes in 134ms.

    Run: [ @repl.it ]

    #!/usr/bin/env python -m enigma -r
    
    #        IJKL
    #    --------
    # GH ) ABCDEF
    #      MNP
    #      ---
    #       QRD
    #       STU
    #       ---
    #         VE
    #         WX
    #         --
    #          YF
    #          YF
    #          ==
    
    SubstitutedDivision
    
    # there are no 0's and no 1's
    --digits="2-9"
    
    # the main division sum
    "ABCDEF / GH = IJKL"
    
    # the intermediate subtraction sums
    "ABC - MNP = QR"
    "QRD - STU = V"
    "VE - WX = Y"
    "YF - YF = 0"
    
    # extra condition: each valid digit occurs (at least) twice in the full sum
    --code="check = lambda *s: all(s.count(d) > 1 for d in irange(2, 9))"
    --extra="check(I, J, K, L, G, H, A, B, C, D, E, F, M, N, P, Q, R, D, S, T, U, V, E, W, X, Y, F, Y, F)"
    
    # the answer is the dividend
    --answer="ABCDEF"
    
    # the digits in the result are distinct [optional]
    --distinct="IJKL"
    
    # tidy up output [optional]
    --solution=""
    

    Solution: The dividend is 253536.

    The full sum is: 253536 ÷ 32 = 7923.

  2. Brian Gladman 8 April 2019 at 5:48 pm

    I have been playing with Jim’s excellent minizinc.py wrapper for the MiniZinc constraint solver so this seemed like a nice puzzle to try it out.

    from minizinc import MiniZinc, var, alphametic, substitute
    
    fmt = """
                  A B C D
            -------------
        E F ) G H I J K L
              M N O 
              -----
                P Q J 
                R S T
                -----
                    U K 
                    V W
                    ---
                      X L 
                      X L
                      ===
    """
    
    p = MiniZinc(f"""
    
    include "globals.mzn";
    
    % declare the decision variables
    {var("2..9", "ABCDEFGHIJKLMNOPQRSTUVWX")};
    {var("array[1..24] of", "2..9", "Y")} = [{', '.join("ABCDEFGHIJKLMNOPQRSTUVWX")}];
    
    % overall division sum
    constraint {alphametic("{EF} * {ABCD} = {GHIJKL}")};
    
    % partial products
    constraint {alphametic("{A} * {EF} = {MNO}")};
    constraint {alphametic("{B} * {EF} = {RST}")};
    constraint {alphametic("{C} * {EF} = {VW}")};
    constraint {alphametic("{D} * {EF} = {XL}")};
    
    % partial differences
    constraint {alphametic("{GHI} - {MNO} = {PQ}")};
    constraint {alphametic("{PQJ} - {RST} = {U}")};
    constraint {alphametic("{UK} - {VW} = {X}")};
    
    % at least two digits from each of 2..9
    constraint forall (x in 2..9) (at_least(2, Y, x));
    
    solve satisfy;
    
    """)
    
    for s in p.solve():
      print(p.substitute(s, fmt))
    
    • Jim Randell 9 April 2019 at 9:04 am

      I think that because there are some symbols that appear more than once in the sum the code that count their occurrences needs a minor adjustment. (Although it doesn’t change the answer that is found – you can change the string of symbols to check to a 29 character string).

      But as you construct the original sum to output the solution you could move the check into the Python code, and have a simpler MiniZinc model (although this requires MiniZinc to be returning all solutions (which is the default behaviour)).

      from minizinc import MiniZinc, var, alphametic
       
      fmt = """
                    A B C D
              -------------
          E F ) G H I J K L
                M N O 
                -----
                  P Q J 
                  R S T
                  -----
                      U K 
                      V W
                      ---
                        X L 
                        X L
                        ===
      """
       
      p = MiniZinc(f"""
       
      % declare the decision variables
      {var("2..9", "ABCDEFGHIJKLMNOPQRSTUVWX")};
       
      % overall division sum
      constraint {alphametic("{EF} * {ABCD} = {GHIJKL}")};
       
      % partial products
      constraint {alphametic("{A} * {EF} = {MNO}")};
      constraint {alphametic("{B} * {EF} = {RST}")};
      constraint {alphametic("{C} * {EF} = {VW}")};
      constraint {alphametic("{D} * {EF} = {XL}")};
       
      % partial differences
      constraint {alphametic("{GHI} - {MNO} = {PQ}")};
      constraint {alphametic("{PQJ} - {RST} = {U}")};
      constraint {alphametic("{UK} - {VW} = {X}")};
       
      solve satisfy;
       
      """)
      
      for s in p.solve():
        r = p.substitute(s, fmt)
        # check each digit 2..9 occurs (at least) twice in the sum
        if all(r.count(x) > 1 for x in '23456789'):
          print(r)
      
  3. GeoffR 10 April 2019 at 8:43 pm

    A standard MiniZinc solution.

    % A Solution in MiniZinc 
    include "globals.mzn";
    
    %          I J K L
    %     ------------
    % GH ) A B C D E F
    %      M N P
    %      ----
    %        Q R D
    %        S T U
    %        -----
    %            V E
    %            W X
    %            ---
    %              Y F
    %              Y F
    %              ===
    
    var 2..9:A; var 2..9:B; var 2..9:C; var 2..9:D; var 2..9:E; 
    var 2..9:F; var 2..9:G; var 2..9:H; var 2..9:I; var 2..9:J; 
    var 2..9:K; var 2..9:L; var 2..9:M; var 2..9:N; var 2..9:P; 
    var 2..9:Q; var 2..9:R; var 2..9:S; var 2..9:T; var 2..9:U; 
    var 2..9:V; var 2..9:W; var 2..9:X; var 2..9:Y; 
    
    % all four digits of the answer were different
    constraint all_different ( [I,J,K,L] );
    
    var 10..99: GH = 10*G + H;
    var 100000..999999: ABCDEF = 100000*A + 10000*B + 1000*C + 100*D + 10*E + F;
    var 1000..9999:IJKL = 1000*I + 100*J + 10*K + L;
    
    var 100..999: ABC = 100*A + 10*B + C;
    var 100..999: MNP = 100*M + 10*N + P;
    
    var 10..99: QR = 10*Q + R;
    var 100..999: QRD = 100*Q + 10*R + D;
    
    var 100..999: STU = 100*S + 10*T + U;
    var 10..99: VE = 10*V + E;
    var 10..99: WX = 10*W + X;
    var 10..99: YF = 10*Y + F;
    
    % intermediate multiplication and subtraction sums
    constraint I * GH == MNP /\ ABC - MNP == QR;
    constraint J * GH == STU /\ QRD - STU == V;
    constraint K * GH == WX /\ VE - WX == Y;
    constraint L * GH == YF;
    
    % all other digits (apart from 0 and 1) occurred at least twice
    constraint forall (d in 2..9) 
    (at_least(2, [A,B,C,D,E,F,G,H,I,J,K,L,M,N,P,Q,R,S,T,U,V,W,X,Y], d));
    
    solve satisfy;
    
    % A = 2; B = 5; C = 3; D = 5; E = 3; F = 6;
    % G = 3; H = 2; I = 7; J = 9; K = 2; L = 3;
    % M = 2; N = 2; P = 4; Q = 2; R = 9; S = 2;
    % T = 8; U = 8; V = 7; W = 6; X = 4; Y = 9;
    % ----------
    % ==========
    % Finished in 247msec
    
    %          7 9 2 3
    %     ------------
    % 3 2 )2 5 3 5 3 6
    %      2 2 4
    %      -----
    %        2 9 5
    %        2 8 8
    %        -----
    %            7 3
    %            6 4
    %            ---
    %              9 6
    %              9 6
    %              ===
    
    

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: