Recent Updates Page 65 Toggle Comment Threads | Keyboard Shortcuts

  • Unknown's avatar

    Jim Randell 7:04 am on 27 March 2019 Permalink | Reply
    Tags:   

    Teaser 2905: Trackword 

    From The Sunday Times, 27th May 2018 [link]

    George and Martha are tackling a Trackword problem which appears in magazines. Nine letters are placed in a 3×3 grid and you have to work from one square to a neighbour, proceeding up, down, left, right or diagonally until all nine squares have been visited to form a nine-letter word. You must start in the top-left corner. As an example, you can get the word EIGHTFOLD from the following grid:

    George and Martha thought that would be interesting to work out how many possible routes there are which start in the top-left corner.

    How many routes are there?

    [teaser2905]

     
    • Jim Randell's avatar

      Jim Randell 7:05 am on 27 March 2019 Permalink | Reply

      (See also: Grid Puzzle)

      There’s a handy [[ grid_adjacency() ]] function in the enigma.py library to compute the adjacency matrix on a square grid.

      This Python program can be used to calculate the number of paths on an m×n grid. For the 3×3 grid it runs in 81ms.

      Run: [ @repl.it ]

      from enigma import (grid_adjacency, icount, arg, printf)
      
      # consider an m x n grid
      m = arg(3, 0, int)
      n = arg(m, 1, int)
      
      # adjacency matrix
      adj = grid_adjacency(m, n, include_diagonal=1)
      
      # generate paths with k additional steps, prefix p, visiting different squares
      def paths(k, p):
        # are we done?
        if k == 0:
          yield p
        else:
          # extend the path
          for x in adj[p[-1]]:
            if x not in p:
              yield from paths(k - 1, p + [x])
      
      # count maximal length paths that start at square 0
      k = m * n - 1
      t = icount(paths(k, [0]))
      printf("[{m}x{n}] total paths = {t}")
      

      Solution: There are 138 different possible routes.

      From square 0 we can go to to the central square (4) or to an edge square (1 or 3), so we can just count the paths with prefix [0, 4] and [0, 1]. There will be the same number of paths with prefix [0, 3] as there are with prefix [0, 1].

      >>> icount(paths(7, [0, 4])) + 2 * icount(paths(7, [0, 1]))
      138
      

      Like

  • Unknown's avatar

    Jim Randell 7:01 am on 26 March 2019 Permalink | Reply
    Tags:   

    Brainteaser 1505: Waste not … 

    From The Sunday Times, 14th July 1991 [link]

    The “tangram” is an ancient Chinese puzzle. It consists of seven pieces which can be formed into a square (as shown) and into many other artistic shapes.

    The middle-sized triangle, the square and the parallelogram are all twice the area of the smaller triangles, and half the area of the larger ones. All the angles are 45, 90 or 135 degrees. And in my version the lengths of the shorter sides of the largest triangles are 7 cm.

    I have a thin rectangular sheet of card 70 cm by 91 cm from which I wish to cut as many such sets of tangrams as possible with the minimum amount of wastage.

    How many complete sets can I make?

    The text of this puzzle is taken from the book Brainteasers (2002), so may differ from the puzzle originally published in the newspaper.

    [teaser1505]

     
    • Jim Randell's avatar

      Jim Randell 7:03 am on 26 March 2019 Permalink | Reply

      The Tangram square shown, has sides measuring 7√2 cm. Which gives it an area of 98 cm².

      The 70 cm × 91 cm piece of card has an area of 6370 cm².

      So there is potentially enough card to make 65 complete sets with no wastage.

      However the square shown does will not fit into the length or width of the card an exact number of times.

      My solution is cut the card into 7 cm × 7 cm squares. This divides the card into 10 × 13 = 130 squares.

      We then rearrange the Tangram into two squares:

      These squares also measure 7 cm × 7cm.

      So, we then cut 65 of the squares using pattern A, and the remaining 65 sets using pattern B, giving us 65 complete Tangram sets.

      Solution: We can make 65 sets, with no wastage.

      Like

    • Lise Andreasen's avatar

      Lise Andreasen 7:28 am on 19 April 2024 Permalink | Reply

      Neat.

      Like

  • Unknown's avatar

    Jim Randell 8:40 am on 25 March 2019 Permalink | Reply
    Tags:   

    Teaser 2930: Odd socks 

    From The Sunday Times, 18th November 2018 [link] [link]

    I had a drawer containing some black socks and some white socks. If I drew out two socks at random the chance of getting a black pair was 1 in __.

    After many washes all the socks looked grey. So I added some red socks to the drawer. Then if I drew out two at random the chance of getting a grey pair was 1 in __.

    After many washes all the socks looked pink. So I added some green socks to the drawer. Then if I drew out two the chance of getting a pink pair was 1 in __.

    After many washes all the socks looked brown. So I have now added some yellow socks to the drawer giving me a total of fewer than fifty socks. Now if I draw out two the chance of getting a brown pair is 1 in __.

    The gaps above consist of four different prime numbers.

    If I draw out two socks at random, what is the chance of getting a yellow pair?

    [teaser2930]

     
    • Jim Randell's avatar

      Jim Randell 8:41 am on 25 March 2019 Permalink | Reply

      This Python 3 program works by finding possible (prime, X, Y) tuples for choosing a pair of X socks from X+Y, and then links together the appropriate number of tuples to solve the puzzle.

      It runs in 75ms.

      Run: [ @replit ]

      from enigma import (irange, is_prime, fraction, printf)
      
      # min and max
      (m, M) = (2, 49)
      
      # find primes of the form (X + Y)(X + Y - 1) / X(X - 1)
      # where X + Y =< M and X >= m, Y >= m
      rs = list()
      for X in irange(max(m, 2), M - m):
        for Y in irange(m, M - X):
          (p, r) = divmod((X + Y) * (X + Y - 1), X * (X - 1))
          if not (r == 0 and is_prime(p)): continue
          rs.append((p, X, Y))
      
      # solve for k steps
      def solve(k, ns=None, ps=None):
        # are we done?
        if k == 0:
          yield (ns, ps)
        else:
          if not ns:
            # first step, use both X and Y
            for (p, X, Y) in rs:
              yield from solve(k - 1, [X, Y], [p])
          else:
            # subsequent steps match sum on X
            T = sum(ns)
            for (p, X, Y) in rs:
              if X == T and p not in ps:
                yield from solve(k - 1,  ns + [Y], ps + [p])
      
      # find a sequence of 4 primes
      for ((B, W, R, G, Y), (p1, p2, p3, p4)) in solve(4):
        # calculate the probability of a yellow pair
        T = B + W + R + G + Y
        (a, b) = fraction(Y * (Y - 1), T * (T - 1))
        # output solution
        printf("P(yellow) = {a}/{b} [B={B} W={W}, p1={p1}; R={R} p2={p2}; G={G} p3={p3}; Y={Y} p4={p4}; T={T}]")
      

      Solution: There is a 1 in 6 chance of getting a yellow pair.

      There are two scenarios which give the answer:

      From 3 black and 3 white, the probability a black pair is 1/5.
      From 6 grey and 9 red, the probability of a grey pair is 1/7.
      From 15 pink and 6 green, the probability of a pink pair is 1/2.
      From 21 brown and 15 yellow, the probability of a brown pair is 1/3.

      From 3 black and 4 white, the probability a black pair is 1/7.
      From 7 grey and 8 red, the probability of a grey pair is 1/5.
      From 15 pink and 6 green, the probability of a pink pair is 1/2.
      From 21 brown and 15 yellow, the probability of a brown pair is 1/3.

      But in both cases the probability of a yellow pair (from 21 brown and 15 yellow) is 1/6.

      In the puzzle I interpreted “some” to mean “at least 2”, and this gives the solution above. However, if we interpret it as “at least 1” then you get 2 further solutions, which give an answer of 1/14. (You can change the value of [[ m ]] to [[ 1 ]] in the program to see this).

      Interestingly there are no solutions (even with the relaxation of “some”) where all the numbers of different coloured socks are all even. Which certainly is an “odd” way to acquire socks.

      Like

  • Unknown's avatar

    Jim Randell 6:36 am on 24 March 2019 Permalink | Reply
    Tags:   

    Teaser 2948: A hardy annual 

    From The Sunday Times, 24th March 2019 [link] [link]

    Yesterday was my grandson’s birthday and we continued a family tradition. I asked him to use any eight different non-zero digits (once each) to form a set of numbers that added to 2019. Last year I asked the equivalent question with a sum of 2018, and I have done this each year for over ten years. Only on one occasion has he been unable to complete the task.

    In this year’s answer his set of numbers included a 3-figure prime that had also featured in last year’s numbers.

    (a) In which year was he unable to complete the task?

    (b) What was the 3-figure prime that featured in this year’s answer?

    [teaser2948]

     
    • Jim Randell's avatar

      Jim Randell 7:48 am on 24 March 2019 Permalink | Reply

      I assumed the numbers are formed only by concatenation of digits, and not any other method.

      This Python program considers the number of digits present in each column of the sum to construct viable solutions.

      It runs in 84ms.

      Run: [ @repl.it ]

      from itertools import (combinations, product)
      from enigma import (nsplit, irange, nconcat, is_prime, printf)
      
      # different ways to construct the sum (for the years under consideration)
      # (number of digits in each column)
      exprs = [ (1, 2, 2, 3), (1, 1, 3, 3), (1, 1, 2, 4), (1, 1, 1, 5) ]
      
      # solve for the end column
      def _solve(ds, expr, digits, c, ss):
        # are we done?
        if not ds:
          # check there is no carry
          if c == 0:
            yield ss
        else:
          # consider digits for this columns
          for s in combinations(digits, expr[-1]):
            (c1, r) = divmod(sum(s) + c, 10)
            # check the sum matches the desired result
            if r == ds[-1]:
              # solve for the remaining columns
              yield from _solve(ds[:-1], expr[:-1], digits.difference(s), c1, [s] + ss)
      
      # find solutions for result n
      # return (<construction>, <digits>)
      def solve(n):
      
        # split the result into digits
        ds = nsplit(n)
      
        # digits to use (can remove (9 - digrt(n)))
        digits = set(irange(1, 9))
      
        # try to solve for each construction
        for expr in exprs:
          for ss in _solve(ds, expr, digits, 0, []):
            yield (expr, ss)
      
      # return 3-digit primes involved in solutions
      def collect(ss):
        r = set()
        for (expr, s) in ss:
          if expr != (1, 2, 2, 3): continue
          for ds in product(s[1], s[2], s[3]):
            n = nconcat(ds)
            if is_prime(n):
              r.add(n)
        return r
      
      # there must be a non-viable year in the last 11 years
      for n in irange(2019, 2009, step=-1):
        ss = list(solve(n))
      
        # are there any solutions?
        if not ss:
          printf("(a) {n} has no viable solutions")
          break
      
        if n == 2019:
          ps2019 = collect(ss)
      
        if n == 2018:
          ps2018 = collect(ss)
          ps = ps2018.intersection(ps2019)
          printf("(b) primes = {ps}")
      

      Solution: (a) 2015. (b) 523.

      Like

      • Jim Randell's avatar

        Jim Randell 8:30 am on 31 March 2019 Permalink | Reply

        There are 9 different ways we can construct the sum to potentially give a 4-digit result.

        Counting the number of digits in each of the columns of the sum (<thousands>, <hundreds>, <tens>, <ones>), we have:

        (2, 2, 2, 2) → ABCD + EFGH
        (1, 2, 2, 3) → ABCD + EFG + H
        (1, 1, 3, 3) → ABCD + EF + GH
        (1, 1, 2, 4) → ABCD + EF + G + H
        (1, 1, 1, 5) → ABCD + E + F + G + H
        (0, 2, 3, 3) → ABC + DEF + GH
        (0, 2, 2, 4) → ABC + DEF + G + H
        (0, 1, 3, 4) → ABC + DE + FG + H
        (0, 1, 2, 5) → ABC + DE + F + G + H

        However, for years in the range 2009 to 2019 we only need to consider the constructions that have a single 4-digit number, i.e.:

        (1, 2, 2, 3)
        (1, 1, 3, 3)
        (1, 1, 2, 4)
        (1, 1, 1, 5)

        It turns out there are 132 sets of numbers that can be made that sum to 2019. And 114 that sum to 2018.

        We can compute the number of solutions for various years as follows:

        2019: 132
        2018: 114
        2017: 114
        2016: 96
        2015: 0
        2014: 132
        2013: 132
        2012: 114
        2011: 132
        2010: 132
        2009: 132
        2008: 234
        2007: 114
        2006: 0
        2005: 65
        2004: 71
        2003: 95
        2002: 65
        2001: 71
        2000: 95
        1999: 96
        1998: 48
        1997: 0
        1996: 83
        1995: 83
        1994: 107
        1993: 89
        1992: 113
        1991: 108
        1990: 101
        1989: 66
        1988: 0

        Using digital roots we can see that the missing digit in the sum for year n is:

        9 − digrt(n)

        So every 9 years (when the year has remainder of 8 when divided by 9), we get a year that has no solutions, as it is not possible to make a year after 1889 without using the digit 1, until we get to 2375. The years we are considering fall within this range, and so there is one year in the required range can have no solutions. This provides the answer to the first part of puzzle.

        The possible solutions for the year 2018 are (with the solutions involving 3 digit numbers indicated (*)):

        [1][36][28][459] = 2018 (*)
        [1][45][28][369] = 2018 (*)
        [1][9][235][468] = 2018
        [1][9][28][3456] = 2018
        [1][9][46][2358] = 2018

        The digits are grouped into columns, so the first number is made by choosing one digit from each of the groups, e.g. 1324, then the second number is made by choosing from the remaining digits, e.g. 685, and the next number is formed from the remaining digits, in this case 9. This exhausts all the digits, so: 1324 + 685 + 9 = 2018.

        In this way we see the possible 3-digit numbers involved are:

        [36][28][459]
        [45][28][369]

        and the only ones that are prime are 389 and 523.

        For 2019 the corresponding solutions are:

        [1][45][28][379] = 2019 (*)
        [1][45][37][289] = 2019 (*)
        [1][8][579][234] = 2019
        [1][9][235][478] = 2019
        [1][9][28][3457] = 2019
        [1][9][37][2458] = 2019

        So the 3-digit prime needs to match:

        [45][28][379]
        [45][37][289]

        And the only one of our candidates that matches is 523.

        So we have:

        2018 = 523 + [1][4][8][69] = (523 + 1486 + 9, 523 + 1489 + 6)

        missing out the digit 7.

        And:

        2019 = 523 + [1][4][8][79] = (523 + 1487 + 9, 523 + 1489 + 7)

        missing out the digit 6.

        This provides the answer to the second part of the puzzle.

        Like

  • Unknown's avatar

    Jim Randell 7:21 am on 23 March 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 466: [Ferry fare] 

    From The Sunday Times, 3rd May 1970 [link]

    The ferryman collected 5s. when he took six horses and two prams across the river, and 5s. 9d. when he brought six bicycles and three wheel-barrows back. He is at present collecting 4s. for two wheel-barrows, three prams and a horse.

    His idiosyncratic tariff of charges is for vehicles and animals only, and not for people.

    How much will he collect for his next cargo, which awaits him on the far bank and consists of one wheel-barrow, one horse, one bicycle and one pram?

    This puzzle was originally published with no title.

    [teaser466]

     
    • Jim Randell's avatar

      Jim Randell 7:32 am on 23 March 2019 Permalink | Reply

      We note that 1 shilling (s) = 12 pence (d).

      So we have the following 3 equations (expression amounts in pence):

      [1]: 6h + 2p = 60
      [2]: 3w + 6b = 69
      [3]: 2w + 1h + 3p = 48

      There are 3 equations in 4 variables, so we cannot work out the actual prices. But we don’t need to, we are looking for the price of a particular combination.

      So, we can consider looking for multipliers t, u, v for the equations that give the required combination:

      [*]: t × [1] + u × [2] + v × [3] = 1w + 1h + 1b + 1p

      Then the amount to be collected (in pence) is then:

      t × 60 + u × 69 + v × 48

      Equating the coefficients of w, h, b, p we get the following 4 equations:

      [w]: 3u + 2v = 1
      [h]: 6t + v = 1
      [b]: 6u = 1
      [p]: 2t + 3v = 1

      which is 4 equations in 3 variables, so we try to solve them:

      From [b]:

      u = 1/6

      Then from [w]:

      v = 1/4

      and from [h]:

      t = 1/8

      And we can check [p] gives the right value (which it does).

      So the equations are consistent, and the solution is:

      60/8 + 69/6 + 48/4 = 31 (pence)

      Solution: He will collect 2s 7d.


      Here’s a Python program that does the same thing using the Gaussian elimination solver for linear equations from the enigma.py library. (Originally written for Enigma 287).

      It runs in 87ms.

      from enigma import (Matrix, printf)
      
      # solve the equations
      (t, u, v) = Matrix.linear([[0, 3, 2], [6, 0, 1], [0, 6, 0], [2, 0, 3]], [1, 1, 1, 1])
      
      # determine the answer in pence
      x = t * 60 + u * 69 + v * 48
      # ... in shillings and pence
      (s, d) = divmod(x, 12)
      
      printf("fare = {s}s {d}d [t={t} u={u} v={v}]")
      

      Like

  • Unknown's avatar

    Jim Randell 7:58 am on 22 March 2019 Permalink | Reply
    Tags:   

    Teaser 2931: Unfortunate 57 

    From The Sunday Times, 25th November 2018 [link] [link]

    In the early days of the internet, I used a secret shorthand for my important passwords:

    Bank=1/7, Credit Card=2/7, ISP=3/7, etc.

    Like all fractions, the decimal expansions:

    1/7 = 0.142857142857142…
    2/7 = 0.285714285714285…

    eventually repeat themselves, in this case in sequences of six digits. In each case, my password was the set of digits that repeat (“Unfortunate 57” is a mnemonic for 142857). As password requirements became stricter, I changed my system to base 11, using an X for the extra digit for “ten”; so for instance in base 11:

    234 (= 1 × 11^2 + 10 × 11^1 + 3 × 11^0) is 1X3 [base 11], and;
    1/2 = 0.5555… [base 11] = 5 / (11^1) + 5 / (11^2) + 5 / (11^3) + …

    In the sequence 1/2, 1/3, …, what is the first password of length greater than six that my base-11 system produces?

    The setter is probably conflating “the internet” with “the world wide web”.

    [teaser2931]

     
    • Jim Randell's avatar

      Jim Randell 7:58 am on 22 March 2019 Permalink | Reply

      For Enigma 1247 I wrote the [[ recurring() ]] function, which will calculate the recurring representation of a fraction in a given base.

      We can use this routine in a short Python program to solve this puzzle. It runs in 74ms.

      Run: [ @replit ]

      from enigma import (irange, inf, recurring, format_recurring, printf)
      
      for x in irange(2, inf):
        (i, nr, rr) = recurring(1, x, base=11, digits='0123456789X')
        printf("1 / {x} = {f} [period = {n}]", f=format_recurring(i, nr, rr), n=len(rr))
        if len(rr) > 6: break
      

      Solution: The first password with length greater than 6 is: 093425X17685.

      It is produced by the fraction 1/13 (in decimal notation).

      Like

    • Lise Andreasen's avatar

      Lise Andreasen 7:17 am on 19 April 2024 Permalink | Reply

      In the early days of the internet, we had SMTP (email), FTP etc.

      Like

  • Unknown's avatar

    Jim Randell 7:08 am on 21 March 2019 Permalink | Reply
    Tags:   

    Teaser 1986: Protracted calculation 

    From The Sunday Times, 8th October 2000 [link]

    In the circle illustrated the numbers represent the sizes of the sectors:

    By combining adjacent ones it is possible to find sectors in this circle of sizes 1, 2, 3, … all the way up to 13 (13 being the whole circle). For example:

    7 = 4 + 1 + 2.

    In a similar fashion, given a circle divided into five sectors in a particular way, it is possible to combine adjacent sectors to give sizes 1, 2, 3, … up to the biggest possible in the circumstances.

    What, in increasing order, are the sizes of the five sectors?

    The text of this puzzle is taken from the book Brainteasers (2002), the wording differs only slightly from the puzzle originally published in the newspaper.

    [teaser1986]

     
    • Jim Randell's avatar

      Jim Randell 7:09 am on 21 March 2019 Permalink | Reply

      If the circle is divided into k sectors, then for each starting sector (and there are k of them) we can make a contiguous region consisting of 1, 2, 3, …, (k − 1) sectors. We don’t make a region of k sectors because that is the whole circle, so we add that in separately giving a total number of arrangements of:

      n(k) = k(k − 1) + 1 = k² − k + 1

      To make the arrangements correspond to the numbers 1, 2, 3, … n(k), the whole circle needs to correspond to the value n(k), and there needs to be a single sector corresponding to the number 1. So we place the number 1 in the first sector, and then distribute the remaining (n(k) − 1) between the remaining (k − 1) sectors.

      This Python 3 program finds the solution in 83ms.

      Run: [ @replit ]

      from itertools import permutations
      from enigma import (irange, arg, printf)
      
      # generate (non-empty) tuples of adjacent sectors
      def sectors(k):
        # consider n consecutive sectors
        for n in irange(1, k - 1):
          # possible start sector
          for i in irange(0, k - 1):
            yield tuple((i + j) % k for j in irange(0, n - 1))
        # the whole circle
        yield tuple(irange(0, k - 1))
      
      # decompose <t> into <n> different numbers, min <m>
      def decompose(t, n, m, s=[]):
        if n == 1:
          if not (t < m):
            yield s + [t]
        else:
          for x in irange(m, t - n):
            yield from decompose(t - x, n - 1, x + 1, s + [x])
      
      # number of sectors to divide the circle into
      k = arg(5, 0, int, prompt="number of sectors")
      assert k > 1
      
      # make a list of adjacent sectors
      ss = list(sectors(k))
      t = len(ss)
      printf("[k={k}: {t} arrangements]")
      
      # put 1 at sector 0, and decompose the remainder
      for d in decompose(t - 1, k - 1, 2):
        for p in permutations(d):
          if p[0] > p[-1]: continue
          s = (1,) + p
          # calculate the values of adjacent sectors
          vs = set(sum(s[i] for i in x) for x in ss)
          if len(vs) == t:
            printf("{s}")
      

      Solution: The five sectors have values: 1, 2, 3, 5, 10 (in numerical order).

      They can be arranged like this:

      As well as the example given it is also possible to make a circle with 4 sectors using the values: 1, 3, 2, 7.

      The program is suitable for experimenting with small values of k. (One simple way to improve the program is to note that as well as a 1 sector, we will also need a 2 sector in the remaining decomposition).

      Here are the number of solutions for various values of k:

       k  n(k)  solutions
       1     1    1
       2     3    1
       3     7    1
       4    13    2
       5    21    1
       6    31    5
       7    43    0
       8    57    6
       9    73    4
      10    91    6
      11   111    0
      12   133   18
      13   157    0
      14   183   20
      ...

      (See: OEIS A058241 [ link ]).

      We’ve come across the following formula before:

      n(k) = k^2 − k + 1

      Specifically in the exploration of Teaser 2907, where it is the number of elements in a finite projective plane of order (k − 1).

      The fact that there is no solution for (k = 7, n = 43), (k = 11, n = 111) and (k = 13, n = 157) makes me wonder if there is a link with projective planes, as finite projective planes of order 6, 10, and 12 (probably) do not exist.


      For a more efficient way to generate “magic circles” see my comment on Enigma 985.

      Like

      • Frits's avatar

        Frits 11:47 am on 13 June 2022 Permalink | Reply

        @Jim,

        You might use (and in Enigma 985):

           
        for x in irange(m, t - n * (n - 1) // 2):
        

        in decompose() as we need different numbers. It doesn’t seem to make much of a difference in the performance.

        Like

        • Jim Randell's avatar

          Jim Randell 11:29 am on 14 June 2022 Permalink | Reply

          @Frits: If I were to re-write the code now I would probably just use [[ decompose() ]] from enigma.py (and [[ tuples() ]] to generate the adjacent sectors). [See: @replit]

          from enigma import (irange, tuples, decompose, arg, printf)
          
          # generate (non-empty) tuples of adjacent sectors
          def sectors(k):
            # the whole circle
            t = tuple(irange(k))
            # consider n consecutive sectors
            for n in irange(1, k - 1):
              yield from tuples(t, n, circular=1)
            # and the whole circle
            yield t
          
          # number of sectors to divide the circle into
          k = arg(5, 0, int)
          assert k > 1
          
          # make a list of adjacent sectors
          ss = list(sectors(k))
          t = len(ss)
          printf("[k={k}: {t} arrangements]")
          
          # put 1 at sector 0, and 2 somewhere, and decompose the remainder
          for d in decompose(t - 3, k - 2, increasing=0, sep=1, min_v=3, fn=list):
            # insert 2 somewhere
            for i in irange(0, (0 if k == 2 else k - 3)):
              s = list(d)
              s.insert(i, 2)
              if s[0] > s[-1]: continue
              # insert 1 at sector 0
              s.insert(0, 1)
              # calculate the value for adjacent sectors
              vs = set(sum(s[i] for i in x) for x in ss)
              if len(vs) == t:
                printf("{s}", s=tuple(s))
          

          But using magic_circles.py gives a much shorter and faster program:

          from enigma import (arg, printf)
          from magic_circles import magic_circle
          
          # number of sectors to divide the circle into
          k = arg(5, 0, int, prompt="number of sectors")
          assert k > 1
          
          # find magic k-circles
          for s in magic_circle(k):
            # output solution
            printf("{s}")
          

          Like

  • Unknown's avatar

    Jim Randell 11:31 am on 20 March 2019 Permalink | Reply
    Tags:   

    Teaser 2932: Triangulation 

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

    Liam plans to make a set of dominoes. They will be triangular, and one face of each domino will have a number at each corner. The numbers run from 0 up to a maximum digit (9 or less), and the set is to include all possible distinguishable dominoes.

    With the maximum digit he has chosen the set would contain a triangular number of dominoes. [A triangular number is one where that number of balls can fit snugly in an equilateral triangle, for example the 15 red balls on a snooker table].

    How many dominoes will he need to make?

    [teaser2932]

     
    • Jim Randell's avatar

      Jim Randell 11:32 am on 20 March 2019 Permalink | Reply

      For each maximum digit, this Python program constructs all possible dominoes that are unique by rotation. It runs in 75ms.

      Run: [ @repl.it ]

      from itertools import product
      from enigma import (irange, is_triangular, printf)
      
      for d in irange(0, 9):
        s = set()
        # choose three numbers for the corners
        for (a, b, c) in product(irange(0, d), repeat=3):
          # record the domino by it's minimal rotation
          s.add(min((a, b, c), (b, c, a), (c, a, b)))
      
        # count the number of different dominoes
        n = len(s)
        t = ('[triangular]' if is_triangular(n) else '')
        printf("d={d}: {n} dominoes {t}")
      

      Solution: He will need to make 45 dominoes.

      There is a degenerate solution where only the digit 0 is used. There is only one domino (0, 0, 0), and 1 is a triangular number T(1) = 1.

      Running the program we see the number dominoes is given by the following sequence:

      1, 4, 11, 24, 45, 76, 119, 176, 249, 340

      which is OEIS A006527 [ link ] the general formula is:

      a(n) = n (n² + 2) / 3

      so we don’t have to count the dominoes.

      from enigma import (irange, is_triangular, printf)
      
      for d in irange(1, 10):
        n = (d**3 + 2 * d) // 3
        t = ('[triangular]' if is_triangular(n) else '')
        printf("d={d}: {n} dominoes {t}", d=d - 1)
      

      If we consider d > 9 there are larger solutions at d = 12 (741 dominoes) and d = 35 (15576 dominoes).

      Like

  • Unknown's avatar

    Jim Randell 7:04 am on 19 March 2019 Permalink | Reply
    Tags: ,   

    Brain-Teaser 465: [Lifts] 

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

    Near my house is an impressive block of flats. It stands 16 storeys high, and each story is a lofty 15 feet from floor to floor. My old friends Bob and Horace operate the two lifts, and both start their shift each morning leaving the ground floor at 8 a.m. precisely.

    The two lifts make automatic compulsory stops at the ground level (there is no basement), the 12th and top floors. But below the 12th, Bob serves only the odd-numbered floors, and Horace the even numbers; these stops are also compulsory (up and down). All stops take just 10 seconds, except at ground level where both lifts wait for 20 seconds.

    Above the 12th both Bob and Horace stop as desired, going up and coming down. Both lifts travel between floors at identical speeds.

    Every morning the two attendants make a rendezvous to exchange newspapers and collect their coffee when their arrivals at a certain floor coincide exactly at two minutes after 11 a.m.

    In feet per second what the speed of each lift between stops?

    Note: In the UK the floors in buildings are: ground floor, first floor, second floor, etc.

    Also, as stated this puzzle does not appear to have a unique solution.

    An answer was published (with Teaser 467) stating:

    “This clever trap, with its nice reasoning, outweighed the slight mathematical bias and kept down the entry to a mixed handful.”

    But later, with Teaser 471 the following statement was made:

    “[465: Regretfully a wrong transposition led to a false calculation of time.]”

    In the comments I give a variation on the puzzle that does have a unique answer.

    This puzzle was originally published with no title.

    [teaser465]

     
    • Jim Randell's avatar

      Jim Randell 7:05 am on 19 March 2019 Permalink | Reply

      Replacing the third paragraph (“Above the 12th floor…”) with the following gives a puzzle that does have a unique solution, and it is the same as the published answer.

      The 13th floor is considered to be unlucky, so at the beginning of each day the attendants toss a coin to decide who should service it that day. The loser has to stop at the 13th floor each time they pass it, and the winner stops at the 14th floor each time they pass it. Both lifts take the same amount of time to travel between adjacent floors.

      This Python program can be used to investigate situations where the attendants follow a fixed schedule of stops. And it solves this variation puzzle in 412ms.

      Run: [ @repl.it ]

      from fractions import Fraction as F
      from enigma import printf
      
      # number of seconds between 08:00:00 and 11:02:00
      S = (3 * 60 + 2) * 60
      
      # wait at each floor (seconds)
      wait = [20] + [10] * 15
      
      # generate (<floor>, <seconds>, <n floors>)
      def stops(fs, wait=wait):
        s = n = f = 0
        while True:
          # going up
          for (i, x) in enumerate(fs):
            if i == 0: continue
            s += wait[f]
            n += (x - f)
            f = x
            yield (f, s, n)
          # going down
          for (i, x) in enumerate(reversed(fs)):
            if i == 0: continue
            s += wait[f]
            n += (f - x)
            f = x
            yield (f, s, n)
      
      # collect possible (f, s, n) tuples
      def collect(fs, xs):
        for (f, s, n) in stops(fs):
          if not (s < S): break
          if f in xs: yield (f, s, n)
      
      # solve for specific floors visited by B and H
      def solve(B, H):
        # find common floors
        xs = set(B).intersection(H)
        # collect (<floor>, <seconds>, <n floor>) tuples for each
        Bs = list(collect(B, xs))
        Hs = list(collect(H, xs))
      
        # consider possible meeting stops for B (at time S)
        for (fB, sB, nB) in Bs:
          # calculate time between floors
          t = F(S - sB, nB)
          # look for matching stops for H
          for (fH, sH, nH) in Hs:
            if fH == fB and sH + t * nH == S:
              printf("t={t}s [floor={fB}, B=(wait={sB}s, floors={nB}), H=(wait={sH}s, floors={nH})]")
      
      # send B to floor 13, H to floor 14
      solve(
        [0, 1, 3, 5, 7, 9, 11, 12, 13, 15], # floors for B
        [0, 2, 4, 6, 8, 10, 12, 14, 15], # floors for H
      )
      

      Solution: The time between floors is 3s, giving an average speed of 5 ft/s.

      By 11:02 am, Bob has spent 7410s waiting and travelled 1170 floors. Horace has has waited for 7140s and travelled 1260 floors.

      Like

  • Unknown's avatar

    Jim Randell 7:41 am on 18 March 2019 Permalink | Reply
    Tags:   

    Teaser 2933: Sunday Teaser 

    From The Sunday Times, 9th December 2018 [link] [link]

    I wrote down two three-figure numbers and worked out their product by long multiplication. Systematically replacing digits by letters, my workings became:

    I then wrote down two numbers which were represented by SUNDAY TEASER.

    What were these two numbers?

    [teaser2933]

     
    • Jim Randell's avatar

      Jim Randell 7:42 am on 18 March 2019 Permalink | Reply

      This alphametic problem can be solved directly using the [[ SubstitutedExpression() ]] solver in the enigma.py library.

      The following run file executes in 123ms.

      Run: [ @repl.it ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      --answer="(SUNDAY, TEASER)"
      
      "NTS * EDS = ARRATS"
      
      "NTS * S = DURS"
      "NTS * D = YRD"
      "NTS * E = ANDU"
      

      Solution: SUNDAY = 684219; TEASER = 731635.

      Like

    • GeoffR's avatar

      GeoffR 9:48 am on 2 December 2020 Permalink | Reply

      
      from itertools import permutations
      digits = set('1234567890')
      
      for P1 in permutations(digits, 7):
        n, t, s, e, d, a, r = P1
        if '0' in (n, e, d, a, t, s):
          continue
        nts, eds = int(n + t + s), int(e + d + s)
        arrats = int(a + r + r + a + t + s)
        if nts * eds == arrats:
      
          # find remaining digits
          Q1 = digits.difference(P1)
          for P2 in permutations(Q1, 2):
            u, y = P2
            durs, yrd = int(d + u + r + s), int(y + r + d)
            andu = int(a + n + d + u)
            if int(s) * nts == durs:
              if int(d) * nts == yrd:
                if int(e) * nts == andu:
                  if durs + yrd * 10 + andu * 100 == arrats:
                    SUNDAY = int(s + u + n + d + a + y)
                    TEASER = int(t + e + a + s + e + r)
                    print(f"SUNDAY = {SUNDAY}, TEASER = {TEASER}")
                    print(f"Main sum: {nts} x {eds} = {arrats}")
      
      # SUNDAY = 684219, TEASER = 731635
      # Main sum: 476 x 326 = 155176
      
      
      

      Like

    • Frits's avatar

      Frits 9:31 pm on 2 December 2020 Permalink | Reply

      A different approach, not very efficient.

      from enigma import nconcat
      
      # get integer value for string <s>
      getvar = lambda vals, template, s: nconcat(vals[template.index(x)] for x in s)
      
      LETTERS = "SDNTURYAE" 
      VARLIST = ["NTS", "DURS", "S", "D", "YRD", "E", "ARRATS", "EDS", "ANDU"]
      
      # minimum values of letters
      RNGMIN = [1, 1, 1, 1, 0, 1, 1, 1, 1]
      
      def solve(t, ns=[]):
        if t == 0:  # we have set all letters
          # calculate variables (we need to store results in a dictionary)
          ex = ""
          d = dict()
          for v in VARLIST:
            ex += "d['" + v + "'] = getvar(ns, LETTERS, '" + v + "');\n"  
          exec(ex)
        
          # perform final checks  
          if d["NTS"] * d["EDS"] != d["ARRATS"]: return
          if d["NTS"] * d["S"] != d["DURS"]: return
          if d["NTS"] * d["D"] != d["YRD"]: return
          if d["NTS"] * d["E"] != d["ANDU"]: return
          
          yield ns
        else:
          if t == 8:       # variable S read, check (S*S) % 10 = S
            if ns[0]**2 % 10 != ns[0]:
              return
          if t == 7:       # variable S and D read, check (S*D) % 10 = D
            if (ns[0] * ns[1]) % 10 != ns[1]:
              return    
          if t == 3:       # variable S,D,N,T,U,R read
            ex = ""
            d = dict()
            for v in VARLIST[:3]:
              ex += "d['" + v + "'] = getvar(ns, LETTERS, '" + v + "');\n" 
            exec(ex)
            if d["NTS"] * d["S"] != d["DURS"]: 
              return
            
          for n in range(RNGMIN[len(LETTERS) - t], len(LETTERS) + 1):
            if n not in ns:   # variables all diffferent
              yield from solve(t - 1, ns + [n])
      
      res = solve(len(LETTERS))
      for r in res: 
        print(f"SUNDAY = {getvar(r, LETTERS, 'SUNDAY')} "
              f"TEASER = {getvar(r, LETTERS, 'TEASER')}")
      
      
      # SUNDAY = 684219 TEASER = 731635
      

      Like

  • Unknown's avatar

    Jim Randell 6:17 am on 17 March 2019 Permalink | Reply
    Tags:   

    Teaser 2947: 55 Divisions 

    From The Sunday Times, 17th March 2019 [link] [link]

    To mark her 55th birthday, Martha, a school teacher, gave each of her nine pupils a sheet of paper with a single different digit from 1 to 9 written on it.

    They stood at the front of the classroom in a row and the 9-digit number on display was divisible by 55. Martha then asked the first 3 in the row (from the left) to sit down. The remaining 6-digit number was also divisible by 55. The next 3 then sat down and the remaining 3-digit number was also divisible by 55.

    The 9 digit number was the smallest possible. What was it?

    [teaser2947]

     
    • Jim Randell's avatar

      Jim Randell 6:25 am on 17 March 2019 Permalink | Reply

      We can treat the problem as an alphametic puzzle, use the [[ SubstitutedExpression() ]] solver from the enigma.py library to find all possible solutions, and then find the smallest of these.

      This Python program runs in 98ms.

      from enigma import (SubstitutedExpression, Accumulator, irange, printf)
      
      # the alphametic puzzle
      p = SubstitutedExpression(
        [ "ABCDEFGHI % 55 = 0", "DEFGHI % 55 = 0", "GHI % 55 = 0" ],
        answer="ABCDEFGHI",
        digits=irange(1, 9),
      )
      
      # find the minimum answer
      r = Accumulator(fn=min).accumulate_from(p.answers())
      
      # output solution
      printf("min answer = {r.value} [of {r.count} solutions]")
      

      Solution: The number is 143869275.

      There are 48 different solutions to the alphametic puzzle.

      Like

    • GeoffR's avatar

      GeoffR 2:46 pm on 19 March 2019 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
      
      enum letters = {A, B, C, D, E, F, G, H, I};  
      array [letters] of var 1..9: v;
      
      constraint all_different(v);
      
      var 100000000..999999999: ABCDEFGHI = v[A] * pow(10,8) + v[B] * pow(10,7) 
      + v[C] * pow(10,6) + v[D] * pow(10,5) + v[E] * pow(10,4) + v[F] * 1000 
      + v[G] * 100 + v[H] * 10 + v[I];
      
      var 100000..999999: DEFGHI = 100000 * v[D] + 10000 * v[E] + 1000 * v[F] 
      + 100 * v[G] + 10 * v[H] + v[I];
      
      var 100..999: GHI = 100 * v[G] + 10 * v[H] + v[I];
      
      constraint ABCDEFGHI mod 55 == 0 /\ DEFGHI mod 55 == 0 /\ GHI mod 55 == 0;
      
      solve minimize(ABCDEFGHI);
      
      output ["Smallest 9-digit number = " ++ show(ABCDEFGHI) ];
      
      % Smallest 9-digit number = 143869275
      % time elapsed: 0.03 s
      % ----------
      % ==========
      % Finished in 241msec
      
      
      

      Like

      • Jim Randell's avatar

        Jim Randell 11:09 am on 20 March 2019 Permalink | Reply

        This puzzle is an ideal candidate for using the [[ solve minimize(...) ]] target in a MiniZinc model.

        Also I didn’t know MiniZinc had [[ enum ]]. (In fact, in the tutorial I used I seem to remember there was a section on how it didn’t have them and how to emulate them. I suppose they must have come along in a later version).

        Like

    • GeoffR's avatar

      GeoffR 12:14 pm on 20 March 2019 Permalink | Reply

      The latest version of MiniZinc( Ver 2.2.3) has much improved documentation and a new menu, including timing for Windows and other features. It seems odd that a solution can be found in 20 -30 msec, but still takes over 200msec to finish.

      Here is the link for enums:

      https://www.minizinc.org/doc-2.2.3/en/spec.html#enumerated-types

      Like

    • Jim Randell's avatar

      Jim Randell 10:29 am on 29 July 2020 Permalink | Reply

      I’ve recently added the [[ accumulate ]] parameter to the [[ SubstitutedExpression() ]] solver, which allows values to be computed from all the solutions.

      So, my Python program above can be modified to:

      from enigma import (SubstitutedExpression, irange, printf)
      
      # the alphametic puzzle
      p = SubstitutedExpression(
        [ "ABCDEFGHI % 55 = 0", "DEFGHI % 55 = 0", "GHI % 55 = 0" ],
        digits=irange(1, 9),
        answer="ABCDEFGHI",
        accumulate=min,
      )
      
      # solve the puzzle
      r = p.run()
      
      # output solution
      printf("min answer = {r.accumulate} [of {r.n} values]")
      

      Although the accumulated value will be output twice.

      We can also achieve the same result using a run file:

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --digits="1-9"
      
      "ABCDEFGHI % 55 = 0"
      "DEFGHI % 55 = 0"
      "GHI % 55 = 0"
      
      --answer="ABCDEFGHI"
      --accumulate="min"
      

      Note that changing the [[ --accumulate ]] parameter to [[ --accumulate="(min, max)" ]] allows us to calculate the minimum and maximum values from the answers.

      This functionality is available in the 2020-07-29 version of the enigma.py library.

      Like

  • Unknown's avatar

    Jim Randell 8:04 am on 16 March 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 464: Home meadow 

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

    The triangular home meadow at Cowpleasure Farm is bounded West and South by fences running due north and due east from the farmhouse; its other fence forms one side of a square field known as Starvecrow. The south fence of Home Meadow is the shared north boundary of two contiguous square fields, Paddock and Rookery, whose total area is just half that of Starvecrow.

    Farmer Nettle has just refenced the whole outer perimeter (i.e. excluding fences common to two fields). He used 146 equal sections of fencing, none of which needed bending or cutting.

    He plans to replace the other fences next year using the same type of section.

    How many will he need? (Don’t worry about gates; they are incorporated in some of the standard sections).

    This puzzle is included in the book Sunday Times Brain Teasers (1974).

    [teaser464]

     
    • Jim Randell's avatar

      Jim Randell 8:06 am on 16 March 2019 Permalink | Reply

      There’s nothing to distinguish the fields P and R, so we’ll call the smaller one P.

      For the square fields P, R, S, we’ll indicate the size of one side also by P, R, S, and the remaining boundary of H can be Q.

      The amount of perimeter fencing (shown in red) required is X:

      X = 3S + 2P + 2R + (R − P) + Q = 3(S + R) + P + Q

      And the amount of internal fencing (the remaining black lines) required is Y:

      Y = 2P + R + S

      This Python program uses the [[ pythagorean_triples() ]] routine (see Teaser 2910) from the enigma.py library to find possible dimensions of field H, and then determines the dimensions of the other fields.

      It runs in 77ms.

      Run: [ @repl.it ]

      from enigma import pythagorean_triples, irange, printf
      
      for (x, y, z) in pythagorean_triples(48):
        # S is the hypotenuse
        S = z
        # one of the other two sides is P + R
        for (PR, Q) in [(x, y), (y, x)]:
          # suppose P < R
          for P in irange(1, PR // 2):
            R = PR - P
            # P^2 + R^2 = S^2 / 2
            if not (2 * (P * P + R * R) == S * S): continue
            # total sum of perimeter fences is 146
            X = 3 * (S + R) + P + Q
            if not (X == 146): continue
            # sum of the internal fences
            Y = S + PR + P
            # output solution
            printf("Y={Y}, S={S} P={P} R={R} Q={Q}")
      

      Solution: He will need 57 sections.

      Like

  • Unknown's avatar

    Jim Randell 8:36 am on 15 March 2019 Permalink | Reply
    Tags:   

    Teaser 2934: Good arraz, Baz! 

    From The Sunday Times, 16th December 2018 [link] [link]

    Baz’s three darts hit the board, scoring different numbers from 1 to 20. “Curious numbers”, said Kaz. Baz looked puzzled. Kaz explained that the first dart’s score to the power of the second dart’s score is a value that contains each numeral 0 to 9 at least once and has the third dart’s score number of digits. Baz only saw that the third dart’s score was the difference between the other two darts’ scores. Kaz wrote the full value on a beer mat. Then Baz put his glass on it and covered most of the value, leaving just the first dart’s score showing to the right and the second dart’s score to the left.

    What did each dart score in the order thrown?

    [teaser2934]

     
    • Jim Randell's avatar

      Jim Randell 8:36 am on 15 March 2019 Permalink | Reply

      This Python program runs in 75ms.

      Run: [ @repl.it ]

      from itertools import permutations
      from enigma import (irange, printf)
      
      # possible scores
      darts = set(irange(1, 20))
      
      # consider different scores for the first two darts
      for (d1, d2) in permutations(darts, 2):
      
        # "the third dart's score was the difference between the other two darts' scores"
        d3 = abs(d1 - d2)
        if d3 == d1 or d3 == d2 or d3 < 10: continue
      
        # "the first dart's score to the power of the second dart's score is a value that contains
        # each digit 0 to 9 at least once and has the third dart's score number of digits"
        x = str(d1**d2)
        if len(x) != d3: continue
        if len(set(x)) != 10: continue
      
        # "the first dart's score showing to the right and the second dart's score to the left."
        # assuming "right" = "least significant digits"
        # and "left" = "most significant digits"
        if not (x.endswith(str(d1)) and x.startswith(str(d2))): continue
      
        # output solution
        printf("darts = ({d1}, {d2}, {d3}) [{d1}^{d2} = {x}]")
      
      

      Solution: The scores were: 5, 19, 14.

      We have:

      5^19 = 19073486328125

      Which starts with 19, and ends in 5.

      Like

  • Unknown's avatar

    Jim Randell 6:59 am on 14 March 2019 Permalink | Reply
    Tags: by: Fred Neville   

    Brainteaser 1795: Dicey columns 

    From The Sunday Times, 9th February 1997 [link]

    A boy amused himself by building three separate columns of some equal-sized dice. In each column each die was placed squarely on the one below it. He then looked at the tops of the columns, read each as a digit, and then read the digits together to form one long number.

    For example, had the tops been:

    then he would have read 113.

    He was surprised to find that the number which he read equalled the total number of visible spots all around and on top of his three columns of dice. He also multiplied together the three numbers from the tops of the columns and found that the answer equalled the total number of dice which he had used.

    What was that total number of visible spots?

     

    For a more challenging Teaser try to find a corresponding situation with more than three columns of dice. There is only one other possibility.

     

    The text of this puzzle is taken from the book Brainteasers (2002), so may differ from the puzzle originally published in the newspaper.

    In fact, the puzzle published in the paper was the more challenging variation.

    [teaser1795]

     
    • Jim Randell's avatar

      Jim Randell 7:01 am on 14 March 2019 Permalink | Reply

      Suppose the tops of the three columns show A, B, C.

      Opposite faces on a die sum to 7, so each die shows 14 spots on the vertical sides, and the top dice also show A, B, C, so if there are n dice the total number of spots visible is:

      14n + (A + B + C) = ABC

      (where ABC is an alphametic expression).

      Also the number of dice is given by:

      n = A × B × C

      which gives us the following alphametic expression to solve:

      (14 × A × B × C) + (A + B + C) = ABC

      where A, B, C are limited to be digits from 1 to 6.

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

      Run: [ @repl.it ]

      >>> python enigma.py SubstitutedExpression --distinct="" --digits="1-6" "14 * (A * B * C) + (A + B + C) = ABC"
      (14 * (A * B * C) + (A + B + C) = ABC)
      (14 * (1 * 3 * 3) + (1 + 3 + 3) = 133) / A=1 B=3 C=3
      [1 solution]
      

      Solution: The total number of visible spots was 133.

      So there are 9 dice in total (3 columns of 3 dice each).

      In the book the puzzle then goes on to suggest:

      For a more challenging Teaser try to find a corresponding situation with more than three columns of dice. There is only one other possibility.

      We can try the same thing with four dice, showing A, B, C, D:

      >>> python enigma.py SubstitutedExpression --distinct="" --digits="1-6" "14 * (A * B * C * D) + (A + B + C + D) = ABCD"
      (14 * (A * B * C * D) + (A + B + C + D) = ABCD)
      (14 * (2 * 5 * 3 * 6) + (2 + 5 + 3 + 6) = 2536) / A=2 B=5 C=3 D=6
      [1 solution]
      

      So the solution to this extra puzzle is with 180 dice (4 columns of 45 dice each), showing 2536 visible spots.

      There are no solutions for 5 dice, at least not reading the numbers on top of the dice as a base 10 number. If we read them as a base 8 number then there are 5 solutions with 5 dice (and 1 with 4 dice, and 4 with 3 dice). (You can try it by adding a [[ --base=8 ]] argument to the commands).

      Like

      • Jim Randell's avatar

        Jim Randell 2:43 pm on 14 March 2019 Permalink | Reply

        Writing:

        (14 × A × B × C) + (A + B + C) = 100 × A + 10 × B + C

        we can simplify this to:

        (99 × A + 9 × B) / (14 × A × B) = C

        So we only needs to consider values of A and B to derive C:

        % python enigma.py SubstitutedExpression --distinct="" --digits="1-6" "div(99 * A + 9 * B, 14 * A * B) = C
        (div(99 * A + 9 * B, 14 * A * B) = C)
        (div(99 * 1 + 9 * 3, 14 * 1 * 3) = 3) / A=1 B=3 C=3
        [1 solution]
        

        The improvement in run time (if any) is negligible.


        However, this gives us a manual way to solve the puzzle.

        C is an integer between 1 and 6, and as the denominator of the expression for C has a divisor of 7 then so must the numerator. In fact it must be the case that 7 divides (11A + B). So for any given value of A there is only a single value for B that is possible, from which we can calculate potential values for C:

        A = 1 → B = 3 → C = 3 (Solution)
        A = 2 → B = 6 → C = 3/2
        A = 3 → B = 2 → C = 15/4
        A = 4 → B = 5 → C = 63/40
        A = 5 → B = 1 → C = 36/5
        A = 6 → B = 4 → C = 15/8

        And only one value for A gives a viable value for C.

        Like

    • GeoffR's avatar

      GeoffR 7:29 pm on 8 August 2019 Permalink | Reply

      For three columns of dice:

      % A Solution in MiniZinc
      include "globals.mzn";
      
      var 1..6: t1; var 1..6: t2; var 1..6: t3;  % top numbers on 3 dice
      var 1..20: n;  % number of dice per column
      
      % total number of visible spots for 3 columns
      constraint 3 * (2 * 7 * n) + t1 + t2 + t3 == 100*t1 + 10*t2 + t3;
      
      % the three numbers from the tops of the three columns mutiplied
      % together give the total number of dice
      constraint t1 * t2 * t3 == 3 * n;
      
      solve satisfy;
      
      output ["Total number of visible spots = " ++ 
      show(3 * (2 * 7 * n) + t1 + t2 + t3)
      ++"\nTotal number of dice = " ++ show(n * 3) ];
      
      % Total number of visible spots = 133
      % Number of dice = 9
      % ----------
      % ==========
      

      For four columns of dice:

      % A Solution in MiniZinc
      include "globals.mzn";
      
      % top numbers on four dice
      var 1..6: t1; var 1..6: t2; var 1..6: t3; var 1..6: t4;
      var 1..75: n;  % number of dice per column
      
      % total number of visible spots for four columns
      constraint 4 * (2 * 7 * n) + t1 + t2 + t3 + t4 
      == 1000*t1 + 100*t2 + 10*t3 + t4;
      
      % the four numbers from the tops of the four columns mutiplied
      % together give total number of dice
      constraint t1 * t2 * t3 * t4 == 4 * n;
      
      solve satisfy;
      
      output ["Total number of visible spots = " ++ 
      show(4 * (2 * 7 * n) + t1 + t2 + t3 + t4)
      ++"\nTotal Number of dice = " ++ show(n * 4)
      ++"\nTop die numbers are " ++ show(t1) ++ ", " ++ show(t2)
      ++ ", " ++ show(t3) ++ " and " ++ show(t4) ];
      
      % Total number of visible spots = 2536
      % Total Number of dice = 180
      % Top die numbers are 2, 5, 3 and 6
      % ----------
      % ==========
      
      

      Like

  • Unknown's avatar

    Jim Randell 7:45 am on 13 March 2019 Permalink | Reply
    Tags:   

    Teaser 2936: Multicoloured 

    From The Sunday Times, 30th December 2018 [link] [link]

    George and Martha are selling wall-paper of various colours. By replacing letters with positive digits, they have devised the following multiplication problem:

    RED × GREY = YELLOW

    The N in GREEN is the remaining positive digit. The red wall-paper is sold only in squares, which is appropriate since RED is a perfect square.

    What is the value of GREEN?

    [teaser2936]

     
    • Jim Randell's avatar

      Jim Randell 7:47 am on 13 March 2019 Permalink | Reply

      We can use the [[ SubstitutedExpression() ]] solver from the enigma.py library to solve the alphametic expressions directly.

      This run-file executes in 119ms.

      Run: [ @repl.it ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      --digits="1-9"
      --answer="GREEN"
      
      "RED * GREY = YELLOW"
      "is_square(RED)"  # optional
      

      Solution: GREEN = 21668.

      The [[ is_square(RED) ]] condition is optional (in that there are no further solutions if it is omitted), but it verifies the statement of the problem, and also allows the run-file to execute a little faster (and is convenient when pursuing a manual solution).

      Like

    • GeoffR's avatar

      GeoffR 12:12 pm on 13 March 2019 Permalink | Reply

      % A solution in MinZinc 
      include "globals.mzn";
      
      var 1..9:R; var 1..9:E; var 1..9:D; var 1..9:G; var 1..9:Y; 
      var 1..9:L; var 1..9:O; var 1..9:W; var 1..9:N; 
      
      constraint all_different([R, E, D, G, Y, L, O, W, N]);
      
      var 100..999: RED = 100*R + 10*E + D;
      var 1000..9999: GREY = 1000*G + 100*R + 10*E + Y;
      var 100000..999999: YELLOW = 100000*Y + 10000*E + 1000*L + 100*L + 10*O + W;
      var 10000..99999: GREEN =10000*G + 1000*R + 110*E + N;
      
      set of int: sq3 = {n*n | n in 10..31};
      constraint RED in sq3;
      
      constraint RED * GREY == YELLOW;
      
      solve satisfy;
      
      output [ "GREEN = " ++ show(GREEN)  ++ "\n"
      ++ show(RED) ++ " X " ++ show(GREY) ++ " = " ++ show(YELLOW)];
      
      % GREEN = 21668
      % 169 X 2163 = 365547
      % time elapsed: 0.02 s
      
      
      

      Like

  • Unknown's avatar

    Jim Randell 6:57 am on 12 March 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 463: Betting prices 

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

    In the third race, the bookmakers’ prices varied considerably and, in some cases, were unusual. At one time or another up to the start of the race, the odds quoted against one or more of the 9 horses were 2 to 1, 3 to 1, 4 to 1, and all other whole numbers to 1, up to and including 28 to 1 (i.e., 27 different prices in all).

    Just before the “off” the Baron saw his chance. The prices then being offered by different bookmakers were such that, by staking a total of less than £100, and placing a whole number of pounds on each of the 9 runners he was able to ensure that, no matter which horse won, he would make an overall profit of exactly £13.

    One horse was clear favourite. The other 8 were “paired” in the betting (i.e., there were 4 pairs, both horses in each pair being at the same price — the 4 prices all being different).

    How much did the Baron stake in all, and what were the 5 prices at which he placed his bets?

    This puzzle is included in the book Sunday Times Brain Teasers (1974).

    [teaser463]

     
    • Jim Randell's avatar

      Jim Randell 6:58 am on 12 March 2019 Permalink | Reply

      This Python program collects together odds and stakes that would give the same winnings, and then looks for a collection of five that would give a profit of £13 as described.

      It runs in 76ms.

      Run: [ @repl.it ]

      from collections import defaultdict
      from itertools import combinations
      from enigma import irange, printf
      
      # record bets = (odds, stake) by winnings
      d = defaultdict(list)
      
      # consider odds of "X to 1"
      for X in irange(2, 28):
        # if x pounds is bet...
        for x in irange(1, 99):
          # winnings are...
          w = x * (X + 1)
          if w < 22: continue
          if w > 112: break
          d[w].append((X, x))
      
      # numbers of bets at lengthening odds
      ns = (1, 2, 2, 2, 2)
      
      # choose a collection of winnings and odds
      for (w, vs) in d.items():
        # choose 5 different odds
        for bets in combinations(vs, len(ns)):
          # check the winnings = stake + profit
          if not (w == sum(n * x for (n, (_, x)) in zip(ns, bets)) + 13): continue
          # output solution
          printf("winnings = {w} -> (odds, stakes) = {bets}")
      

      Solution: The Baron staked bets totalling £71. The bets were placed at odds of: 3-1, 6-1, 13-1, 20-1, 27-1.

      The bets were:

      £21 at 3-1
      £12 at 6-1 [×2]
      £6 at 13-1 [×2]
      £4 at 20-1 [×2]
      £3 at 27-1 [×2]

      Giving a total stake of £71, and a total winnings of £84 should any single bet come in.

      Like

  • Unknown's avatar

    Jim Randell 6:49 am on 11 March 2019 Permalink | Reply
    Tags:   

    Teaser 2937: Long division 

    From The Sunday Times, 6th January 2019 [link] [link]

    I wrote down a 2-digit number and a 5-digit number and then carried out a long division.

    I then erased all of the digits in the calculation, other than the 1’s, and so finished up with the image above.

    If I told you how many different digits I had erased, then you should be able to work out my two original numbers.

    What were my two original numbers?

    [teaser2937]

     
    • Jim Randell's avatar

      Jim Randell 6:52 am on 11 March 2019 Permalink | Reply

      Here’s a solution using the [[ SubstitutedDivision() ]] and [[ filter_unique() ]] functions from the enigma.py library.

      This program runs in 63ms. (Internal runtime is 7.2ms).

      Run: [ @replit ]

      from enigma import (SubstitutedDivision, filter_unique, printf)
      
      # the division sum
      p = SubstitutedDivision(
        "????1 / ?? = 1???",
        [ "?? - ?? = ?1", "?1? - 1?? = ??", "??? - ??? = 11", "111 - 111 = 0" ],
        digits=(0, 2, 3, 4, 5, 6, 7, 8, 9),
        verbose="T",  # show candidate solutions
      )
      
      # find solutions unique by the number of digits involved
      f = lambda s: len(set(s.s.values()))
      g = lambda s: (s.a, s.b)
      ss = filter_unique(p.solve(), f, g).unique
      
      # output solutions
      for s in ss:
        printf("SOLUTION: {s.a} / {s.b} = {s.c} [{n} digits]", n=f(s))
      

      Solution: The two original numbers were 37 and 58571.

      The diagram can describe 3 possible divisions:

      58201 ÷ 37 = 1573
      58571 ÷ 37 = 1583
      58941 ÷ 37 = 1593

      The first and third of these have 8 different digits in the long division sum, the second one uses 9 different digits and so gives the solution.

      Although the puzzle states that the erased digits are not 1 (and the program ensures this), there are no further solutions to the more general problem where the erased digits may be 1. We can see this by adding [[ 1 ]] in the [[ digits ]] specification on line 7 (or just removing that line completely to allow any digit to be used).

      Like

    • GeoffR's avatar

      GeoffR 7:16 pm on 14 March 2019 Permalink | Reply

      This solution found the same three possible solutions

      However, only the solution 58571 / 37 = 1583 had a unique number of digits erased by the setter, as the other two solutions had the same number of digits erased. The two digit number is therefore 37 and the five digit number is 58571.

      % A Solution in MiniZinc
      include "globals.mzn";                   
      
      %        w c d e         1 5 8 3
      %      ---------       ----------    
      %  a b)f g h i w    3 7)5 8 5 7 1
      %      a b              3 7
      %      ---              ---
      %      m 1 h            2 1 5
      %      w p q            1 8 5
      %      -----            -----          
      %        r s i            3 0 7
      %        t u v            2 9 6 
      %        -----            -----   
      %          1 1 1            1 1 1
      %          1 1 1            1 1 1 
      %          =====            =====
                                                                                                                                          
      int: w == 1;
      
      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: m; 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;
       
      constraint a > 0 /\ j > 0 /\ m > 0 /\ r > 0 /\ t > 0;
      
      var 10..99: ab = 10*a + b;
      var 1000..1999: wcde = 1000*1 + c*100 + d*10 + e;
      var 10000..99999: fghiw = 10000*f + 1000*g + 100*h + 10*i + w;
      
      var 10..99: jk = 10*j + k;
      var 100..999: m1h = 100*m + 10^1 + h;
      var 100..199: wpq = 100*1 + 10*p + q;
      var 100..999: rsi = 100*r + 10*s + i;
      var 100..999: tuv = 100*t + 10*u + v;
      
      var 10..99: rs = 10*r + s;
      var 10..99: m1 = 10*m + 1;
      var 10..99: fg = 10*f + g;
      
      constraint ab * wcde == fghiw;
      constraint fg - ab == m1;
      constraint c * ab = wpq /\ m1h - wpq == rs;
      
      constraint d * ab == tuv /\ rsi - tuv == 11;
      constraint e * ab == 111;
      
      % variables used in programme - all erased by setter (but not including w = 1)
      var set of int: s1 = {a, b, c, d, e, f, g, h, i, m, p, q, r, s, t, u, v};  
      
      solve satisfy;
      
      output [ show(fghiw) ++ " / " ++ show (ab) ++ " = " ++ show(wcde) 
      ++ ", digit set used (exc w=1) = " ++ show(s1) ++ "\n"
      ++ "\n[a, b, c, d, e, f, g, h, i, m, p, q, r, s, t, u, v ]  "
      ++ "\n" ++  show ( [a, b, c, d, e, f, g, h, i, m, p, q, r, s, t, u, v ] )];  % excludes w = 1
      
      % 58201 / 37 = 1573, digit set used (exc w=1) = {0,2,3,5,7,8,9}
      % 7 no. digit variables used, not inc 1
      
      % [a, b, c, d, e, f, g, h, i, m, p, q, r, s, t, u, v ]  
      % [3, 7, 5, 7, 3, 5, 8, 2, 0, 2, 8, 5, 2, 7, 2, 5, 9]
      % % time elapsed: 0.02 s
      % ----------
      % 58571 / 37 = 1583, digit set used (exc w=1) = {0,2,3,5,6,7,8,9} - ANSWER
      % 8 no. digit variables used, not inc 1
      
      % [a, b, c, d, e, f, g, h, i, m, p, q, r, s, t, u, v ]  
      % [3, 7, 5, 8, 3, 5, 8, 5, 7, 2, 8, 5, 3, 0, 2, 9, 6]
      % % time elapsed: 0.02 s
      % ----------
      % 58941 / 37 = 1593, digit set used (exc w=1) = {2,3,4,5,7,8,9}
      % 7 no. digit variables used, not inc 1
      
      % [a, b, c, d, e, f, g, h, i, m, p, q, r, s, t, u, v ]  
      % [3, 7, 5, 9, 3, 5, 8, 9, 4, 2, 8, 5, 3, 4, 3, 3, 3]
      % % time elapsed: 0.02 s
      % ----------
      % ==========
      % Finished in 232msec
      
      
      

      Like

    • elbaz haviv's avatar

      elbaz haviv 1:10 pm on 30 August 2023 Permalink | Reply

      1593 x 37 and 1573 x 37 also fit the puzzle

      Like

      • Jim Randell's avatar

        Jim Randell 1:35 pm on 30 August 2023 Permalink | Reply

        As noted above these 2 candidate solutions are eliminated as they both have 7 different digits erased. The remaining candidate has 8 different erased digits, and so provides the required answer to the puzzle.

        Like

    • elbaz haviv's avatar

      elbaz haviv 4:18 pm on 30 August 2023 Permalink | Reply

      ok later I noticed that but I don’t find
      an edit future to correct my self.
      anyway Thank you.

      Like

  • Unknown's avatar

    Jim Randell 12:16 am on 10 March 2019 Permalink | Reply
    Tags:   

    Teaser 2946: Pentagonal gardens 

    From The Sunday Times, 10th March 2019 [link] [link]

    Adam and Eve have convex pentagonal gardens consisting of a square lawn and paving. Both gardens have more than one right-angled corner. All the sides of the gardens and lawns are the same whole number length in metres, but Adam’s garden has a larger total area. Eve has worked out that the difference in the areas of the gardens multiplied by the sum of the paved areas (both in square metres) is a five-digit number with five different digits.

    What is that number?

    [teaser2946]

     
    • Jim Randell's avatar

      Jim Randell 1:16 am on 10 March 2019 Permalink | Reply

      If I’ve understood this correctly there are only two ways to construct the gardens, and this gives a fairly limited set of integer sides. And only one of those gives a viable 5-digit number.

      I worked out 2 possible shapes for the gardens, where the lawn forms most of the perimeter:

      To make calculating the area easier I have split the lawn of A’s garden in two and inserted the paved area between. The areas are the same as if the lawn was a contiguous square.

      If we suppose the line segments making up the perimeter of the gardens are units, then both squares are unit squares and both triangles have a base of length 1.

      A’s triangle has a height of √(7)/2 and an area of √(7)/4. E’s triangle has a height of √(3)/2 and an area of √(3)/4.

      The difference in the total areas of the gardens is:

      (1 + √(7)/4) − (1 + √(3)/4) = (√7 − √3) / 4

      The sum of the paved areas is:

      √(7)/4 + √(3)/4 = (√7 + √3) / 4

      Multiplying these together we get:

      (√7 + √3) × (√7 − √3) / (4 × 4) = 1 / 4

      So, if the gardens were all of side x, the number N would be:

      N = (x^4) / 4

      For a 5-digit value for N there are only a few values of x to try, and this can be completed manually or programatically.

      This Python program runs in 77ms.

      Run: [ @repl.it ]

      from enigma import (irange, div, is_duplicate, printf)
      
      # consider 5 digit values for N
      for x in irange.round(pow(4 * 10000, 0.25), pow(4 * 99999, 0.25)):
        N = div(pow(x, 4), 4)
        if N is None or is_duplicate(N): continue
        # output solution
        printf("x={x} N={N}")
      

      Solution: The number is 16384.

      Like

      • Jim Randell's avatar

        Jim Randell 8:55 am on 10 March 2019 Permalink | Reply

        I’m pretty sure these are the only two possible shapes.

        If you imagine trying to form a set of 5 equal length linked rods into a convex pentagon with more than one right angle, then it is not possible with 3 right angles, so there must be exactly 2 right angles. And these are either on adjacent vertices or have one vertex between them.

        Either way, the remaining rods are forced into unique positions, giving the shapes A and E.

        Although note that with A there are many ways that a unit square can fit inside the pentagon (not necessarily touching the perimeter).

        Like

  • Unknown's avatar

    Jim Randell 9:30 am on 9 March 2019 Permalink | Reply
    Tags: by: T Verschoyle,   

    Brain-Teaser 462: [Crocodiles] 

    From The Sunday Times, 5th April 1970 [link]

    A friend of mine, who is headmistress of a small school, sends her fifteen girls for a walk every day in a crocodile of threes. She told me that she had for long been trying, unsuccessfully, to arrange that no two girls ever walked together in a trio more than once during a whole week; and she added that, denoting the girls by the first fifteen letters of the alphabet, she wanted A to walk with B and C on Sunday, and with the consecutive pairs of letters for the rest of the week, finishing with N and O on Saturday.

    “Well”, I replied, “if four more trios were specified, I could find a unique solution for your problem. But, if you want to work it out yourself, I shall help you by telling you B’s and C’s partners throughout the week:

    Mon: BHJ, CMN
    Tue: BIK, CLO
    Wed: BLN, CEF
    Thu: BMO, CDG
    Fri: BDF, CIJ
    Sat: BEG, CHK

    Furthermore, F, who is a bit of a snob as regards those lower in the alphabetical order, will be relieved to find that she does not have to walk with the two available furthest from herself in that order until Saturday.

    Now, you should be able to tell me with whom D walks on Sunday and on Wednesday.”

    This puzzle was originally published with no title.

    [teaser462]

     
    • Jim Randell's avatar

      Jim Randell 9:31 am on 9 March 2019 Permalink | Reply

      I’ve marked this puzzle as flawed for two reasons. Firstly when the solution was published it was acknowledged that there was not a unique answer, and secondly I’m not really sure that the constraint about F makes sense.

      My first thought was that it means that F partnered N and O (the two furthest along from F alphabetically) on Saturday, but N and O are already partnering A on Saturday. It does say the “two available furthest from herself”, so perhaps it means F partners L and M (the next furthest alphabetically), but L and M were partnering A on Friday, so can’t appear in a grouping on Saturday. In fact, according to the information we are given, the groups: ANO, BEG, CHK are already defined for Saturday, leaving DFIJLM, to be formed into viable groups. So maybe we are meant to partner F with J and M. This is the interpretation I ended up using, and it does generate the published answer(s). But I think there is still a problem (see below).

      This Python 3 program solves the puzzle recursively in 865ms.

      Run: [ @repl.it ]

      from itertools import combinations
      from enigma import unpack, partitions, join, update, flatten, printf
      
      # check no pairs are repeated
      def pairs(ps, ts):
        ps = ps.copy()
        for t in ts:
          for p in combinations(t, 2):
            if p in ps: return None
            ps.add(p)
        return ps
      
      # complete the groups, with pairs ps already used
      def solve(groups, ps):
        # find days with missing groups
        gs = list((k, vs) for (k, vs) in groups.items() if len(vs) < 5)
        if not gs:
          yield groups
        else:
          # choose the day with the fewest missing groups
          (k, vs) = min(gs, key=unpack(lambda k, vs: 5 - len(vs)))
          # form the remaining kids into groups
          for ts in partitions(kids.difference(*vs), 3):
            ts = list(join(sorted(t)) for t in ts)
            ps2 = pairs(ps, ts)
            if ps2:
              yield from solve(update(groups, [(k, sorted(vs + ts))]), ps2)
      
      # the kids
      kids = set("ABCDEFGHIJKLMNO")
      
      # the groupings we are given
      groups = dict(
        Sun=["ABC"],
        Mon=["ADE", "BHJ", "CMN"],
        Tue=["AFG", "BIK", "CLO"],
        Wed=["AHI", "BLN", "CEF"],
        Thu=["AJK", "BMO", "CDG"],
        Fri=["ALM", "BDF", "CIJ"],
        Sat=["ANO", "BEG", "CHK", "FJM"],
      )
      
      # check no pairing is duplicated among the given groups
      ps = pairs(set(), flatten(groups.values()))
      assert ps
      
      # solve for the remaining groups
      for gs in solve(groups, ps):
        # find the group on day d for child x
        get = lambda d, x: list(t for t in gs[d] if x in t)[0]
        # a measure for F's partners
        fn = lambda d: sum(int(x, 25) - 9 for x in get(d, 'F') if x != 'F')
        # output the groups
        for (k, vs) in gs.items():
          printf("{k}: {vs} [{m}]", vs=join(vs, sep=" "), m=fn(k))
        # D's groups on Sun and Wed
        printf("[D] Sun={S} Wed={W}", S=get("Sun", 'D'), W=get("Wed", 'D'))
        printf()
      

      Solution: There are two possible solutions: (1) D partners H and O on Sunday, and K and M on Wednesday; (2) D partners K and N on Sunday, and J and O on Wednesday.

      The full groupings look like this:

      Sun: ABC DHO EJL FKN GIM
      Mon: ADE BHJ CMN FIO GKL
      Tue: AFG BIK CLO DJN EHM
      Wed: AHI BLN CEF DKM GJO
      Thu: AJK BMO CDG EIN FHL
      Fri: ALM BDF CIJ EKO GHN
      Sat: ANO BEG CHK DIL FJM

      Sun: ABC DKN EIM FHO GJL
      Mon: ADE BHJ CMN FKL GIO
      Tue: AFG BIK CLO DHM EJN
      Wed: AHI BLN CEF DJO GKM
      Thu: AJK BMO CDG EHL FIN
      Fri: ALM BDF CIJ EKO GHN
      Sat: ANO BEG CHK DIL FJM

      And now we run into the problem with F, their “worst” day is suppose to be Saturday, when they partner J and M.

      But in the first case, F partners K and N on Sunday, each of these is one step further along the alphabet than Saturday’s partners, so is surely a less desirable situation. If we just sum the positions in the alphabet of her partners to get a measure of “badness”, the partnering I and O on Monday is also less desirable than Saturday.

      Using the same measure we find that in the second case, Sunday, Monday and Thursday all score as badly as Saturday for F.

      And if we use other measures (e.g. looking for the “best” of the two partners, or the “worst”) we find that in neither of these scenarios does Saturday does provide F with their worst partnering of the week.

      Further, if we consider all possible pairings for F on Saturday (and not a specific one) we find it is not possible to solve the puzzle so F has her worst day on Saturday.

      So maybe it would have just been better to say: “F doesn’t get on with her sisters, J and M. So she will be relieved to find she does not have to walk with them until Saturday”. Or just come straight out with it: “F walked with J and M on Saturday”. But that still leaves the problem of the two answers. Although an extra condition disallowing one of the groupings in one of the answers would sort that out.

      Like

  • Unknown's avatar

    Jim Randell 8:06 am on 8 March 2019 Permalink | Reply
    Tags: ,   

    Teaser 2938: Numerophobia 

    From The Sunday Times, 13th January 2019 [link] [link]

    In Letterland there are no numerals. They use the decimal system of counting just like we do but the digits 0-9 are represented by the first ten letters of the alphabet AJ inclusive but in no particular order. The following calculations are typical:

    A + G = C
    B × J = FH
    GE × AI = HDB

    What number is represented by ABCDEFGHIJ?

    As stated this puzzle does not have a unique solution.

    This puzzle was not included in the book The Sunday Times Teasers Book 1 (2021).

    [teaser2938]

     
    • Jim Randell's avatar

      Jim Randell 8:07 am on 8 March 2019 Permalink | Reply

      We can feed the alphametic expressions directly to the [[ SubstitutedExpression() ]] solver from the enigma.py library.

      This run-file executes in 125ms.

      Run: [ @replit ]

      #! python3 -m enigma -rr
      
      SubstitutedExpression
      
      --answer="ABCDEFGHIJ"
      
      "A + G = C"
      "B * J = FH"
      "GE * AI = HDB"
      

      Solution: There are two solutions: ABCDEFGHIJ = 1840253697, and ABCDEFGHIJ = 3840951627.

      The two solutions arise as we can swap the values of (A, E) with (G, I). One of them is (1, 2) and the other is (3, 9).

      Apparently the setter was unaware that there were two solutions, which seems a bit odd as this kind of puzzle can very easily be checked. For example my own alphametic solver is available here [ https://repl.it/@jim_r/alphametic ]. Click “Run”, enter the expressions, and you get the two solutions straight away. [Note: As of 2024 code sharing via replit no longer works].

      Here’s an example transcript:

      Python 3.6.1 (default, Dec 2015, 13:05:11)
      [GCC 4.8.2] on linux
      expr[0] (or enter) >>> A + G = C
      expr[1] (or enter) >>> B * J = FH
      expr[2] (or enter) >>> GE * AI = HDB
      expr[3] (or enter) >>>
      (A + G = C) (B * J = FH) (GE * AI = HDB)
      (1 + 3 = 4) (8 * 7 = 56) (32 * 19 = 608) / A=1 B=8 C=4 D=0 E=2 F=5 G=3 H=6 I=9 J=7
      (3 + 1 = 4) (8 * 7 = 56) (19 * 32 = 608) / A=3 B=8 C=4 D=0 E=9 F=5 G=1 H=6 I=2 J=7
      [2 solutions]
      [timing] elapsed time: 0.0016964s (1.70ms)
      

      The published solution is:

      Teaser 2938
      There were two possible correct answers: 1840253697 or 3840951627.
      We apologise for any confusion.

      Like

    • GeoffR's avatar

      GeoffR 1:20 pm on 8 March 2019 Permalink | Reply

      % A solution in MinZinc 
      include "globals.mzn";
      
      var 0..9: A; var 0..9: B; var 0..9: C; var 0..9: D; var 0..9: E;
      var 0..9: F; var 0..9: G; var 0..9: H; var 0..9: I; var 0..9: J;
      
      constraint A != 0 /\ G != 0 /\ C != 0 /\ B != 0 
      /\ J != 0 /\ F != 0 /\ H != 0;
      
      constraint all_different ( [A,B,C,D,E,F,G,H,I,J] );
      
      var 10..99: FH = 10*F + H;
      var 10..99: GE = 10*G + E;
      var 10..99: AI = 10*A + I;
      var 100..999: HDB = 100*H + 10*D + B;
      
      constraint A + G == C;
      constraint B * J == FH;
      constraint GE * AI = HDB;
      
      solve satisfy;
      
      output [ "ABCDEFGHIJ = " ++ show(A),show(B),show(C),show(D),show(E),
      show(F),show(G),show(H),show(I),show(J) ];
      
      % ABCDEFGHIJ = 3840951627
      % ABCDEFGHIJ = 1840253697
      
      

      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