Enigmatic Code

Programming Enigma Puzzles

Enigma 857: Four cubes

From New Scientist #2012, 13th January 1996 [link]

Harry, Tom and I were challenged to find four perfect cubes, one consisting of one digit, one of two digits, one of three digits and one of four digits, such that the ten digits used included nine different digits. We were allowed to regard 0 as a valid solution for the one-digit cube.

Our solutions were all different. You might say that we each found two solutions, though each of us simply found an alternative for one of our numbers, the other three numbers being common to both solutions. The three numbers common to both my solutions did not appear in any of Harry’s or Tom’s solutions.

Please list those three numbers in ascending order.

[enigma857]

3 responses to “Enigma 857: Four cubes

  1. Jim Randell 24 June 2022 at 10:26 am

    This Python program runs in 61m. (Internal runtime is 2.2ms).

    Run: [ @replit ]

    from collections import defaultdict
    from enigma import (
      irange, inf, cb, ndigits, cproduct, union, nsplit,
      subsets, intersect, diff, chain, printf
    )
    
    # find 1-4 digit cubes
    d = defaultdict(list)
    for i in irange(0, inf):
      n = cb(i)
      k = ndigits(n)
      if k > 4: break
      d[k].append(n)
    
    # find solution sets that use 9 different digits
    ss = list(ss
      for ss in cproduct(d[k] for k in irange(1, 4))
        if len(union(nsplit(x) for x in ss)) == 9
    )
    
    # find pairs of solution sets that share 3 numbers
    rs = list(rs for rs in subsets(ss, size=2) if len(intersect(rs)) == 3)
    
    # choose a pair for D
    for D in rs:
      ds = intersect(D)
      # choose pairs for H and T
      for (H, T) in subsets(diff(rs, {D}), size=2):
        # H and T do not have any numbers in common with ds
        if any(ds.intersection(x) for x in chain(H, T)): continue
        # output solution
        printf("ans={ds}\n-> D={D}\n-> H/T={H} / {T}", ds=sorted(ds))
    

    Solution: The numbers were: 64, 729 5832.

    The setters numbers were: (0|1, 64, 729 5832).

    Harry and Tom’s numbers were: (0|1, 27 343 6859), (8, 27, 125|512, 4096).

    There are only 6 sets of cubes that use 9 different digits, and these combine to form 3 pairs, where each pair has 3 numbers in common. And these 3 pairs are the pairs found by T, D, H.

  2. GeoffR 24 June 2022 at 11:41 am

    A part programme/part manual solution.
    I chose to find the 6 sets of cubes for Tom, Dick and Harry and then manually annotate the multiple outputs to show that the conditions of the teaser had been met.

    % A Solution in MiniZinc 
    include "globals.mzn";
    
    var 0..9:A; var 0..9:B; var 0..9:C; var 0..9:D;
    var 0..9:E; var 0..9:F; var 0..9:G; var 0..9:H;
    var 0..9:I; var 0..9:J;
    
    constraint B > 0 /\ D > 0 /\ G > 0;
    
    % The ten digits used included nine different digits
    constraint card( {A, B, C, D, E, F, G, H, I, J} ) == 9;
    
    % Cubes are (A, BC, DEF, GHIJ)
    var 10..99: BC = 10*B + C;
    var 100..999: DEF = 100*D + 10*E + F;
    var 1000..9999: GHIJ = 1000*G + 100*H + 10*I + J;
    
    % Sets of cubes for 1, 2, 3 and 4 digit numbers
    set of int: cb1 == {0, 1, 8};
    set of int: cb2 = {n * n * n | n in 3..4};
    set of int: cb3 = {n * n * n | n in 5..9};
    set of int: cb4 = {n * n * n | n in 10..21};
    
    constraint A in cb1 /\ BC in cb2 /\ DEF in cb3 /\ GHIJ in cb4;
    
    solve satisfy;
    
    output [ "Cubes are " ++ show(A) ++ ", " ++ show(BC) ++ ", " 
    ++ show(DEF) ++ ", " ++ show(GHIJ) ];
    
    % Cubes are 0, 27, 343, 6859  Harry/Tom (1)
    % ----------
    % Cubes are 8, 27, 125, 4096  Harry/Tom (3)
    % ----------
    % Cubes are 8, 27, 512, 4096  Harry/Tom (4)
    % ----------
    % Cubes are 1, 27, 343, 6859  Harry/Tom (2)
    % ----------
    % Cubes are 0, 64, 729, 5832  Dick(1)
    % ----------
    % Cubes are 1, 64, 729, 5832  Dick(2)
    % ----------
    % ==========
    % Dick's three numbers in ascending order are 64, 729, 5832.
    
    
    
    
    
  3. Frits 30 June 2022 at 2:29 pm

    Following GeoffR’s approach.

       
    from enigma import SubstitutedExpression, is_cube_p
    
    # the alphametic puzzle
    p = SubstitutedExpression(
      [
       "is_cube_p(A)",
       "is_cube_p(BC)",
       "is_cube_p(DEF)",
       "is_cube_p(GHIJ)",
       # put A at the back so we don't miss a possible zero
       "nd(BCDEFGHIJA) == 9",
      ],
      answer="A, BC, DEF, GHIJ",
      # allow zero for A
      d2i={0: "BDG"},
      # number of different digits
      code="nd = lambda n: len(set(x for x in str(n)))",
      distinct="",
      verbose=0,    # use 256 to see the generated code
    )
    
    # collect solutions
    sols = [y for _, y in p.solve()]
    
    save = set()
    # find pairs of solution sets that share 3 numbers
    for s1 in sols:
      for s2 in sols:
        common = tuple(set(s1) & set(s2))
        if len(common) == 3:
          save.add(common)
          
    if len(save) < 3: exit(0)      
    
    # find entries for which all numbers don't exist in other entries
    for k1 in save:
      if any(x in k2 for k2 in save if k2 != k1 for x in k1): continue
      print("numbers:", ', '.join(str(x) for x in sorted(k1)))
    

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 )

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: