Recent Updates Page 62 Toggle Comment Threads | Keyboard Shortcuts

  • Unknown's avatar

    Jim Randell 7:08 pm on 7 June 2019 Permalink | Reply
    Tags:   

    Teaser 2959: The Magnificent Seven 

    From The Sunday Times, 9th June 2019 [link] [link]

    After a day’s filming, a group of those involved in the film’s production went for a gallop.

    They split into threes, with a samurai leading each grouping.

    The seven samurai were:

    BRONSON, BRYNNER, BUCHHOLZ, COBURN, DEXTER, MCQUEEN and VAUGHN.

    The others involved in the gallop were:

    ALANIZ, ALONZO, AVERY, BISSELL, BRAVO, DE HOYOS, HERN, LUCERO, NAVARRO, RUSKIN, RUSSELL, SUAREZ, VACIO and WALLACH.

    For each grouping, any two names from the three had exactly 2 letters in common (e.g., BRYNNER and BRAVO have B and R in common).

    If I told you who accompanied BRONSON, you should be able to tell me who accompanied (a) MCQUEEN and (b) DEXTER.

    [teaser2959]

     
    • Jim Randell's avatar

      Jim Randell 11:16 pm on 7 June 2019 Permalink | Reply

      This Python program runs in 116ms.

      Run: [ @repl.it ]

      from enigma import (grouping, subsets, diff, unpack, filter_unique, printf)
      
      # the "others"
      others = (
        'ALANIZ', 'ALONZO', 'AVERY', 'BISSELL', 'BRAVO', 'DE HOYOS', 'HERN',
        'LUCERO', 'NAVARRO', 'RUSKIN', 'RUSSELL', 'SUAREZ', 'VACIO', 'WALLACH'
      )
      
      # selection function
      fn = grouping.share_letters(2)
      
      # find a gang for leader x, with remaining members chosen from ys
      def gang(x, ys):
        for (y, z) in subsets((y for y in ys if fn(x, y)), size=2):
          if fn(y, z):
            yield (y, z)
      
      # find multiple gangs, with leaders from x, followers from ys
      def gangs(xs, ys, gs=[]):
        # are we done?
        if not xs:
          yield gs
        else:
          # find a gang for the first leader
          for g in gang(xs[0], ys):
            # and solve for the rest
            yield from gangs(xs[1:], diff(ys, g), gs + [g])
      
      # record possible values for (g1, g2, g3)
      vs = list()
      
      # find possible 2-gangs led by BRONSON, DEXTER, MCQUEEN
      for gs in gangs(["BRONSON", "DEXTER", "MCQUEEN"], others):
        # check the remaining 2-gangs can be made with the remaining followers
        for _ in gangs(["BRYNNER", "BUCHHOLZ", "COBURN", "VAUGHN"], diff(others, *gs)):
          vs.append(gs)
          # we only need one example
          break
      
      # "if I told you who accompanied BRONSON ..."
      f = unpack(lambda B, D, M: B)
      # "... you could tell me who accompanied MCQUEEN and DEXTER"
      g = unpack(lambda B, D, M: (M, D))
      (ss, _) = filter_unique(vs, f, g)
      
      # output solutions
      for (B, D, M) in ss:
        printf("BRONSON + {B} -> DEXTER + {D}, MCQUEEN + {M}")
      

      Solution: (a) MCQUEEN was accompanied by HERN and RUSSELL. (b) DEXTER was accompanied by AVERY and DE HOYOS.

      There are only three possible ways that complete groupings can be made:

      BRONSON = BISSELL, DE HOYOS
      DEXTER = AVERY, LUCERO
      MCQUEEN = HERN, RUSSELL
      BRYNNER = NAVARRO, RUSKIN
      BUCHHOLZ = BRAVO, SUAREZ
      COBURN = ALONZO, VACIO
      VAUGHN = ALANIZ, WALLACH

      BRONSON = BISSELL, DE HOYOS
      DEXTER = AVERY, RUSSELL
      MCQUEEN = HERN, RUSKIN
      BRYNNER = LUCERO, NAVARRO
      BUCHHOLZ = BRAVO, SUAREZ
      COBURN = ALONZO, VACIO
      VAUGHN = ALANIZ, WALLACH

      BRONSON = BISSELL, LUCERO
      DEXTER = AVERY, DE HOYOS
      MCQUEEN = HERN, RUSSELL
      BRYNNER = NAVARRO, RUSKIN
      BUCHHOLZ = BRAVO SUAREZ
      COBURN = ALONZO, VACIO
      VAUGHN = ALANIZ, WALLACH

      Telling us the parters of BRONSON uniquely identifies the solution, so it must the last of these groupings.

      Like

  • Unknown's avatar

    Jim Randell 11:04 am on 7 June 2019 Permalink | Reply
    Tags:   

    Teaser 2906: In proportion 

    From The Sunday Times, 3rd June 2018 [link] [link]

    In 2000 the Sultan of Proportion told his five sons they would inherit his fortune in amounts proportionate to their ages at his death.

    Accordingly, they each recently received a different whole number of tesares. Strangely, if he had lived a few more hours the five ages would have been consecutive and each son would again have received a whole number of tesares. Such a delay would have benefited just one son (by 1000 tesares).

    How many tesares were distributed in total?

    [teaser2906]

     
    • Jim Randell's avatar

      Jim Randell 11:06 am on 7 June 2019 Permalink | Reply

      Assuming ages are expressed as a whole number of years.

      In the actual situation the five ages are all different, and in the hypothetical situation (which is a few hours later) the ages are consecutive, lets say:

      a + 1, a + 2, a + 3, a + 4, a + 5

      The proportion going to each son would be:

      (a + 1) / (5a + 15)
      (a + 2) / (5a + 15)
      (a + 3) / (5a + 15)
      (a + 4) / (5a + 15)
      (a + 5) / (5a + 15)

      In the actual case one of the sons is one year younger, and as the ages are all different it can only be the youngest son, so that actual ages are:

      a, a + 2, a + 3, a + 4, a + 5

      and the actual proportions are:

      a / (5a + 14)
      (a + 2) / (5a + 14)
      (a + 3) / (5a + 14)
      (a + 4) / (5a + 14)
      (a + 5) / (5a + 14)

      So the youngest son is better off by 1000 tesares in the hypothetical situation, so if the total number of tesares to be distributed is T, we have:

      T (a + 1) / (5a + 15) = T a / (5a + 14) + 1000
      T = 1000 / [(a + 1) / (5a + 15) – a / (5a + 14)]
      T = 1000 (5a + 14) (5a + 15) / (4a + 14)

      As the 5 sons were around in 2000 and the puzzle was set in 2018, we can suppose that each son is older than 18 (otherwise we can find a second solution).

      This Python program runs in 68ms.

      Run: [ @repl.it ]

      from enigma import (irange, div, printf)
      
      # splits for the specified ages (must all be integers)
      def split(T, ages):
        t = sum(ages)
        return list(div(T * x, t) for x in ages)
      
      # consider possible youngest ages (there is a further solution at a=9)
      for a in irange(18, 100):
      
        # the youngest son is 1000 better off in the hypothetical case
        # compute the total value to be distributed
        z = 5 * a + 14
        T = div(1000 * z * (z + 1), z - a)
        if T is None: continue
      
        # hypothetical ages (consecutive)
        h_ages = list(irange(a + 1, a + 5))
        h_splits = split(T, h_ages)
        if None in h_splits: continue
      
        # actual ages (the youngest is one year younger)
        ages = [a] + h_ages[1:]
        splits = split(T, ages)
        if None in splits: continue
      
        # all the rest (other than the youngest) lost out
        diffs = tuple(y - x for (x, y) in zip(splits, h_splits))
          
        printf("T={T}")
        printf("actual: ages={ages}, splits={splits}")
        printf("hypoth: ages={h_ages}, splits={h_splits}, diff={diffs}")
        printf()
      

      Solution: In total 383,160 tesares were distributed.

      The actual ages of the sons at the time of the Sultan’s death were: 59, 61, 62, 63, 64. The youngest son turning 60 shortly after.

      If we allow ages less than 18 then there is a further solution where the actual ages of the sons are: 9, 11, 12, 13, 14, and 70,800 tesares are distributed amongst them.

      Like

  • Unknown's avatar

    Jim Randell 1:07 pm on 6 June 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 482: [Alphabetical cricket] 

    From The Sunday Times, 23rd August 1970 [link]

    The Alphabet CC ended last season with a fine win against the Early Closers XI. Declaring at 155 for six they dismissed their opponents with only minutes to spare. The Early Closers’ captain, Bond, made a spirited 71 not out.

    “Nice gesture of the opposition to bat in alphabetical order”, said C. F. Arrowroot, the Alphabet president; “And did you notice that each one of the first three wickets fell when the total was the product of Bond’s score and that of the outgoing batsman?”

    “Even odder”, commented B. P. Biggin, “except when Collins was out the total at the fall of every one of their wickets was the square of the dismissed batsman’s score.”

    No one made a “duck” and there was just one “extra”. I should perhaps add that no two Early Closers had the same surname initial.

    How many did Collins score, and what was Bond’s score at the fall of the seventh wicket?

    This puzzle was originally published with no title.

    [teaser482]

     
    • Jim Randell's avatar

      Jim Randell 1:09 pm on 6 June 2019 Permalink | Reply

      Although not explicitly mentioned in the puzzle text, presumably we are talking about a cricket match.

      B is one of the first pair to go into bat, and at the 10th dismissal he is “not out”, so he is paired with every other batsman. If there is an A, he would be in the first pair (and the first to be dismissed), and C would be next (and be the second to be dismissed). If there isn’t an A, C would be in the first pair and be the first to be dismissed. So C is either the first or second batsman to be dismissed.

      I tackled this problem in 2 parts. The first part deals with the first three dismissals, where the score is always the product of B’s score and the dismissed batsman’s score (and two of the scores have to be the square of the dismissed batsman’s score – the one that isn’t identifies C).

      The second part deals with the remaining dismissals (4th – 10th) the scores have to be the square of the dismissed batsman’s score.

      When the 10th batsman is dismissed the total score must be a square less than 155, so not more than 12².

      This program runs in 80ms.

      Run: [ @repl.it ]

      from enigma import (irange, div, printf)
      
      # solve the first three dismissals, at each the total score is the
      # product of B's score and the dismissed batsman's score and all,
      # except C, the total is the square of the dismissed batsman's score.
      # return ([(<B's score>, <dismissed score>, <extras>), ...], <C>)
      # t = total so far
      # b = B's current score
      # ds = scores at dismissals
      # x = current extras
      # c = identify C
      def solve1(t=0, b=0, ds=[], x=0, c=None):
        n = len(ds)
        # are we done?
        if n == 3:
          # check C has been allocated
          if c in (0, 1):
            yield (ds, c)
        else:
          # possible extra
          for x2 in irange(x, 1):
            # possible current score for B
            for b2 in irange(b, 71):
              # calculate the score for the dismissed batsman (d)
              #   t2 = t + (b2 - b) + d + (x2 - x) = b2 * d
              # so:
              #   d = (t + b2 + x2 - b - x) / (b2 - 1)
              d = div(t + b2 + x2 - b - x, b2 - 1)
              if d is None or d < 1: continue
              t2 = b2 * d
              # is the total the square of d?
              c2 = c
              if t2 != d * d:
                # this must be C
                if c is not None: continue
                c2 = n
              yield from solve1(t2, b2, ds + [(b2, d, x2)], x2, c2)
      
      # solve the remaining dismissals, at each the total score is the
      # square of the dismissed batman's score
      # t = total score so far
      # b = B's current score
      # ds = scores of B and dismissed batsman
      # x = extra (0 or 1)
      def solve2(t=0, b=0, ds=[], x=0):
        n = len(ds)
        # are we done?
        if n == 10:
          # check an extra has been scored and B's score is 71
          if x == 1 and ds[-1][0] == 71:
            yield ds
        else:
          # possible extra
          for x2 in irange(x, 1):
            # possible scores for next batsman
            for d in irange(1, 12):
              # the new total is...
              t2 = d * d
              if not (t < t2 < 155): continue
              # calculate the current score for B
              b2 = t2 + b + x - t - d - x2
              if b2 < b: continue
              yield from solve2(t2, b2, ds + [(b2, d, x2)], x2)
                
      # solve for the first 3 dismissals
      for (ds1, c) in solve1():
        (b, d, x) = ds1[-1]
        # solve for the remaining dismissals
        for ds in solve2(b * d, b, ds1, x):
          # output the solution
          printf("[ds={ds}]")
          printf("-> C={C} [i={c}]; B[i=6]={B}", C=ds[c][1], B=ds[6][0])
      

      Solution: Collins scored 5. Bond had scored 41 at the 7th dismissal.

      The scores for the batsman (in dismissal order) were:

      2, 5 (Collins), 4, 5, 6, 8, 9, 10, 11, 12, 71 (not out, Bond)

      And the total scores at each dismissal were:

      4, 10 (Collins), 16, 25, 36, 64, 81, 100, 121, 144

      So there is an A (who was dismissed first). The extra was scored between A’s dismissal and C’s dismissal.

      Bond’s scores at each dismissal were:

      2, 2, 4, 8, 13, 33, 41, 50, 60, 71

      Like

  • Unknown's avatar

    Jim Randell 2:14 pm on 3 June 2019 Permalink | Reply
    Tags:   

    Teaser 2908: Number challenge 

    From The Sunday Times, 17th June 2018 [link] [link]

    I challenged Charlotte and Oliver to find a 9-digit number, using nine different digits, so that:

    • The number given by the 1st and 2nd digits was divisible by 2.
    • The number given by the 2nd and 3rd digits was divisible by 3.

    And so on until:

    • The number given by the 8th and 9th digits was divisible by 9.

    They each produced a different, correct solution.

    Charlotte claimed hers was the better solution since in her number, the number formed by the first seven digits was also divisible by 7, Charlotte’s age.

    What was Charlotte’s number?

    [teaser2908]

     
    • Jim Randell's avatar

      Jim Randell 2:15 pm on 3 June 2019 Permalink | Reply

      We can solve this puzzle using the [[ SubstitutedExpression() ]] solver from the enigma.py library.

      This run file executes in 124ms.

      Run: [ @repl.it ]

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --answer="ABCDEFGHI"
      
      "AB % 2 = 0"
      "BC % 3 = 0"
      "CD % 4 = 0"
      "DE % 5 = 0"
      "EF % 6 = 0"
      "FG % 7 = 0"
      "GH % 8 = 0"
      "HI % 9 = 0"
      
      # 2 solutions without this, only 1 with it
      "ABCDEFG % 7 = 0"
      

      Solution: Charlotte’s number was 187254963.

      And Oliver’s number was 781254963.

      Allowing leading zeros gives the following additional solutions:

      081254963
      087254963

      which could also be valid numbers for Oliver.

      Like

    • GeoffR's avatar

      GeoffR 7:19 pm on 3 June 2019 Permalink | Reply

      % A Solution in MiniZinc 
      include "globals.mzn"; 
      
      var 1..9: a; var 1..9: b; var 1..9: c;
      var 1..9: d; var 1..9: e; var 1..9: f;
      var 1..9: g; var 1..9: h; var 1..9: i;
      
      constraint all_different ( [a,b,c,d,e,f,g,h,i]);
      
      % two digit numbers
      var 10..99: ab = 10*a + b;
      var 10..99: bc = 10*b + c;
      var 10..99: cd = 10*c + d;
      var 10..99: de = 10*d + e;
      var 10..99: ef = 10*e + f;
      var 10..99: fg = 10*f + g;
      var 10..99: gh = 10*g + h;
      var 10..99: hi = 10*h + i;
      
      % number formed by first seven digits
      var 1000000..9999999: abcdefg = 1000000*a + 100000*b + 10000*c
      + 1000*d + 100*e + 10*f + g;
      
      % divisibility constraints
      constraint ab mod 2 == 0 /\ bc mod 3 == 0
      /\ cd mod 4 == 0 /\ de mod 5 == 0
      /\ ef mod 6 == 0 /\ fg mod 7 == 0
      /\ gh mod 8 == 0 /\ hi mod 9 == 0
      /\ abcdefg mod 7 == 0;   % only Charlotte
      
      solve satisfy;
      
      output ["Charlotte's number = " ++ show(a),show(b),show(c),
      show(d),show(e),show(f),show(g),show(h),show(i) ];
      
      % Charlotte's number = 187254963
      % time elapsed: 0.03 s
      % ----------
      % ==========
      % Finished in 217msec
      
      
      

      Like

  • Unknown's avatar

    Jim Randell 10:57 am on 2 June 2019 Permalink | Reply
    Tags:   

    Brainteaser 1590: Demonoes 

    From The Sunday Times, 28th February 1993 [link]

    Damien deleted a dot from one of the dominoes so that when I laid them out randomly to form a rectangle I ended up with the following arrangement:

    Fill in the outlines of the dominoes.

    This puzzle is included in the book Brainteasers (2002). The wording above is taken from the book. It is slightly changed from the original puzzle.

    [teaser1590]

     
    • Jim Randell's avatar

      Jim Randell 10:58 am on 2 June 2019 Permalink | Reply

      The puzzle uses a standard set of dominoes, so there should be 8 instances of each digit.

      In the supplied grid there 9 0’s and only 7 1’s, so one of the 0’s should be a 1.

      I adapted the code used in Enigma 179, Enigma 303 and Enigma 342 to give a generic solver for this type of problem, which also includes code to output solution grids.

      This Python code runs in 204ms.

      Run: [ @repl.it ]

      from enigma import update, printf
      from domino import DominoGrid
      
      grid = [
        6, 2, 4, 2, 4, 4, 5, 4,
        3, 0, 3, 5, 5, 3, 6, 6,
        4, 4, 3, 5, 5, 2, 2, 3,
        3, 6, 3, 0, 0, 1, 1, 6,
        1, 5, 6, 6, 0, 2, 1, 4,
        1, 4, 2, 5, 0, 2, 1, 3,
        1, 2, 0, 0, 0, 5, 0, 6,
      ]
      
      # look for 0's in the grid
      for (i, x) in enumerate(grid):
        if x != 0: continue
        # try to fit the dominoes with the 0 replaced by a 1
        p = DominoGrid(8, 7, update(grid, [(i, 1)]))
        for s in p.solve():
          printf("[@{i}: 0 -> 1]\n")
          p.output_solution(s)
      

      Solution: The dominoes are arranged thus:

      There are two 0-5 dominoes shown highlighted in yellow. One of them should be a 1-5 domino (although we don’t know which one).

      It is likely I will fold the [[ DominoGrid() ]] class into the enigma.py library in a future release.

      Like

      • John Crabtree's avatar

        John Crabtree 5:09 am on 13 August 2020 Permalink | Reply

        The 4-0 is unique, and then 3-0 is unique. With some perseverance, one gets to the grid shown by Jim.

        Like

  • Unknown's avatar

    Jim Randell 8:16 pm on 31 May 2019 Permalink | Reply
    Tags:   

    Teaser 2958: Sudoku crossword 

    From The Sunday Times, 2nd June 2019 [link] [link]

    George and Martha are doing a mathematical crossword. There is a 3×3 grid with the numbers 1 to 9 inclusive appearing once each. The clues are as follows:

    Across:
    top line: a prime number
    middle line: a prime number
    bottom line: a prime number

    Down:
    left column: a perfect square
    middle column: a perfect square
    right column: a prime number

    Although you do not need to know this, one of the diagonal three-digit numbers is also prime.

    What is the sum of the three “across” numbers?

    [teaser2958]

     
    • Jim Randell's avatar

      Jim Randell 8:18 pm on 31 May 2019 Permalink | Reply

      We can solve this using the [[ SubstitutedExpression() ]] solver from the enigma.py library.

      This run file executes in 180ms.

      Run: [ @repl.it ]

      #! python -m enigma -rr
      
      # consider the grid:
      #
      #  A B C
      #  D E F
      #  G H I
      
      SubstitutedExpression
      
      --digits="1-9"
      
      "is_prime(ABC)"
      "is_prime(DEF)"
      "is_prime(GHI)"
      
      "is_square(ADG)"
      "is_square(BEH)"
      "is_prime(CFI)"
      
      --answer="ABC + DEF + GHI"
      

      Solution: The sum of the three across numbers is 1449.

      The grid is:

      2 8 3
      5 4 7
      6 1 9

      The across numbers are: 283 (prime), 547 (prime), 619 (prime), and their sum is 1449.

      The down numbers are: 256 (square), 841 (square), 379 (prime), and their sum is 1476.

      The diagonals can be read (left to right) as 249 and 643, and the second of these is prime.

      There are no further solutions if the digit 0 is not excluded.

      Like

    • GeoffR's avatar

      GeoffR 8:43 am on 21 June 2019 Permalink | Reply

      
      % A Solution in MiniZinc
      include "globals.mzn"; 
      
      %  Grid
      %  A B C
      %  D E F
      %  G H I
      
      var 1..9:A; var 1..9:B; var 1..9:C; 
      var 1..9:D; var 1..9:E; var 1..9:F; 
      var 1..9:G; var 1..9:H; var 1..9:I; 
      
      constraint all_different ( [A,B,C,D,E,F,G,H,I]);
      
      % Rows
      var 100..999: ABC = 100*A + 10*B + C;
      var 100..999: DEF = 100*D + 10*E + F;
      var 100..999: GHI = 100*G + 10*H + I;
      
      % Columns
      var 100..999: ADG = 100*A + 10*D + G;
      var 100..999: BEH = 100*B + 10*E + H;
      var 100..999: CFI = 100*C + 10*F + I;
      
      predicate is_prime(var int: x) = 
      x > 1 /\ forall(i in 2..1 + ceil(sqrt(int2float(ub(x))))) 
      ((i < x) -> (x mod i > 0));
      
      set of int: sq3 = {n*n | n in 10..31};
      
      % Rows
      constraint is_prime(ABC) /\ is_prime(DEF) /\ is_prime(GHI);
      
      % Columns
      constraint ADG in sq3 /\ BEH in sq3 /\ is_prime(CFI);
      
      solve satisfy;
      
      output [ "Rows total is "++ show(ABC + DEF + GHI) ]
      ++ [ "\nRows are "++ show(ABC)  ++ ", " ++ show(DEF) ++ 
      " and " ++ show (GHI) ];
      
      % Rows total is 1449
      % Rows are 283, 547 and 619
      % time elapsed: 0.02 s
       %----------
      % ==========
      % Finished in 253msec
      

      Like

  • Unknown's avatar

    Jim Randell 9:45 am on 30 May 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 481: [Long Lane] 

    From The Sunday Times, 16th August 1970 [link]

    The houses in Long Lane are conventionally numbered; odd on one side, even on the other. Six of my friends, all of different professions, live there, all except Black on the same side of the road. Each man’s house has a two-digit number, and the sum of the twelve digits, which is a perfect square, equals the number of the solicitor’s house. One house, next door to Robinson, is vacant.

    Reversing the digits of the number of Robinson’s house give the number of the doctor’s house. Both numbers are primes. The two extreme numbers of the six are occupied by Jones and the dentist.

    Reversing the digits of Green’s house gives the number of the architect’s house, and the difference between the squares of these is the square of the number of journalist’s house. Smith and the stockbroker live next door to each other.

    What is the number of the vacant house? What is White’s profession? And what is the name of the stockbroker?

    This puzzle was originally published with no title.

    [teaser481]

     
    • Jim Randell's avatar

      Jim Randell 9:46 am on 30 May 2019 Permalink | Reply

      There are quite a few conditions. I started with the two conditions that deal with reversing one of the house numbers to get another number. Together these conditions give us the house numbers for two of the names and three of the jobs, so we can work out what the majority parity of the numbers is and fill out the remaining numbers appropriately.

      This Python program runs in 96ms.

      from enigma import (irange, filter2, is_prime, nreverse, is_square, subsets, flatten, printf)
      
      # select the first x in xs that satisfies f
      def select(xs, f):
        for x in xs:
          if f(x):
            return x
      
      # possible house numbers
      numbers = set(irange(10, 99))
      
      # split them into even and odd numbers
      (even, odd) = map(set, filter2(lambda n: n % 2 == 0, numbers))
      
      # complete a set of 6 house numbers
      def complete(ns):
        # count the even and odd numbers
        r0 = len(even.intersection(ns))
        r1 = len(odd.intersection(ns))
        # find the majority parity
        m = -1
        if r0 > 1: m += 1
        if r1 > 1: m += 2
        if m not in (0, 1): return
        # do we need to choose a minority number?
        for ys in subsets([odd, even][m].difference(ns), size=1 - [r1, r0][m]):
          # choose the remaining majority numbers
          for zs in subsets([even, odd][m].difference(ns), size=6 - len(ys) - len(ns)):
            s = ns.union(ys, zs)
            # sum the digits
            t = sum(flatten(divmod(n, 10) for n in s))
            # is a perfect square, and one of the numbers itself
            if not (t in s and is_square(t)): continue
            # return the candidate set
            yield (sorted(s), m, t)
      
      # consider Green's house number
      for Gre in numbers:
        # the reverse gives the number of the Architect's house
        Arc = nreverse(Gre)
        if Arc not in numbers: continue
        # and the difference between the squares
        # is the square of the number of the Journalist's house
        Jou = is_square(abs(Gre ** 2 - Arc ** 2))
        if Jou is None or Jou not in numbers: continue
      
        # Robinson's house number is a prime
        for Rob in numbers:
          if not is_prime(Rob): continue
          # and is the reverse of the Doctor's number
          Doc = nreverse(Rob)
          # which is also prime
          if not is_prime(Doc): continue
      
          # complete the set of numbers
          for (ns, m, t) in complete(set((Gre, Rob, Arc, Jou, Doc))):
            # the sum of the digits is the number of the Solicitor's house
            Sol = t
            # Black is in the minority parity house
            Bla = select(ns, (lambda n: n % 2 != m))
      
            # (at least) one of the houses next to Robinson is vacant
            vacant = set([Rob - 2, Rob + 2]).difference(ns)
            if len(vacant) < 1: continue
      
            # the extreme numbers are occupied by Jones and the Dentist
            for (Jon, Den) in subsets([ns[0], ns[-1]], size=2, permute=1):
      
              # and we now have 5 of the 6 professions
              ps = set([Arc, Jou, Doc, Sol, Den])
              if len(ps) != 5: continue
              Sto = select(ns, (lambda n: n not in ps))
      
              # and 4 of the 6 names
              ss = set([Gre, Rob, Bla, Jon])
              if len(ss) != 4: continue
              for (Smi, Whi) in subsets(ss.symmetric_difference(ns), size=2, permute=1):
      
                # Smith and the Stockbroker live next door to each other
                if not (abs(Smi - Sto) == 2): continue
      
                # output solutions
                name = { Gre: 'Green', Rob: 'Robinson', Bla: 'Black', Jon: 'Jones', Smi: 'Smith', Whi: 'White' }
                job = { Arc: 'Architect', Jou: 'Journalist', Doc: 'Doctor', Sol: 'Solicitor', Den: 'Dentist', Sto: 'Stockbroker' }
                for n in ns:
                  printf("{n}: {name} ({job})", name=name[n], job=job[n])
                printf("vacant = {vacant}", vacant=sorted(vacant))
                printf()
      

      Solution: The vacant house is number 29. White is the Solicitor. Robinson is the Stockbroker.

      The solution is completely determined:

      13: Jones (Doctor)
      31: Robinson (Stockbroker)
      33: Smith (Journalist)
      49: White (Solicitor)
      56: Black (Architect)
      65: Green (Dentist)

      29: vacant

      Like

  • Unknown's avatar

    Jim Randell 9:01 am on 29 May 2019 Permalink | Reply
    Tags:   

    Teaser 2909: Pensionable service 

    From The Sunday Times, 24th June 2018 [link] [link]

    A few years ago my father was lucky enough to have been able to retire and take his pension at sixty. I explained to my young son – not yet a teenager – that this was not now usual, and that neither I nor he would be so lucky in the future.

    When I am as old as my father is now, I shall be six times my son’s present age. By then, my son will be nine years older than I am now. (These statements all refer to whole years and not fractions of years).

    How old am I now?

    [teaser2909]

     
    • Jim Randell's avatar

      Jim Randell 9:02 am on 29 May 2019 Permalink | Reply

      Very straightforward.

      Run: [ @repl.it ]

      # suppose the father is currently x, the setter y and the son z
      
      from enigma import (irange, div, printf)
      
      # the son is not yet a teenager
      for z in irange(1, 12):
      
        # the father's current age is 6x the sons age
        x = 6 * z
      
        # but this is more than 60
        if not (x > 60): continue
      
        # the son will be 9 years older than the setters current age in (x - y) years
        # z + (x - y) = y + 9
        y = div(x + z - 9, 2)
        if y is None: continue
      
        printf("father = {x}, setter = {y}, son = {z}")
      

      Solution: You are 34.

      Manually (these are the same steps the program carries out):

      If the father is currently x, the setter y and the son z.

      Then, the son is not yet a teenager:

      z = 1 … 12

      The father is six times the son’s present age, x = 6z, and this is more than 60. The only two possibilities are:

      z = 11, x = 66
      z = 12, x = 72

      The son will be 9 years older than the setters current age in (x − y) years, so:

      z + (x − y) = y + 9
      y = (x + z − 9) / 2

      So we get:

      z = 11, x = 66, y = 34
      z = 12, x = 72, y = 75/2

      And only the first of these is viable.

      Liked by 1 person

    • Jim Randell's avatar

      Jim Randell 9:44 am on 30 May 2019 Permalink | Reply

      Here is a simple MiniZinc model for the puzzle:

      %#! minizinc -a
      
      var int: x; % father's age
      var int: y; % setter's age
      var int: z; % son's age
      
      % all ages are non-negative
      constraint x > y /\ y > z /\ z > 0;
      
      % father is aged over 60
      constraint x > 60;
      
      % son is not yet a teenager
      constraint z < 13;
      
      % father's age is 6x son's age
      constraint x = 6 * z;
      
      % the son will be 9 years older than the setters age in (x - y) years
      constraint z + (x - y) = y + 9;
      
      solve satisfy;
      

      Like

  • Unknown's avatar

    Jim Randell 7:44 am on 27 May 2019 Permalink | Reply
    Tags:   

    Teaser 2911: Remembering PINs 

    From The Sunday Times, 8th July 2018 [link] [link]

    My 10-year-old grandson has several PINs of various lengths to remember. To help him in this, he has systematically replaced different digits by different letters to get corresponding words as THREE, FIVE, SIX, SEVEN, NINE, TEN and FIFTEEN. Being very clever, he has arranged it so that each PIN is divisible by the number specified by the corresponding word.

    What is his PIN for FIFTEEN?

    [teaser2911]

     
    • Jim Randell's avatar

      Jim Randell 7:45 am on 27 May 2019 Permalink | Reply

      We can solve this puzzle using the [[ SubstitutedExpression() ]] solver from the enigma.py library, by writing an alphametic expression for each PIN.

      We also need to remember to allow leading zeros (this is required as TEN is divisible by 10, so NINE must have a leading zero).

      This run file executes in 130ms.

      Run: [ @replit ]

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --invalid="0,"
      --answer="FIFTEEN"
      
      "THREE % 3 = 0"
      "FIVE % 5 = 0"
      "SIX % 6 = 0"
      "SEVEN % 7 = 0"
      "NINE % 9 = 0"
      "TEN % 10 = 0"
      "FIFTEEN % 15 = 0"
      

      Solution: FIFTEEN = 1412550.

      The PINs are:

      THREE = 23955 or 29355
      FIVE = 1475
      SIX = 846
      SEVEN = 85750
      NINE = 0405
      TEN = 250
      FIFTEEN = 1412550

      H and R are 3 and 9 (in some order), the other letters are fixed.

      Like

    • GeoffR's avatar

      GeoffR 8:36 pm on 27 May 2019 Permalink | Reply

      % A Solution in MiniZinc 
      include "globals.mzn"; 
      
      var 0..9: F; var 0..9: I; var 0..9: V; var 0..9: E; 
      var 0..9: S; var 0..9: X; var 0..9: T; var 0..9: N; 
      var 0..9: H; var 0..9: R;
      
      constraint all_different ([F,I,V,E,S,X,T,N,H,R]);
      
      % N = 0, since TEN is divisible by 10
      constraint N == 0;  
      
      % Lower bound for variables allows for zero as a leading digit
      var 1000..99999: THREE = 10000*T + 1000*H + + 100*R + 11*E;
      var 100..9999: FIVE = 1000*F + 100*I + 10*V + E;
      var 10..999: SIX = 100*S + 10*I + X;
      var 1000..99999: SEVEN = 10000*S + 1000*E + 100*V + 10*E + 0;
      var 100..999: NINE = 100*I + 0 + E;  % since N = 0
      var 10..999: TEN = 100*T + 10*E + 0;
      var 100000..9999999: FIFTEEN = 1000000*F + 100000*I + 10000*F
      + 1000*T + 100*E + 10*E + N;
      
      constraint THREE mod 3 == 0 /\ FIVE mod 5 == 0 /\ SIX mod 6 == 0
      /\ SEVEN mod 7 == 0 /\ NINE mod 9 == 0 /\ TEN mod 10 == 0
      /\ FIFTEEN mod 15 == 0;
      
      solve satisfy;
      
      output ["FIFTEEN = " ++ show(FIFTEEN) ]
      ++ ["\nTHREE = "++ show(THREE) ]
      ++ ["\nFIVE = "++ show(FIVE) ]
      ++ ["\nSIX = "++ show(SIX) ]
      ++ ["\nSEVEN = "++ show(SEVEN) ]
      ++ ["\nNINE = "++ show(NINE) ]
      ++ ["\nTEN = "++ show(TEN) ];
      
      % FIFTEEN = 1412550
      % THREE = 29355  (or THREE = 23955)
      % FIVE = 1475
      % SIX = 846
      % SEVEN = 85750
      % NINE = 405
      % TEN = 250
      %----------
      %==========
      %Finished in 214msec
      
      
      
      

      Like

  • Unknown's avatar

    Jim Randell 8:55 am on 26 May 2019 Permalink | Reply
    Tags:   

    Brainteaser 1575: Quantum scales 

    From The Sunday Times, 15th November 1992 [link]

    The merchants of Mathematica only ever have to weigh things that weigh a whole number of “quantums”, that country’s unit of weight. They have a pair of balancing scales, and four weights. By using these weights (on either side of the balance) they can determine the weight of items weighing 1, 2, 3, 4, 5, … quantums, and they have designed the four weights so that this sequence continues as high as it possibly can with just four weights.

    With their balance and weights they can determine the weight of a Maxpack, but not of anything heavier.

    What is the weight of a Maxpack?

    This puzzle is included in the book Brainteasers (2002). The wording above is taken from the book. It is slightly changed from the original puzzle, to remove an ambiguity.

    [teaser1575]

     
    • Jim Randell's avatar

      Jim Randell 8:55 am on 26 May 2019 Permalink | Reply

      First let’s consider a problem with being able to balance exact weights of 1 … n.

      If we can weigh the numbers 1 … n using k weights, then by adding an extra weight of (2n + 1) we can weigh:

      1 … n (using the original combinations of weights)
      n + 1 … 2n (using (2n + 1) − x, for each x in the original combinations of weights)
      2n + 1 (using the extra weight)
      2n + 2 … 3n + 1 (using (2n + 1) + x, for each x in the original combinations of weight)

      So, with a weight of 1, we can weigh 1 … 1.

      With weights of (1, 3) we can weigh 1 … 4.

      With weights of (1, 3, 9) we can weigh 1 … 13.

      With weights of (1, 3, 9, 27) we can weigh 1 … 40.

      (Each weight is an increasing power of 3, 3⁰ = 1, 3¹ = 3, 3² = 9, 3³ = 27, …).

      And this would be the best we could manage if we had to balance exact weights.

      But in this puzzle we know each object we have to weigh is one of the values 1 … N.

      So there is no point in being able to balance an object with a weight of 1, as if we can make a combination with a weight of 2, and determine that our object is lighter than it, then, as weights are quantised, it can only have a weight of 1.

      In fact, there is no point in having weights of any odd value, as we determine that a weight is between (2k) and (2k + 2), then it can only have a weight of (2k + 1).

      So, by doubling the 4 weights to (2, 6, 18, 54) we can balance exact weights of 2, 4, 6, 8, …, 80.

      And we will be able to determine the weight of any object weighing 1 … 80 units:

      Any object that has an even value from 2 … 80 can be balanced exactly.

      Any object with an odd value from 3 … 79 can be isolated between two even values.

      Any object that weighs less than 2, must have a value of 1.

      The weight of any object that weighs more than 80 units cannot be determined exactly.

      Solution: The weight of a Maxpack is 80 units.

      Like

  • Unknown's avatar

    Jim Randell 10:39 pm on 24 May 2019 Permalink | Reply
    Tags:   

    Teaser 2957: Beyond the fields we know 

    From The Sunday Times, 26th May 2019 [link] [link]

    A field named “Dunsany levels” has four unequal straight sides, two of which are parallel. Anne — with her dog, Newton — walked from one corner of the field straight towards her opposite corner. Leon did the same from an adjacent corner along his diagonal. Yards apart, they each rested, halfway along their paths, where Leon, Anne and a signpost in the field were perfectly aligned. Straight fences from each corner converged at the signpost, making four unequal-area enclosures.

    Newton made a beeline for the signpost, on which the whole-number area of the field, in acres, was scratched out. Clockwise, the enclosures were named: “Plunkett’s bawn”, “Three-acre meadow”, “Drax sward” and “Elfland lea”. Anne knew that “Three-acre meadow” was literally true and that “Elfland lea” was smaller by less than an acre.

    What was the area of “Dunsany levels” in acres?

    [teaser2957]

     
    • Jim Randell's avatar

      Jim Randell 11:03 pm on 24 May 2019 Permalink | Reply

      The field is a trapezium (or trapezoid in US terminology).

      By drawing a diagram of the layout we determine that there is only a limited range of possible values for the area of Elfland Lea, and only one of which gives a whole number for the total area of the field.

      Solution: The total area of the field is 11 acres.

      Here is my analysis:

      We can draw the trapezium, ABCD, with the parallel sides horizontal, and we get a diagram like this:

      I assumed that “halfway” meant exactly at the midpoint.

      The midpoints of the diagonals AC and BD are exactly half way between the parallel lines AB and CD, so the signpost lies on the line XY (and obviously within the field).

      If we suppose the trapezium has a height of 2h, then the line XY is a distance h from both AB and CD.

      Now if we suppose the signpost S lies somewhere on this line:

      If the length of AB is q and the length of CD is p, and the trapezium has a height of 2h, then the area of the trapezium is:

      area(ABCD) = (p + q)h = ph + qh

      And the area of the triangles ABS and CDS are:

      area(ABS) = qh/2
      area(CDS) = ph/2

      (and the exact position of S does not matter, as long as it is on line XY).

      So it follows that the combined area of the triangles ADS and BCS is:

      area(ADS) + area(BCS) = ph/2 + qh/2

      (the same as the combined area of triangles ABS and CDS).

      And one of these pairs consists of “Three-acre meadow” and “Elfland lea”. So one enclosure is exactly 3 acres, and the other is somewhere between 2 and 3 acres (excluding the endpoints), so the combined area of these two enclosures is between 5 and 6 acres (excluding the endpoints).

      The total area of the field is twice this value, so it is an integer between 10 and 12 (excluding the endpoints). The answer follows directly, without the need to write a program.

      Like

  • Unknown's avatar

    Jim Randell 8:08 am on 23 May 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 480: [Hymn numbers] 

    From The Sunday Times, 9th August 1970 [link]

    The church hymn board shows the numbers of the four hymns chosen for the service. There are 800 hymns in the hymn book in use. The numbers are shown by slipping rectangular cards along the four grooved ledges.

    Each card has a digit printed on each side of it, and there are no nines, inverted sixes being used instead.

    What is the smallest number of cards which must be kept in stock so that the numbers of any four different hymns can be shown on the board?

    This puzzle was originally published with no title.

    [teaser480]

     
    • Jim Randell's avatar

      Jim Randell 8:09 am on 23 May 2019 Permalink | Reply

      (A similar puzzle is given in H E Dudeney’s 1917 book Amusements In Mathematics [ link ]. See: Puzzle 426: The Hymn-Board Poser).

      I assumed the hymns are numbered from 1 to 800.

      I think it is easier to work out the digits required on the back of an envelope, but here is a program that does it.

      It examines the hymn numbers, and finds sequences of 4 hymns that use a maximal number of copies of each card, and then totals the numbers for each type of card. It runs in 80ms.

      from enigma import (defaultdict, irange, arg, printf)
      
      # maximum hymn number (N), and number of hymns on the board (K)
      N = arg(800, 0, int)
      K = arg(4, 1, int)
      printf("[N={N} K={K}]")
      
      # record maximum numbers
      m = defaultdict(lambda: defaultdict(list))
      
      # consider hymn numbers
      for n in irange(1, N):
        # displayed as cards with '9' replaced by '6'
        s = str(n).replace('9', '6')
        # record the hymn numbers by the number of each digit required
        for d in set(s):
          m[d][s.count(d)].append(n)
      
      # count maximum numbers of each digit for 4 hymns
      T = 0
      for d in '012345678':
        # collect K numbers with a maximal count
        ks = sorted(m[d].keys())
        ns = list()
        t = 0
        while True:
          n = K - len(ns)
          if n == 0: break
          k = ks.pop()
          xs = m[d][k][:n]
          t += k * len(xs)
          ns.extend(xs)
        printf("digit {d} -> {ns}; requires {t} copies")
        T += t
      
      printf("total copies = {T}")
      

      The minimum number of digits required is 82, and we put 2 digits on each card, so…

      Solution: The minimum number of cards required is 41.

      Examples of maximal sequences for each digit are:

      digit 0 → [100, 200, 300, 400]; requires 8 copies
      digit 1 → [111, 101, 110, 112]; requires 9 copies
      digit 2 → [222, 122, 202, 212]; requires 9 copies
      digit 3 → [333, 133, 233, 313]; requires 9 copies
      digit 4 → [444, 144, 244, 344]; requires 9 copies
      digit 5 → [555, 155, 255, 355]; requires 9 copies
      digit 6 → [666, 669, 696, 699]; requires 12 copies
      digit 7 → [777, 177, 277, 377]; requires 9 copies
      digit 8 → [188, 288, 388, 488]; requires 8 copies

      There is no point making a card with the same digit on both sides, so we can make C(9, 2) = 36 cards corresponding to all pairs of different digits. This uses each digit 8 times, so leaves us with: 1, 2, 3, 4, 5, 6, 6, 6, 6, 7. And we can pair these up as: (1, 6), (2, 6), (3, 6), (4, 6), (5, 7), making a full set of pairs of different digits, and 5 duplicates.

      To show that these cards are sufficient to make all possible combinations is a bit trickier, and something I might revisit later. It might be interesting to determine the smallest number of different pairing types (along with necessary duplicates) required to make a working set.

      Like

  • Unknown's avatar

    Jim Randell 12:18 pm on 22 May 2019 Permalink | Reply
    Tags:   

    Teaser 2912: Be crafty and box clever 

    From The Sunday Times, 15th July 2018 [link] [link]

    Tyson, a crafter, had several cylindrical enclosed boxes (with heights equal to diameters) in two sizes. Each box’s surface area (including top and bottom) was a three-figure integer in square centimetres, and the larger boxes had a radius which was a whole number multiple of that of the smaller boxes.

    He kept them all in one vertical stack, to within one centimetre of the top of their metre-deep storage bin. Whilst working out fabric-cutting schemes, Tyson found that all the bigger boxes’ surface areas combined equalled all the smaller boxes’ surface areas combined and that the total surface area (in square centimetres) of all the boxes had all its numerals in ascending order.

    What was the total surface area of all the boxes, in square centimetres?

    [teaser2912]

     
    • Jim Randell's avatar

      Jim Randell 12:19 pm on 22 May 2019 Permalink | Reply

      The surface areas of the two different types of cylinders are both 3 figure integers. And the larger cylinder is a scaled up version of the smaller cylinder by a whole number. The smallest possible scaling factor is 2, which would make the surface area of the larger cylinder 4 times the surface area of the smaller cylinder. So the surface area of the smaller cylinder (a) cannot be more than 249.

      This Python program starts by considering possible values for a and then scaling up this value (by a factor of ) to give A the surface area of the larger cylinder.

      It then consider possible values for N, the number of larger cylinders, and corresponding value for n, the number of smaller cylinders, until it finds suitable numbers that when stacked are between 99 and 100 cm high.

      It runs in 73ms.

      Run: [ @repl.it ]

      from enigma import (irange, inf, pi, sqrt, nsplit, tuples, printf)
      
      # check for (strictly) increasing digits
      is_increasing = lambda n: all(x < y for (x, y) in tuples(nsplit(n), 2))
      
      # 3.pi/2
      c = 1.5 * pi
      
      # consider the smaller surface area (a)
      for a in irange(100, 249):
        # the smaller diameter is...
        d = sqrt(a, c)
      
        # suppose larger radius is k.r
        # the larger surface area A = k^2.a
        for k in irange(2, inf):
          A = k * k * a
          if A > 999: break
          D = k * d
      
          # consider number of larger cylinders (N)
          for N in irange(1, inf):
            # the number of small cylinders...
            n = k * k * N
            # remaining space
            r = 100.0 - (N * D + n * d)
            if r < 0.0: break
            if not (r < 1.0): continue
      
            # total surface area of all cylinders, has increasing digits
            T = 2 * n * a
            if not is_increasing(T): continue
      
            printf("a={a} d={d}")
            printf("  k={k} A={A} D={D}")
            printf("    N={N} n={n} r={r}, T={T}")
      

      Solution: The total surface area of the boxes is 3456 square centimetres.

      The smaller cylinders have a surface area of 144cm², with a corresponding diameter of about 5.53cm, and there are 12 of them, making a height of about 66.33cm.

      The larger cylinders are scaled up by a factor of 2 (the scaling factor can only be 2 or 3), so have a surface area of 576cm², and a diameter of about 11.06cm. There are 3 of them, which stack to a height of 33.17cm.

      The total stacked height of the 15 cylinders is about 99.50cm.

      The total surface area of the 15 cylinders is 3456cm².

      Like

  • Unknown's avatar

    Jim Randell 4:50 pm on 16 May 2019 Permalink | Reply
    Tags:   

    Teaser 2956: A nice little earner 

    From The Sunday Times, 19th May 2019 [link] [link]

    The “value” of a number is found by subtracting its first digit from the last. For example, 6, 72, 88 and 164 have values 0, −5, 0 and 3 respectively.

    Raising funds for a local charity, I placed some raffle tickets numbered from 1 up to a certain 3-digit number, in a box. Participants then selected a ticket at random. If the value of their number was positive, they won that amount in £; if the value was negative, they contributed that [positive] amount in £. Otherwise no money changed hands.

    All the tickets having been used, the total amount raised in £ was a rearrangement of the digits in that number of tickets.

    How much was raised?

    [teaser2956]

     
    • Jim Randell's avatar

      Jim Randell 4:51 pm on 16 May 2019 Permalink | Reply

      If the “value” is positive, we have to pay the ticket holder that amount. If it is negative, the ticket holder pays us. And if the value is zero nothing happens.

      So in each case we lose an amount equal to the “value” of the ticket.

      This Python program subtracts the values of the tickets, until we have a positive amount that can be rearranged to give the ticket number.

      Run: [ @repl.it ]

      from enigma import (irange, nsplit, printf)
      
      # total amount raised
      t = 0
      
      # consider ticket numbers (up to a max 3-digit value)
      for n in irange(1, 999):
        # split the number into digits
        ds = nsplit(n)
        # calculate the "value" of the number
        v = ds[-1] - ds[0]
        t -= v
        # solution when the total raised has the digits of n
        if t > 0 and n > 99 and sorted(nsplit(t)) == sorted(ds):
          printf("n={n} t={t}")
      

      Solution: £249 was raised.

      The number of tickets is 942.

      The next solution occurs with 91,727 tickets, and £12,779 raised.

      Like

  • Unknown's avatar

    Jim Randell 5:20 pm on 11 May 2019 Permalink | Reply
    Tags:   

    Teaser 2913: Return tickets 

    From The Sunday Times, 22nd July 2018 [link] [link]

    In our tombola the tickets were numbered consecutively from 1 upwards and were printed in books of 20. A local airline donated the prizes – a number of tickets to Paris and back. We decided to split the prizes into single-journey tickets and award them in an unusual way. If any ticket number had all different digits which were in increasing order then it won an outward flight to Paris: if it had all different digits which were in decreasing order then it won a flight back from Paris. So, for example, number 145 won an outward flight, number 30 won a flight back, and single-figure numbers were lucky enough to win tickets there and back. Luckily we had exactly the right number of tickets for all the prizes to be awarded.

    How many tickets did we print?

    [teaser2913]

     
    • Jim Randell's avatar

      Jim Randell 5:21 pm on 11 May 2019 Permalink | Reply

      I originally wrote a program that just considers increasing ticket numbers until it finds a solution, but the Python program below finds all possible answers for a specified number of tickets per book (which can be given as a command line argument).

      It does this by collecting increasing and decreasing numbers, and then considering them in order. It runs in 87ms.

      Run: [ @replit ]

      from enigma import (subsets, irange, nconcat, arg, printf)
      
      # k tickets per book
      k = arg(20, 0, int)
      printf("[{k} tickets per book]")
      
      # collect increasing and decreasing numbers (actually, we only need max_size=4)
      incs = set(nconcat(s) for s in subsets(irange(0, 9), min_size=1, max_size=9) if s[0] != 0)
      decs = set(nconcat(s) for s in subsets(irange(9, 0, step=-1), min_size=1, max_size=9) if s != (0,))
      
      # find when the increasing and decreasing totals are the same
      ninc = ndec = 0
      s = None
      for t in sorted(incs.union(decs)):
        if t in incs: ninc += 1
        if t in decs: ndec += 1
        if s:
          (t0, n) = s
          t1 = t - 1
          # look for answers in the range [t0..t1]
          ans = list(x for x in irange(t0, t1) if x % k == 0)
          printf("tickets = 1 - {t0}..{t1} [incs = decs = {n}] ans={ans}", t1=t - 1)
          s = None
        if ninc == ndec:
          s = (t, ninc)
      

      Solution: 1480 tickets were printed.

      It turns out there are no solutions larger than 8519, so a basic search of ticket numbers can stop there (and give a program that finds all possible solutions), and so the code above need only consider numbers of up to 4-digits.

      8519 is divisible by 7 and 1217. With 7 tickets per books have solutions with 7, 1484, 8512, 8519 tickets. With 1217 tickets per book the only solution is 8519 tickets.

      Like

  • Unknown's avatar

    Jim Randell 5:03 pm on 9 May 2019 Permalink | Reply
    Tags:   

    Teaser 2955: Go forth and multiply 

    From The Sunday Times, 12th May 2019 [link] [link]

    Adam and Eve have convex hexagonal gardens whose twelve sides are all the same whole number length in yards. Both gardens have at least two right-angled corners and the maximum possible area this allows. Each garden has a path from corner to corner down an axis of symmetry. Adam multiplies the sum of the path lengths by the difference of the path lengths (both in yards) and Eve squares Adam’s answer, getting a perfect fifth power with no repeated digit.

    What was Eve’s answer?

    See also: Teaser 2946.

    [teaser2955]

     
    • Jim Randell's avatar

      Jim Randell 5:28 pm on 9 May 2019 Permalink | Reply

      Once you’ve worked out the shapes involved, you find that Eve’s answer is 8x^4, and a simple program (or a simple guess) lets us find the appropriate answer.

      Run: [ @repl.it ]

      from enigma import (irange, inf, is_duplicate, is_power, printf)
       
      # consider the length of the side
      for x in irange(1, inf):
        E = 8 * x**4
        if E > 9876543210: break
        if is_duplicate(E): continue
        if not is_power(E, 5): continue
        printf("E={E} [x={x}]")
      

      Solution: Eve’s answer was 32768.

      Like

      • Jim Randell's avatar

        Jim Randell 9:08 am on 12 May 2019 Permalink | Reply

        Here’s the analysis to work out the formula for Eve’s answer:

        If we consider a hexagon (with sides of unit length) that has a right angle at a given vertex, then we can’t have another right angle at an adjacent vertex, as it becomes impossible to construct a convex hexagon if we do.

        So, we need only consider a pair of right angles separated by 1 or 2 intermediate vertices.

        Taking the case with 2 intermediate vertices we get a hexagon that looks like this:

        The length of the diagonal being (1 + √2).

        In the case with only 1 intermediate vertex we get a hexagon that looks like this:

        If the angle XYZ is θ, then the area of the triangle XYZ is given by:

        area(XYZ) = ((√2)/2)sin(θ)

        which is at a maximum when sin(θ) = 1, i.e. θ = 90°.

        And the length of the diagonal d = √3.

        So, for hexagons with side x, the two diagonals have lengths:

        (1 + √2)x
        (√3)x

        Adam’s value (the sum multiplied by the difference) is:

        A = (1 + √2 + √3)x(1 + √2 − √3)x
        A = 2(√2)x²

        And Eve’s value is the square of this:

        E = 8x⁴

        And we are told E is an exact power of 5.

        Choosing x = 8 gives E = 8⁵ = 32768, which has five different digits as required.

        Like

        • Jim Randell's avatar

          Jim Randell 10:46 pm on 12 May 2019 Permalink | Reply

          For completeness:

          The general case of the first hexagon (with right angles separated by two vertices) is a shape like this:

          The red line bisects the hexagon into two identical shapes (by rotation), but in general is not a line of reflective symmetry.

          Again the area of the triangle XYZ is given by the formula:

          area(XYZ) = ((√2)/2)sin(θ)

          and so the maximum area is achieved when sin(θ) = 1, i.e. θ = 90°.

          Which gives us the diagram originally presented (where the red line is a line of reflective symmetry).

          So both gardens have the same area, being composed of two (1, 1, √2) triangles and two (1, √2, √3) triangles. Giving a total area of (1 + √2).

          Like

  • Unknown's avatar

    Jim Randell 12:43 pm on 9 May 2019 Permalink | Reply
    Tags: by: John Walker   

    Brainteaser 1568: Back to the future 

    From The Sunday Times, 27th September 1992 [link]

    Many dates, such as my birthday 27th September 1972, are palindromic when written down in the form day/month/year without breaks, my birthday being 2791972.

    What about palindromic dates in the millennium beginning on 1st January 2000?

    (a) How many palindromic dates will there be in this millennium?

    (b) Of these, which two are closest together?

    The text above is taken from the book Brainteasers (2002), and is different from the originally published puzzle, which is reproduced below:

    With another palindromic date occurring on Tuesday (29.9.1992) I am reminded of a Teaser I set last year in which readers were asked to find the longest sequence of consecutive non-palindromic dates in the next 200 years. Here’s another idea:

    Assuming the standard numerical format of a date as day.month.year with the year as a four-figure number and with no zeros to start the day or month, find the two palindromic dates in the future which are closest together.

    [teaser1568]

     
    • Jim Randell's avatar

      Jim Randell 12:44 pm on 9 May 2019 Permalink | Reply

      This Python program considers dates from 1-1-2000 to 31-12-2999. It runs in 780ms.

      Run: [ @replit ]

      from datetime import (date, timedelta)
      from enigma import (repeat, inc, concat, tuples, Accumulator, printf)
      
      # record palindromic dates from 2000 - 2999
      ds = list()
      for d in repeat(inc(timedelta(days=1)), date(2000, 1, 1)):
        if not (d.year < 3000): break
        s = concat(d.day, d.month, d.year)
        if s == s[::-1]:
          ds.append(d)
      printf("[{n} palindromic dates]", n=len(ds))
      
      # find the two dates closest together
      r = Accumulator(fn=min)
      r.accumulate_data_from((b - a, (a, b)) for (a, b) in tuples(ds, 2))
      
      # output solution
      (t, (a, b)) = (r.value, r.data)
      printf("{a.day}-{a.month}-{a.year} -> {b.day}-{b.month}-{b.year} ({t.days} days)")
      

      Solution: (a) There are 323 palindromic dates. (b) The closest pair is: 23-2-2232 and 2-3-2232 (8 days apart).

      Pleasingly the number of palindromic dates is itself a palindrome.

      If we extend the date range to the year 9999 there are 2107 more palindromic dates (assuming the calendar remains the same). And the closest two are:

      29-8-8892 and 2-9-8892 (4 days apart)

      And if we extend the current calendar backwards to year 1 we can manage even better:

      31-10-113 and 3-11-113 (3 days apart)

      Like

    • Lise Andreasen's avatar

      Lise Andreasen 12:20 am on 8 May 2024 Permalink | Reply

      Does your algorithm count 1112111 (to give an example) as one or 2 dates? 1/11/2111 and 11/1/2111.

      Like

      • Lise Andreasen's avatar

        Lise Andreasen 12:30 am on 8 May 2024 Permalink | Reply

        Oh, never mind. Figured it out.

        Like

    • Lise Andreasen's avatar

      Lise Andreasen 12:34 am on 8 May 2024 Permalink | Reply

      It’s possible to count the variations.
      There are 81 dates of the form a/b/22ba.
      There are 27 dates of the form a/bc/2cba.
      There are 192 dates of the form ab/c/2cba.
      There are 22 dates of the form ab/12/21ba.

      Neat algorithm though. 👍🏻

      Like

      • Jim Randell's avatar

        Jim Randell 10:26 am on 8 May 2024 Permalink | Reply

        I don’t know if it is a typo, but these numbers don’t add up to 323.

        I found there should 193 dates of the form ab/c/2cba. (Or maybe you forgot: 29/2/2292).

        Like

        • Lise Andreasen's avatar

          Lise Andreasen 12:53 pm on 8 May 2024 Permalink | Reply

          It was a typo. And it’s probably also a remnant of me getting that leap year date wrong the first time through.

          Like

  • Unknown's avatar

    Jim Randell 11:22 am on 8 May 2019 Permalink | Reply
    Tags:   

    Teaser 2914: Bank statement 

    From The Sunday Times, 29th July 2018 [link] [link]

    My last bank statement was most interesting. The first line showed the opening balance in pounds and pence, then each of the following four lines showed a debit together with the resulting balance. I did not go overdrawn.

    Remarkably, each of the five balances used the same five different digits once only, and the largest of the digits was less than three times the smallest. Each of the four debits also used five different digits once only, but the digits in the debits were all different from those in the balances.

    What was the final balance?

    [teaser2914]

     
    • Jim Randell's avatar

      Jim Randell 11:23 am on 8 May 2019 Permalink | Reply

      This Python 3 program runs in 415ms.

      Run: [ @repl.it ]

      from itertools import (combinations, permutations)
      from collections import defaultdict
      from enigma import (irange, nconcat, nsplit, join, sprintf as f)
      
      digits = irange(0, 9)
      
      # from transactions <ts> and balance <b> find <k> transactions
      def solve(ts, b, k, s=[]):
        if k == 0:
          yield s
        elif b in ts:
          for (d, a) in ts[b]:
            yield from solve(ts, a, k - 1, s + [(b, d, a)])
      
      # choose 5 different digits for the balance
      for ds in combinations(digits, 5):
      
        # the largest is less than 3x the smallest
        if not (ds[-1] < 3 * ds[0]): continue
      
        # make all possible numbers from the digits
        ns = sorted(nconcat(s) for s in permutations(ds) if s[0] != 0)
      
        # find transactions that make viable debits
        ts = defaultdict(list)
        for (a, b) in combinations(ns, 2):
          d = b - a
          xs = set(nsplit(d))
          if len(xs) == 5 and xs.isdisjoint(ds):
            ts[b].append((d, a))
      
        # find a sequence of 4 transactions
        for b in ts.keys():
          for s in solve(ts, b, 4):
            print(f("final = {f} [{s}]", s=join((f("{b} - {d} = {a}") for (b, d, a) in s), sep=", "), f=s[-1][2]))
      

      Solution: The final balance was £ 347.58.

      There are two possibilities for the initial amount and the first debit amount, which give the same value for the balance:

      (1) 853.47 – 109.62 = 743.85; or:
      (1) 873.45 – 129.60 = 743.85

      After that the next three debits are:

      (2) 743.85 – 169.02 = 574.83
      (3) 574.83 – 120.96 = 453.87
      (4) 453.87 – 106.29 = 347.58

      The condition that “the largest of the digits was less than three times the smallest” reduces the search space, but there are no further solutions without this condition.

      Like

    • GeoffR's avatar

      GeoffR 10:28 am on 9 May 2019 Permalink | Reply

      A brute force approach in MiniZinc uses 45 integer variables and sets to solve this teaser.

      % A Solution in MiniZinc 
      include "globals.mzn"; 
      
      % Balance/Debit Sums - uses 5-digit integers for £ and pence parts
      % ABCDE - abcde == FGHIJ;
      % FGHIJ - fghij == KLMNO;
      % KLMNO - klmno == PQRST;
      % PQRST - pqrst == UVWXY;
      
      % Balances integers
      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;
      var 0..9: K; var 0..9: L; var 0..9: M; var 0..9: N; var 0..9: O;
      var 0..9: P; var 0..9: Q; var 0..9: R; var 0..9: S; var 0..9: T;
      var 0..9: U; var 0..9: V; var 0..9: W; var 0..9: X; var 0..9: Y;
      
      constraint A != 0 /\ F != 0 /\ K != 0 /\ P != 0 /\ U != 0;
      
      % max balance digit < 3 * min digit for the five balances  
      constraint max([A,B,C,D,E]) < 3 * min([A,B,C,D,E]);
      constraint max([F,G,H,I,J]) < 3 * min([F,G,H,I,J]);
      constraint max([K,L,M,N,O]) < 3 * min([K,L,M,N,O]);
      constraint max([P,Q,R,S,T]) < 3 * min([P,Q,R,S,T]);
      constraint max([U,V,W,X,Y]) < 3 * min([U,V,W,X,Y]);
      
      % Balances - sets of integers
      var set of int: s1 = { A,B,C,D,E };
      var set of int: s2 = { F,G,H,I,J };
      var set of int: s3 = { K,L,M,N,O };
      var set of int: s4 = { P,Q,R,S,T };
      var set of int: s5 = { U,V,W,X,Y };
      
      % Sets s1 to s5 have the same integers
      constraint card (s1 intersect s2 ) == 5;
      constraint card (s1 intersect s3 ) == 5;
      constraint card (s1 intersect s4 ) == 5;
      constraint card (s1 intersect s5 ) == 5;
      
      % Debits integers
      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;
      var 0..9: k; var 0..9: l; var 0..9: m; var 0..9: n; var 0..9: o;
      var 0..9: p; var 0..9: q; var 0..9: r; var 0..9: s; var 0..9: t;
      
      constraint a != 0 /\ f != 0 /\ k != 0 /\ p != 0;
      
      % Debits - sets of integers
      var set of int: s6 = { a,b,c,d,e };
      var set of int: s7 = { f,g,h,i,j };
      var set of int: s8 = { k,l,m,n,o };
      var set of int: s9 = { p,q,r,s,t };
      
      % Debit sets s6 to s9 have the same integers
      constraint card (s6 intersect s7 ) == 5;
      constraint card (s6 intersect s8 ) == 5;
      constraint card (s6 intersect s9 ) == 5;
      
      % Sets s1 and s6 have no digits in common
      constraint card(s1 intersect s6) == 0;
      
      % Form all 5-digit integers
      var 10000..99999: ABCDE = 10000*A + 1000*B + 100*C + 10*D + E;
      var 10000..99999: FGHIJ = 10000*F + 1000*G + 100*H + 10*I + J;
      var 10000..99999: KLMNO = 10000*K + 1000*L + 100*M + 10*N + O;
      var 10000..99999: PQRST = 10000*P + 1000*Q + 100*R + 10*S + T;
      var 10000..99999: UVWXY = 10000*U + 1000*V + 100*W + 10*X + Y;
      
      var 10000..99999: abcde = 10000*a + 1000*b + 100*c + 10*d + e;
      var 10000..99999: fghij = 10000*f + 1000*g + 100*h + 10*i + j;
      var 10000..99999: klmno = 10000*k + 1000*l + 100*m + 10*n + o;
      var 10000..99999: pqrst = 10000*p + 1000*q + 100*r + 10*s + t;
      
      % Balance/Debit sums in sequence
      constraint ABCDE - abcde == FGHIJ;
      constraint FGHIJ - fghij == KLMNO;
      constraint KLMNO - klmno == PQRST;
      constraint PQRST - pqrst == UVWXY;
      
      solve satisfy;
      
      output ["Final Balance = " ++ "£"++ show(U),show(V),show(W) ++ "." 
      ++ show(X),show(Y) ] 
      ++ ["\n" ++ show(ABCDE) ++ " - " ++ show(abcde)  ++ " = " ++ show(FGHIJ) ]
      ++ ["\n" ++ show(FGHIJ) ++ " - " ++ show(fghij)  ++ " = " ++ show(KLMNO) ]
      ++ ["\n" ++ show(KLMNO) ++ " - " ++ show(klmno)  ++ " = " ++ show(PQRST) ]
      ++ ["\n" ++ show(PQRST) ++ " - " ++ show(pqrst)  ++ " = " ++ show(UVWXY) ];
      
      % Final Balance = £347.58
      % 85347 - 10962 = 74385 - five digit integer format for £/pence sums
      % 74385 - 16902 = 57483
      % 57483 - 12096 = 45387
      % 45387 - 10629 = 34758
      % % time elapsed: 0.27 s
      % ----------
      % Final Balance = £347.58
      % 87345 - 12960 = 74385
      % 74385 - 16902 = 57483
      % 57483 - 12096 = 45387
      % 45387 - 10629 = 34758
      % % time elapsed: 0.27 s
      % ----------
      % ==========
      % Finished in 666msec
      
      

      Like

  • Unknown's avatar

    Jim Randell 12:58 pm on 7 May 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 479: [Sixpences] 

    From The Sunday Times, 2nd August 1970 [link]

    My nephew Anselm collects good old-fashioned sixpences in a good old-fashioned piggy bank. These he recently extracted to audit and, while experimenting by putting them into two or more equal piles of two or more coins, found that there were exactly six different ways in which this could be done.

    From one of these combinations he returned one pile to the bank, and found that the balance could again be distributed into equal piles in exactly six different ways. On this second occasion he returned two equal piles from one of the combinations to the bank, and again found that the balance could be distributed into equal piles in six different ways only. He conducted this experiment a total of seven times, on the third occasion returning three piles, on the fourth four piles and so on, and after the seventh found that he had 24 sixpences remaining.

    On none of these occasions did he deposit as much as 25s. in the bank. His third deposit was twice as much as his sixth, and three times as much as his second. His fifth deposit was five times as large as his first.

    How many sixpences had he saved up?

    I have modified the wording slightly to clarify the puzzle.

    This puzzle was originally published with no title.

    [teaser479]

     
    • Jim Randell's avatar

      Jim Randell 12:59 pm on 7 May 2019 Permalink | Reply

      I assumed that making one pile with all the coins in does not count (as there are no solutions if it does count as one of the six configurations).

      1s = 12d, so at no point does Anselm deposit more than 52 coins. So he cannot start with more than (24 + 7×52 = 388) coins. This gives us a bounded solution space to search in, but it is more interesting to run the process backwards starting with the 24 final coins.

      This Python 3 program works backwards recursively to solve the problem. It runs in 79ms.

      from enigma import (divisors, div, printf)
      
      # possible pile sizes for n coins
      piles = lambda n: list(p for p in divisors(n) if 1 < p < n)
      
      # work backwards from <n> coins and <i> piles deposited to 1 pile deposited
      # i = number of piles deposited
      # n = number of coins
      # ps = possible pile sizes
      # return [(<n coins>, <n piles>), ...]
      def solve(n, i, ps, ss=[]):
        if i == 0:
          yield ss
        else:
          # consider the number of coins in each pile
          for k in ps:
            # i equally sized piles were deposited in the bank
            d = i * k
            # but not more than 52 coins
            if d > 52: break
            # the total number of coins before the deposit
            t = n + d
            # and t must have 6 possible piles numbers
            ds = piles(t)
            if not (len(ds) == 6): continue
            yield from solve(t, i - 1, ds, [(t, k)] + ss)
      
      # we end up with 24 coins
      N = 24
      for ss in solve(N, 7, piles(N) + [N]):
      
        # calculate the numbers of coins returned to the bank at each stage
        ds = list(i * k for (i, (_, k)) in enumerate(ss, start=1))
        # 3rd deposit was twice the 6th and 3 times the 2nd
        if not (ds[2] == 2 * ds[5] == 3 * ds[1]): continue
        # 5th deposit was 5 times the 1st
        if not (ds[4] == 5 * ds[0]): continue
      
        # output solution
        for (i, ((t, k), d)) in enumerate(zip(ss, ds), start=1):
          printf("{i}: {t} coins in {p} piles of {k}; deposit {i} piles = {d} coins", p=div(t, k))
        printf("started with {n} coins; finished with {N} coins", n=ss[0][0])
        printf()
      

      Solution: Anselm has 138 sixpences.

      Liked by 1 person

  • Unknown's avatar

    Jim Randell 4:41 pm on 6 May 2019 Permalink | Reply
    Tags:   

    Teaser 2915: £sd 

    From The Sunday Times, 5th August 2018 [link] [link]

    50 years ago, the coins in circulation were the halfpenny (1/2d), penny (1d), threepenny bit (3d), sixpence (6d), shilling (12d), florin (2 shillings) and half crown (2 shillings and sixpence).

    One day, having at least one of each of the above coins, I decided to bank them.

    The cashier set out the coins in separate piles, checked them (discovering that the number of coins in each pile was a square), and gave me exactly a 10-shilling note in exchange.

    If I told you how many different numbers of coins were in those piles, you should be able to work out the numbers of each coin.

    In the order half crown down to halfpenny, how many coins of each type were there?

    [teaser2915]

     
    • Jim Randell's avatar

      Jim Randell 4:42 pm on 6 May 2019 Permalink | Reply

      We know there is at least one of each denomination of coin. So that is 1/2 + 1 + 3 + 6 + 12 + 24 + 30 = 76.5d accounted for, leaving us only 43.5d to worry about, and we need to make this amount from quantities that are 1 less than a perfect square.

      It turns out there are 6 different ways to achieve this. Five of them use 3 different quantities, the sixth way uses 4 different quantities, and gives us the solution.

      This Python 3 program runs in 73ms.

      Run: [ @repl.it ]

      from enigma import (defaultdict, isqrt, irange, arg, printf)
      
      # express total <t> using denominations <ds>, quantities <qs>
      def express(t, ds, qs, s=[]):
        if t == 0:
          if not ds:
            yield s
          elif 0 in qs:
            yield s + [0] * len(ds)
        elif ds:
          d = ds[0]
          for i in qs:
            if d * i > t: break
            yield from express(t - d * i, ds[1:], qs, s + [i])
      
      # denominations of coins (in half-pennies)
      coins = (1, 2, 6, 12, 24, 48, 60)
      
      # total amount (of half-pennies)
      T = arg(240, 0, (lambda x: int(2 * float(x))))
      printf("[T={T}(1/2)d]")
      
      # subtract one of each coin from the total
      t = T - sum(coins)
      
      # squares - 1 (up to t)
      squares1 = list(i * i - 1 for i in irange(1, isqrt(t)))
      
      # collect results by how many different quantities there are
      r = defaultdict(list)
      
      # consider ways to express t using (i^2 - 1) quantities
      for qs in express(t, coins, squares1):
        # record result by the numbers of different quantities
        k = len(set(qs))
        printf("[{qs} -> {k} values]")
        r[k].append(qs)
      
      # look for keys with unique values
      for (k, vs) in r.items():
        if len(vs) == 1:
          # include the first coin of each denomination
          qs = list(n + 1 for n in vs[0])
          # output quantities and denominations (in half-pennies)
          printf("{k} values -> {T}(d/2) = {qs} x {coins}(d/2)")
      

      Solution: The numbers of coins in the piles (from half-crowns down to half-pennies) are: 1, 1, 1, 4, 1, 9, 36.

      Like

      • Frits's avatar

        Frits 3:36 pm on 5 June 2024 Permalink | Reply

        “The cashier set out the coins in separate piles”.

        I understand you have assumed that the cashier made 7 piles per denomination. I would also have considered fi 4four piles (with 4, 4, 36 and 196 coins).

        Like

        • Jim Randell's avatar

          Jim Randell 5:02 pm on 5 June 2024 Permalink | Reply

          @Frits: My natural interpretation was that each denomination is in a separate pile, so there is (exactly) one pile per denomination.

          Like

    • GeoffR's avatar

      GeoffR 9:26 pm on 6 May 2019 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
      
      % HP = No. HalfPennies, P3 = No. Threepence, P6 = No. Sixpence....
      var 1..150:HP; var 1..100:P; var 1..40:P3; var 1..20:P6;     
      var 1..10:SH; var 1..5:FL; var 1..4:HC; 
      
      % even number of half-pennies needed to make 120p
      constraint HP mod 2 == 0;  
      
      % the number of coins in each pile was a square
      set of int: sq = {1, 4, 9, 16, 25, 36, 49, 64, 81, 100};
      
      % all types of coins are squares
      constraint HP in sq /\ P in sq /\ P3 in sq /\ P6 in sq
      /\ SH in sq /\ FL in sq /\ HC in sq;
      
      % number of coins/types to make 120p 
      constraint HP * 1 div 2 + P*1 + P3*3  + P6*6 + SH*12 
      + FL*24 + HC*30 == 120;
      
      var set of int: coins = {HP, P, P3, P6, SH, FL, HC};
      
      solve satisfy;
      output [ show([HP,P,P3,P6,SH,FL,HC]) ++ "  " ++ show(coins) ];
      
      % [HP, P, P3,P6,SH,FL,HC] Set of Coins
      % ------------------------------------ 
      % [64, 4, 4, 1, 1, 1, 1]  {1,4,64}
      % [4, 25, 1, 4, 1, 1, 1]  {1,4,25}
      % [4, 16, 4, 4, 1, 1, 1]  {1,4,16}
      % [4, 1, 9, 4, 1, 1, 1]  {1,4,9}
      % [36, 9, 1, 4, 1, 1, 1]  {1,4,9,36} << only set of 4 coin types
      % [16, 1, 1, 1, 4, 1, 1]  {1,4,16}
      % ==========
      % Answer: 1 Half Crown, 1 Florin, 1 Shilling, 4 Sixpence
      % 1 Threepence, 9 Pennies and 36 HalfPennies
      
      
      

      Like

c
Compose new post
j
Next post/Next comment
k
Previous post/Previous comment
r
Reply
e
Edit
o
Show/Hide comments
t
Go to top
l
Go to login
h
Show/Hide help
shift + esc
Cancel
Design a site like this with WordPress.com
Get started