Updates from Jim Randell Toggle Comment Threads | Keyboard Shortcuts

  • 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

  • Unknown's avatar

    Jim Randell 1:37 pm on 5 May 2019 Permalink | Reply
    Tags:   

    Teaser 2916: Pointless batting averages 

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

    When my son was chosen to play cricket for his School First XI, I kept a record of the number of runs he scored in each of his first five innings. After each innings I calculated his batting average (the total number of runs scored so far divided by the number of innings) and found an interesting pattern:

    (i) Each score was under 30
    (ii) They [the scores] were all different
    (iii) Each of the five averages was a whole number

    When he asked me how he could maintain this pattern with his sixth innings, I was able to tell him the smallest score that would achieve this.

    What is the largest number this could have been?

    [teaser2916]

     
    • Jim Randell's avatar

      Jim Randell 1:37 pm on 5 May 2019 Permalink | Reply

      If the scores in the first five innings are (a, b, c, d, e) and there are scores for the sixth innings f, (between 0 and 29), that continue the pattern. And there will be a smallest such value:

      (a, b, c, d, e, f) → f_min

      So, we can look at all possible (a, b, c, d, e, f) values and find the largest possible f_min value.

      This Python program runs in 569ms.

      Run: [ @repl.it ]

      from enigma import (irange, Accumulator, printf)
      
      # possible next scores
      def scores(ss, avgs):
        t = sum(ss)
        n = len(ss) + 1
        for s in irange(-t % n, 29, step=n):
          if s not in ss:
            yield (ss + [s], avgs + [(t + s) // n])
      
      # find sequences of length k
      def solve(ss=[], avgs=[], k=5):
        if len(ss) == k:
          yield (ss, avgs)
        else:
          for (ss1, avgs1) in scores(ss, avgs):
            yield from solve(ss1, avgs1, k)
      
      # find the largest of the smallest values
      r = Accumulator(fn=max)
      
      for (ss, avgs) in solve():
        # find the smallest score to maintain this
        for (ss1, avgs1) in scores(ss, avgs):
          s = ss1[-1]
          r.accumulate(s)
          if s == r.value: printf("scores={ss} (avgs={avgs}) -> score={s} (avg={avg})", avg=avgs1[-1])
          break  # we only want the smallest value
      
      # output the solution
      printf("max value = {r.value}")
      

      Solution: The largest number it could have been is 23.

      I found 142 sequences that give this largest possible f_min value, although only 15 of these also have the averages take on 5 different values.

      One possible sequence is:

      (5, 11, 17, 27, 25)

      which give the corresponding averages of:

      (5, 8, 11, 15, 17)

      A score in the sixth innings of 23, would give an average of 18 over the six innings.

      Like

  • Unknown's avatar

    Jim Randell 2:13 pm on 4 May 2019 Permalink | Reply
    Tags: by: S G Worthington   

    Brain-Teaser 478: [Alphametic family] 

    From The Sunday Times, 26th July 1970 [link]

    Brian and Betty have a daughter, Moira, and this can be proved by addition where each letter is represented by a different digit:

    BRIAN + BETTY = MOIRA

    The sum of the individual digit values of MOIRA gives her age. The age of her brother ROBERT is similarly obtained. The sum of the children’s ages is a perfect square.

    How old is Robert?

    This puzzle was originally published with no title.

    [teaser478]

     
    • Jim Randell's avatar

      Jim Randell 2:14 pm on 4 May 2019 Permalink | Reply

      Once we have the solved the alphametic sum the value of ROBERT is determined.

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

      The following run file executes in 703ms. (Internal runtime of the generated program is 490ms).

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      "BRIAN + BETTY = MOIRA"
      
      "is_square(sum([M, O, I, R, A, R, O, B, E, R, T]))"
      
      --answer="sum([R, O, B, E, R, T])"
      

      But it is faster to write a short program that uses the [[ SubstitutedSum() ]] solver.

      This Python program runs in 79ms. (Internal runtime is 7.0ms).

      from enigma import (SubstitutedSum, is_square, printf)
      
      # make the alphametic sum
      p = SubstitutedSum(['BRIAN', 'BETTY'], 'MOIRA')
      
      # solve it
      for s in p.solve():
        # compute the ages
        (m, r) = (sum(s[x] for x in w) for w in ('MOIRA', 'ROBERT'))
        # check they sum to a square
        if not is_square(m + r): continue
        # output solution
        printf("r = {r} [m = {m}] [{s}]", s=p.substitute(s, "BRIAN + BETTY = MOIRA"))
      

      Solution: Robert is 23.

      Moira is 26. Together the ages sum to 49 (= 7²).

      There are 2 possible sums as the values of N and Y (in the units column of the sum) are interchangeable.

      So the sum is one of:

      14836 + 15007 = 29843
      14837 + 15006 = 29843

      Like

      • Jim Randell's avatar

        Jim Randell 2:40 pm on 22 November 2024 Permalink | Reply

        Or using the [[ SubstitutedExpression.split_sum ]] solver generates a program with an internal runtime of just 1.1ms.

        #! python3 -m enigma -rr
        
        SubstitutedExpression.split_sum
        
        "BRIAN + BETTY = MOIRA"
        
        --extra="is_square(sum([M, O, I, R, A, R, O, B, E, R, T]))"
        
        --answer="sum([R, O, B, E, R, T])"
        

        Like

    • GeoffR's avatar

      GeoffR 3:10 pm on 6 May 2019 Permalink | Reply

      % A solution in MinZinc 
      include "globals.mzn";
      
      var 0..9: B; var 0..9: R; var 0..9:I; var 0..9: A; var 0..9: N;
      var 0..9: E; var 0..9: T; var 0..9:Y; var 0..9: M; var 0..9: O;
      
      constraint B > 0 /\ M > 0 /\ R > 0;
      constraint all_different ([B, R, I, A, N, E, T, Y, M, O]);
      
      var 10000..99999: BRIAN = 10000*B + 1000*R + 100*I + 10*A + N;
      var 10000..99999: BETTY = 10000*B + 1000*E + 100*T + 10*T + Y;
      var 10000..99999: MOIRA = 10000*M + 1000*O + 100*I + 10*R + A;
      
      constraint BRIAN + BETTY == MOIRA;
      
      % The sum of the children’s ages is a perfect square
      set of int: sq = {9, 16, 25, 36, 49, 64, 81, 100};
      constraint  (M + O + I + R + A + R + O + B + E + R + T) in sq;
      
      solve satisfy;
      
      % The sum of the individual digit values gives each child's age
      output [ "ROBERT = " ++ show(R+O+B+E+R+T)] ++  
      [", MOIRA = " ++ show(M+O+I+R+A) ]
      ++ ["\nSum is " ++ show(BRIAN) ++ " + " ++ show(BETTY) ++ 
      " = " ++ show(MOIRA) ] ;
      
      % ROBERT = 23, MOIRA = 26
      % Sum is 14837 + 15006 = 29843
      % % time elapsed: 0.03 s
      % ----------
      % ROBERT = 23, MOIRA = 26
      % Sum is 14836 + 15007 = 29843
      % % time elapsed: 0.03 s
      % ----------
      % ==========
      % Finished in 254msec
      
      
      

      The parents ages (22 and 13) or (23 and 12) don’t seem to make much sense in relation to the children’s ages! ie Robert (23) and Moira(26)

      Like

  • Unknown's avatar

    Jim Randell 5:41 pm on 2 May 2019 Permalink | Reply
    Tags:   

    Teaser 2954: Lovely meter, RITA made! 

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

    Revisiting the old curiosity shop, I bought an unusual moving-iron ammeter (made by Rho Iota Tau Associates). On the non-linear scale “9” was the last possible “whole amperes” scale graduation marked before the “full scale deflection” end stop (which was a half turn of the pointer from zero).

    The booklet gave the pointer swing from zero (in degrees) equal to the current (in amperes) raised to a fixed single-figure positive whole number power, then divided by a positive whole number constant. Curiously, the angle between “exact” pointer swings, calculated using this formula, for two single-figure “whole amperes” values was exactly a right angle.

    What, in amperes, were these two currents (lower first) and to what power were they raised?

    [teaser2954]

     
    • Jim Randell's avatar

      Jim Randell 5:44 pm on 2 May 2019 Permalink | Reply

      The title of the puzzle, of course, is a reference the song Lovely Rita by The Beatles.

      This Python program runs in 82ms.

      Run: [ @repl.it ]

      from enigma import (irange, subsets, div, fdiv, printf)
      
      # the deflection in degrees is d(x) = (x^n)/k
      
      # consider possible single figure powers n
      for n in irange(2, 9):
      
        # choose a and b the two single figure values
        for (a, b) in subsets(irange(0, 9), size=2):
      
          # determine the constant
          k = div(b**n - a**n, 90)
          if not k: continue
      
          # 9 amps -> deflection =< 180 degrees
          # 10 amps -> deflection > 180 degrees
          if not (9**n <= 180 * k < 10**n): continue
          
          d = lambda x: fdiv(x**n, k)
          printf("n={n}, a={a} b={b}, k={k} [a->{da:.2f} b->{db:.2f} 9->{d9:.2f} 10->{d10:.2f}]", da=d(a), db=d(b), d9=d(9), d10=d(10))
      

      Solution: The two currents are 3 A and 9 A. They are raised to the power of 8.

      So the formula for the deflection (in degrees) as a function of the current (in amps) is:

      d(x) = (x^8) / 478224

      Giving the corresponding readings for currents from 0 to 10 amps:

       0 A →   0.000°
       1 A →   0.000°
       2 A →   0.001°
       3 A →   0.014° (d = 9/656)
       4 A →   0.137°
       5 A →   0.817°
       6 A →   3.512°
       7 A →  12.055°
       8 A →  35.082°
       9 A →  90.014° (d = 90 + 9/656)
      10 A → 209.107° (d > 180)

      So if you want to read small currents you had better be good at measuring very small angles.

      There are two further solutions for single digit powers and single digit currents that give a difference of exactly 90°.

      These are:

      d(x) = (x^4) / 72; for 3A and 9A
      d(x) = (x^6) / 2912; for 2A and 8A

      But these are disallowed by the condition that 9A should be on the scale and 10A off the scale. In the first case both 9A and 10A are on the scale, in the second case they are both off the scale. But they would be solutions to similar puzzles where the scale goes to 10A (but not 11A), or 8A (but not 9A), respectively.

      Like

  • Unknown's avatar

    Jim Randell 3:04 pm on 2 May 2019 Permalink | Reply
    Tags: by: G S Green   

    Brain-Teaser 477: [Tribute of goats] 

    From The Sunday Times, 19th July 1970 [link]

    His four wives have to make tribute of goats to the Khan of Bakristan. My job is to collect the goats.

    “Kahn Sahib says each gift to be divisible by donor’s age which consists of first and third digits of her number of goats”, said Munshi. “I don’t know ages, but know the goats required from each”.

    I knew their ages. To celebrate each wife’s 31st birthday the Khan had married a teenager, so I quickly jotted down the four numbers of goats — no names because Munshi was looking over my shoulder and reading each of my four numbers from right to left, as they do in Bakristan. “Numbers correct”, he said.

    Having done things the opposite way my numbers agreed with his.

    What are the ages of the 3rd and 4th wife?

    This puzzle was originally published with no title.

    [teaser477]

     
    • Jim Randell's avatar

      Jim Randell 3:05 pm on 2 May 2019 Permalink | Reply

      If we suppose the current ages of the four wives are:

      AB > CD > EF > GH

      Then the difference in the ages of consecutive wives is a number between 12 and 18.

      And the numbers of goats must be:

      APB, CQD, ERF, GSH

      (assuming each is a three digit number), where each number is divisible by the corresponding age.

      And this set of numbers can also be read as:

      BPA, DQC, FRE, HSG

      This is enough to allow us to use the general alphametic solver [[ SubstitutedExpression() ]] from the enigma.py library to find an answer.

      The following run file executes in 188ms.

      Run: [ @replit ]

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --distinct=""
      
      # ages in order
      "AB > CD > EF > GH > 12"
      
      # number of goats is divisible by the age
      "APB % AB = 0"
      "CQD % CD = 0"
      "ERF % EF = 0"
      "GSH % GH = 0"
      
      # age difference of consecutive wives
      "11 < AB - CD < 19"
      "11 < CD - EF < 19"
      "11 < EF - GH < 19"
      
      # the set of numbers is the same in reverse
      "ordered(APB, CQD, ERF, GSH) == ordered(BPA, DQC, FRE, HSG)"
      
      # answer is the current ages of the wives
      --answer="(AB, CD, EF, GH)"
      

      Solution: The third wife is 35. The fourth wife is 17.

      When the first wife is 31, the new (second) wife was 13.

      18 years later: The first wife is 49, the second wife is now 31, and the new (third) wife is 13.

      18 years later: The first wife is 67, the second wife is 49, the third wife is now 31, and the new (fourth) wife is 13.

      4 years later (brings us to now): The first wife is 71, the second wife is 53, the third wife is 35, and the fourth wife is 17.

      The corresponding numbers of goats are: 781, 583, 385, 187 (1936 goats in total).

      Like

  • Unknown's avatar

    Jim Randell 3:40 pm on 1 May 2019 Permalink | Reply
    Tags:   

    Teaser 2917: Polygoland 

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

    We’ve all heard of Heligoland but George and Martha are on holiday in Polygoland. This is an island and when it was first inhabited, the authorities created as many national parks as possible subject to the restriction that each such park will be a regular polygon with the angle between each side being an integral number of degrees, and all the parks have different numbers of sides. Walking along the border between two such parks, Martha commented that the angle (A) of one of them was an exact multiple of the number of sides (S) in the other. George mentioned that the multiple was equal to the number of parks on the island.

    What are A and S?

    [teaser2917]

     
    • Jim Randell's avatar

      Jim Randell 3:40 pm on 1 May 2019 Permalink | Reply

      For a regular n-gon, the internal angles are (180 − 360 / n) degrees.

      So we can determine the number of possible n-gons with integer angles t from the number of divisors of 360 (greater than 2).

      There are 22 possible polygons, so t = 22

      So we need to find a solution to the equation:

      180 − 360 / n = 22m
      n = 360 / (180 − 22m)

      where n is a divisor of 360 (greater than 2).

      There are only a few values of m to consider and only one of them gives a viable value for n.

      Run: [ @repl.it ]

      from enigma import (divisors, irange, div, printf)
      
      # find divisors of 360 where n > 2
      ns = list(n for n in divisors(360) if n > 2)
      t = len(ns)
      printf("[{t} different polygons]")
      
      # now consider possible values of m
      for m in irange(1, 180 // t):
        n = div(360, 180 - t * m)
        if n is None or n == m or n not in ns: continue
        printf("A={A} degrees, S={m} [m={m} n={n}]", A=(180 - 360 // n))
      

      Solution: A = 176°, S = 8.

      The solution to the equation is m = 8, which gives a value of n = 90.

      The angle 176° is 4° off a straight line, so if we walk along the perimeter each side turns us by 4°. After 90 sides we have turned through 360°.

      176 = 22 × 8, and 8 is a divisor of 360, so there will be an octagonal park (with interior angles of 180° − 45° = 135°).

      Like

  • Unknown's avatar

    Jim Randell 8:10 am on 30 April 2019 Permalink | Reply
    Tags:   

    Brainteaser 1567: How many teams? 

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

    The teams in our local football league each play each of the others once in a season, earning three points for a win and one point for a draw. After the last Saturday of the season (when all the teams had played one game that day) I worked out the league table (with the teams in alphabetical order). I then consistently replaced digits in the table by letters, using different letters for different digits.

    Here is part of that table, showing some of the entries in three of the rows:

    What is the number of teams in the league? And what is the number TEAMS?

    This puzzle is included in the book Brainteasers (2002). The wording here is taken from the book and is only slightly changed from the original puzzle.

    [teaser1567]

     
    • Jim Randell's avatar

      Jim Randell 8:11 am on 30 April 2019 Permalink | Reply

      If there are n teams in the league, then at the end of the season each team has played all the other (n − 1) teams, and this total number of matches must be represented in the sum of the “won”, “drawn”, “lost” columns in the table.

      H + O + W = n − 1
      M + A + N = n − 1
      T + E + A = n − 1

      If each team played one match on the final Saturday, then there must be an even number of teams. And if n is even, then (n − 1) is odd.

      We are given the points in the third row:

      3T + E = S

      And we are given the “goals against” for two teams. Each “lost” game involves conceding at least one goal, so:

      NY, AM

      (and the values cannot be equal).

      Together these give us enough information to assign values to the letters.

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

      The following run file executes in 216ms.

      Run: [ @repl.it ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      # sums of "won", "drawn", "lost" are the same
      "H + O + W == M + A + N == T + E + A"
      
      # sum is odd
      "(H + O + W) % 2 = 1"
      
      # points for third row
      "3 * T + E = S"
      
      # "lost" <= "goals against"
      "N < Y"
      "A < M"
      
      # answer: (number of teams, value of TEAMS)
      --answer="(H + O + W + 1, TEAMS)"
      

      Solution: There are 12 teams in the league. TEAMS = 16459.

      The first row has “won”, “drawn”, “lost” values of 0, 3, 8, but we don’t know which order.

      The second row has 5 “won”, 4 “drawn”, 2 “lost”, and 7 “goals against”.

      The third row has 1 “won”, 6 “drawn”, 4 “lost” and 5 “goals against”, giving 9 points.

      There are 12 teams, so there are 66 matches played in total.

      Like

  • Unknown's avatar

    Jim Randell 10:47 am on 29 April 2019 Permalink | Reply
    Tags:   

    Teaser 2918: Prime multiplication 

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

    Almost everyone knows that the single digit prime numbers are 2, 3, 5, and 7, the number 1 having been excluded quite a long time ago.

    Here is a multiplication involving prime digits:

    What is the answer?

    [teaser2918]

     
    • Jim Randell's avatar

      Jim Randell 10:47 am on 29 April 2019 Permalink | Reply

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

      The following run file executes in 113ms.

      Run: [ @replit ]

      #! python -m enigma -rr
      
      #        A B C
      #    *     D E
      #    ---------
      #      F G H J
      #    K L M N
      #    ---------
      #    P Q R S T
      #    =========
      
      SubstitutedExpression
      
      # use only prime digits
      --digits="2,3,5,7"
      --distinct=""
      
      "ABC * DE = PQRST"
      "ABC * E = FGHJ"
      "ABC * D = KLMN"
      
      # required answer
      --answer="PQRST"
      

      Solution: The result of the multiplication is 25575.

      If the digit 1 were allowed, there would be a further 9 solutions (including one that does not have the digit 1 in the result).

      Like

    • GeoffR's avatar

      GeoffR 1:58 pm on 29 April 2019 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
      
      set of int: S = {2,3,5,7};    % single digit primes
      
      var S: a;  var S: b;  var S: c;  var S: d;
      var S: e;  var S: f;  var S: g;  var S: h;
      var S: i;  var S: j;  var S: k;  var S: m;
      var S: n;  var S: p;  var S: q;  var S: r;
      var S: s;  var S: t;  
      
      %      a b c
      %   x    d e
      %    -------
      %    f g h i
      %  j k m n 0
      %  ---------
      %  p q r s t
      %  ---------
      
      var 100..999: abc = 100*a + 10*b + c;
      var 10..99: de = 10*d + e;
      var 10000..99999: pqrst = 10000*p + 1000*q + 100*r + 10*s + t;
      var 1000..9999: fghi = 1000*f + 100*g + 10*h + i;
      var 10000..99999: jkmn0 = 10000*j + 1000*k + 100*m + 10*n;
      
      constraint abc * de == pqrst;
      constraint abc * d * 10 == jkmn0;
      constraint abc * e == fghi;
      
      solve satisfy;
      
      % a = 7; b = 7; c = 5; d = 3; e = 3;
      % f = 2; g = 3; h = 2; i = 5; 
      % j = 2; k = 3; m = 2; n = 5; 
      % p = 2; q = 5; r = 5; s = 7; t = 5;
      % time elapsed: 0.02 s
      %----------
      %==========
      % Sum is:
      %     775
      %   x  33
      %   ----
      %    2325
      %   23250
      %   -----
      %   25575
      %   -----
      
      

      Like

  • Unknown's avatar

    Jim Randell 8:50 am on 28 April 2019 Permalink | Reply
    Tags:   

    Teaser 2919: Letters puzzle 

    From The Sunday Times, 2nd September 2018 [link] [link]

    My best friend has a special birthday later this month, and I have composed a Teaser to celebrate the occasion.

    First of all, I wrote that date as a single number (with the day at the start, the month in the middle and the year at the end).

    Then, replacing different letters consistently with different non-zero digits, I found that the sum of LETTERS and PUZZLE gives that number.

    Find the prime value of TEASER.

    [teaser2919]

     
    • Jim Randell's avatar

      Jim Randell 8:51 am on 28 April 2019 Permalink | Reply

      The sum is of the form:

      LETTERS + PUZZLE = abc92018

      Where a, b, c allow the result to read as a valid date in September 2018 (after the date of the puzzle, which is 2nd September 2018).

      If the date is read as: ab.09.2018, we have: 3 ≤ ab ≤ 30; c = 0.

      If the date is read as: bc.9.2018, we have: a = 0; 3 ≤ bc ≤ 30.

      Note that if the result of the sum is 3092018, the birthday could be on 03.09.2018 or 30.9.2018.

      The following run file executes in 133ms. (Internal runtime of the generated code is 1.1ms).

      Run: [ @replit ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression.split_sum
      
      # upper case letters are distinct
      --distinct="AELPRSTUZ"
      
      # but non-zero
      --invalid="0,AELPRSTUZ"
      
      # digits stand for themselves
      --literal="01289"
      
      # expressions to solve
      "{LETTERS} + {PUZZLE} = {abc92018}"
      --extra="is_prime({TEASER})"
      
      # the result of the sum should read as a valid September date
      --code="valid = lambda d, f, v=0: f == v and 2 < d < 31"
      --extra="valid({ab}, {c}) or valid({bc}, {a})"
      
      # required answer
      --answer="{TEASER}"
      
      # [optional] faster prime checking
      --code="is_prime = is_prime_mr"
      

      Solution: TEASER = 314719.

      The sum is: 2133197 + 658821 = 2792018.

      And so the date is 27.9.2018 (27th September 2018).

      Like

    • Frits's avatar

      Frits 12:11 pm on 13 August 2025 Permalink | Reply

      Two calls to is_prime().

      from functools import reduce
      from enigma import is_prime
      
      # LETTERS + PUZZLE = ab92018  (as L must be even) ab < 31 or b = 0
       
      # convert digits to a number
      d2n = lambda *s: reduce(lambda x, y: 10 * x + y, s)
      
      nums = set(range(1, 10))
      
      # e < 6 as u = 6 - e 
      for e in range(1, 6):
        s = 8 - e 
        for r in nums - {e, s}:
          # TEASER is a prime number
          if r not in {1, 3, 7, 9}: continue
          # (R + L) % 10 = 1
          if not (0 < (l := 11 - r) < 10): continue
          # (E + Z + 1) % 10 = 0
          if not (0 < (z := 9 - e) < 10): continue
          # (T + Z + 1) % 10 = 2,  T = 11 - Z = 2 + E
          t = e + 2
          if not (0 < (t := 11 - z) < 10): continue
          # (T + U + 1) % 10 = 9, U = 8 - T, U = 6 - E
          u = 6 - e
          # different digits
          if len(unused := nums - {e, s, r, l, z, t, u}) != 2: continue
         
          letters = d2n(l, e, t, t, e, r, s)
          # L must be even, if L >= 3: P + E = 10, if L = 2: P + E <= 10
          for p in [u for u in unused if (u + e < 11 if l == 2 else u + e == 10)]:
            puzzle = d2n(p, u, z, z, l, e)
            for a in unused - {p}:
              if is_prime(teaser := d2n(t, e, a, s, e, r)):
                print("answer:", teaser)
      

      Like

  • Unknown's avatar

    Jim Randell 8:17 am on 27 April 2019 Permalink | Reply
    Tags: by: G F Anderson   

    Brain-Teaser 476: [Football pools] 

    From The Sunday Times, 12th July 1970 [link]

    A football pools fan suggests a novel points scoring system which, he says, is a lot of fun and so easy to do.

    For Home wins and Draws the goals for teach match are written down (Home teams first, of course), and the figures placed next to each other. This gives the points. For example, a Home team winning by 10 goals to 3 scores 103 points, a 5-5 Draw 55 points, and so on. You have to select a given number of matches, for example, eight, from the list, which the object of making the highest points score.

    I need not tell you about points for Away wins, because I did not include any among my selections when I tried out the system the other day. All my forecasts were correct. They comprised 2 Home Wins, and the remainder were all Draws. One of my Home wins was worth 2 more points than the other Home win. No match had a goals aggregate greater than 16, and the points obtained from my 2 Home wins accounted for exactly 60 per cent of the points obtained from all the matches I selected.

    How many points did I score?

    This puzzle was originally published with no title.

    [teaser476]

     
    • Jim Randell's avatar

      Jim Randell 8:18 am on 27 April 2019 Permalink | Reply

      This Python 3 program runs in 93ms.

      Run: [ @repl.it ]

      from enigma import (nsplit, nconcat, irange, subsets, div, join, printf)
      
      # points for a match with a score of <x>-<y>
      def points(x, y):
        return nconcat(nsplit(x) + nsplit(y))
      
      # possible wins
      wins = list()
      for x in irange(1, 16):
        wins.extend((x, y, points(x, y)) for y in irange(0, min(x - 1, 16 - x)))
      
      # possible draws
      draws = list((x, x, points(x, x)) for x in irange(0, 8))
      
      # find k draws that give t points
      def solve(k, t, ds=draws, s=[]):
        if k == 0:
          if t == 0:
            yield s
        else:
          for (i, (x, y, p)) in enumerate(ds):
            if not (p > t):
              yield from solve(k - 1, t - p, ds[i:], s + [(x, y)])
      
      # choose the two home wins (different)
      for ((x1, y1, p1), (x2, y2, p2)) in subsets(wins, size=2):
        if not (abs(p1 - p2) == 2): continue
      
        # p1 + p2 accounts for exactly 60% of the points
        # so, calculate the total number of points
        w = p1 + p2
        t = div(100 * w, 60)
        if t is None: continue
      
        # find 5 draws (not necessarily all different) worth the remaining 40%
        for (i, ds) in enumerate(solve(5, t - w)):
          if i == 0: printf("total {t} pts; wins = {x1}-{y1}; {x2}-{y2}")
          printf("  draws = {ds}", ds=join((join(d, sep="-") for d in ds), sep="; "))
          break # only need one example
      

      Solution: Your selection scored 440 points.

      Possible draws are 0-0, 1-1, …, 8-8, scoring 0, 11, …, 88 points respectively. So draws always score some multiple of 11 points.

      There are 16 ways to have two wins that have scores differing by 2, but only one of these gives the remaining 40% of points being a multiple of 11.

      That is: wins of 13-1 and 13-3, which have scores of 131 points and 133 points respectively.

      Together these give 264 points, which is 60% of a total of 440 points, leaving 176 points to be made up from the draws, and 176 = 16 × 11.

      There are 63 ways in which we can choose 5 draws to give a total of 176 points. For example: two 8-8 matches, and three 0-0 matches.

      Like

  • Unknown's avatar

    Jim Randell 8:01 am on 26 April 2019 Permalink | Reply
    Tags:   

    Teaser 2953: Marble tower 

    From The Sunday Times, 28th April 2019 [link] [link]

    Liam has a number of bags of marbles; each bag contains the same number (more than 1) of equal-size marbles.

    He is building a tetrahedron with the marbles, starting with a layer which fits snugly in a snooker triangle. Each subsequent triangular layer has one fewer marble along each edge. With just one bag left he had completed a whole number of layers; the number of marbles along the edge of the triangle in the last completed layer was equal to the number of completed layers. The last bag had enough marbles to just complete the next layer.

    How many bags of marbles did Liam have?

    [teaser2953]

     
    • Jim Randell's avatar

      Jim Randell 8:24 am on 26 April 2019 Permalink | Reply

      This Python program runs in 85ms.

      Run: [ @repl.it ]

      from enigma import (irange, inf, T, div, printf)
      
      # P(n) = the nth tetrahedral number
      P = lambda n: (n * (n + 1) * (n + 2)) // 6
      
      def solve():
        # suppose there are n bags, each containing k marbles
        # there are enough marbles in the final bag to complete a layer
        # so the number of marbles in a bag is a triangular number
        for x in irange(2, inf):
          k = T(x)
      
          # and there must be (x + 1) completed layers
          # and layers T(x + 1) ... T(2x + 1) have used (n - 1) k marbles
          # so: P(2x + 1) - P(x) = (n - 1) k
          # solve for (n - 1)
          n = div(P(2 * x + 1) - P(x), k)
          if n:
            yield (k, n + 1, x)
      
      for (k, n, x) in solve():
        printf("{n} bags, each containing {k} marbles, layers 1 - {x} (of {t}) remaining", t=2 * x + 1)
        break
      

      Solution: There were 20 bags of marbles.


      We can simplify the equation:

      P(2x + 1) − P(x) = (n − 1)T(x)

      to:

      n = 7x/3 + 17/3 + 2/x

      For integer x the first two terms give us a whole number of thirds, so the 2/x term must also provide a whole number of thirds, i.e. x = 1, 2, 3, or 6.

      And the only values to give an integer value for n are:

      x = 1, n = 10
      x = 6, n = 20

      There are T(x) marbles in each of the n bags, and this is more than 1, so this eliminates the first solution leaving, T(6) = 21 marbles in each of the 20 bags.

      Here’s a Python program that uses the analysis:

      from enigma import (div, printf)
      
      for x in [2, 3, 6]:
        n = div((7 * x + 17) * x + 6, 3 * x)
        if n:
          printf("n={n} [x={x}]")
      

      Like

  • Unknown's avatar

    Jim Randell 8:16 am on 25 April 2019 Permalink | Reply
    Tags:   

    Brainteaser 1563: Family sum 

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

    In this puzzle digits have been consistently replaced by letters, with different letters being used for different digits. This addition sum then makes sense:

    also AND is divisible by three.

    What is the number REAGAN?

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

    [teaser1563]

     
    • Jim Randell's avatar

      Jim Randell 8:17 am on 25 April 2019 Permalink | Reply

      This puzzle can easily be solved using the [[ SubstitutedExpression() ]] solver from the enigma.py library.

      The following run-file executes in 480ms.

      Run: [ @replit ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      "RONALD + AND + NANCY = REAGAN"
      
      "AND % 3 = 0"
      
      --answer="REAGAN"
      

      Solution: REAGAN = 396168.

      The symbols L and C appear in the tens column, but not elsewhere, so their values can be interchanged. This gives rise to the two possible sums:

      308627 + 687 + 86854 = 396168
      308657 + 687 + 86824 = 396168

      Like

      • Jim Randell's avatar

        Jim Randell 8:41 am on 9 June 2023 Permalink | Reply

        For a faster solution we can use the [[ SubstitutedExpression.split_sum ]] solver.

        The following run file executes in 73ms. (Internal runtime of the generated program is 1.5ms).

        Run: [ @replit ]

        #! python3 -m enigma -rr
        
        SubstitutedExpression.split_sum
        
        "RONALD + AND + NANCY = REAGAN"
        
        --extra="AND % 3 = 0"
        
        --answer="REAGAN"
        

        Like

    • GeoffR's avatar

      GeoffR 12:20 pm on 25 April 2019 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
       
      var 0..9: R; var 0..9: O; var 0..9: N; var 0..9: A;  var 0..9: L; 
      var 0..9: D; var 0..9: C; var 0..9: Y; var 0..9: E;  var 0..9: G; 
      
      constraint R != 0 /\ A != 0 /\ N != 0;
      constraint all_different( [R,O,N,A,L,D,C,Y,E,G]);
      
      var 100..999: AND = 100*A + 10*N + D;
      var 10000..99999: NANCY = 10000*N + 1000*A + 100*N + 10*C + Y;
      
      var 100000..999999: RONALD = 100000*R + 10000*O + 1000*N 
      + 100*A + 10*L + D;
      
      var 100000..999999: REAGAN = 100000*R + 10000*E + 1000*A 
      + 100*G + 10*A + N;
      
      constraint AND mod 3 == 0;
      
      constraint RONALD + AND + NANCY == REAGAN;
      
      solve satisfy;
      
      output [show(RONALD) ++ " + " ++ show(AND) ++ " + " ++ 
      show(NANCY) ++ " = " ++ show(REAGAN)];
      
      % 308657 + 687 + 86824 = 396168
      % time elapsed: 0.02 s
      % ----------
      % 308627 + 687 + 86854 = 396168
      % time elapsed: 0.02 s
      %----------
      %==========
      
      

      Like

    • Frits's avatar

      Frits 1:44 pm on 9 June 2023 Permalink | Reply

        
      column 3: x + N + A = .A with x = 1,2,3 so N = 8,9,0
      
      column 2: y + O + N = E so either:
      
      N = 9, is not possible
      N = 8 and O = 0 and x = 2  
      N = 0 causes y to be zero but then O = E
      
      --> N = 8, O = 0, E = 9 and x = 2
      
      column 4:
      z + A + A + N = 2G so z + A + A >= 21 - 8 so A = 6,7
      
      using AND is divisible by three:
      (A, D, Y) is either (6, 7, 4) or (7, 3, 2)
      (A, D, Y, L+C) is either (6, 7, 4, 7) or (7, 3, 2, 9)
      (A, D, Y, {L, C}) is either (6, 7, 4, {2, 5}) or (7, 3, 2, {4, 5})
      
      (A, G) = (6, 1) as A = 7 causes G to be 3 (which is same as D)
      
      so (N, O, E, A, D, Y, G) = (8, 0, 9, 6, 7, 4, 1) with {L, C} = {2, 5}
      This leaves R = 3
      

      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