Recent Updates Page 64 Toggle Comment Threads | Keyboard Shortcuts

  • Unknown's avatar

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

    Brain-Teaser 473: Gouttes d’Or 

    From The Sunday Times, 21st June 1970 [link]

    The conical glasses at the Hôtel d’Or hold one eighth of a litre and are embellished from base to brim with a picture of Bacchus. In making the hotel’s famous Gouttes d’Or, sold at NF 5.20, it was customary to fill the glass up to Bacchus’ neck (4/5th of the way up the glass) and then add an olive; the profit on raw materials was a modest 100 per cent.

    Gaston, the barman, has decided that he must make the more realistic profit of 400 per cent. So now the olive is put in first and then liquor is added up to the level of Bacchus’ chest (3/5ths of the way up the glass). The price has been reduced to NF 4.80.

    Gaston explained: “Ze olives are standard sized and cost me one centime a cc. Yes, I could put in ze olive after measuring out the liquid — but zen it would be necessary to charge …”

    How much?

    This is a corrected version of the originally published puzzle. In the original version the price of the first glass was incorrectly given as NF 5.30 (instead of NF 5.20). The puzzle can still be solved in the same way, but the numbers don’t work out as nicely.

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

    [teaser473]

     
    • Jim Randell's avatar

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

      If the conical glass has a height of h and a radius (at the top) of r, then a completely full glass will have a volume of:

      𝛑 r² h / 3 = 125

      So, if it was filled to a height of (k/5) h (and hence a radius of (k/5) r, then the volume of liquid is:

      𝛑 (kr/5)² (kh/5) / 3 = (k/5)³ 125 = k³

      So a 4/5 full glass contains 64 cc, and a 3/5 full glass 27 cc.

      If olives have a volume of x cc (and cost 1 centime per cc) and the liquor has a cost of y centimes per cc, and the profit is 100% (i.e. the cost of the drink is twice the cost of the raw materials), then for the first glass we have:

      520 = 2(x + 64y)
      260 = x + 64y

      And for the second glass we have a 400% profit (i.e. the cost of the drink is 5 times the cost of the raw materials), on a drink with the olive added before the liquor we have:

      480 = 5(x + (27 − x)y)
      96 = x + 27y − xy

      (assuming the olive is submerged, and so displaces its own volume of liquid).

      These two equations have a reasonable solution at x = 4, y = 4. (And an unreasonable solution where x = 219, which is a very large olive, and wouldn’t fit in the glass).

      So the cost of a 3/5 glass, if the olive was added last, and the profit multiple is 5, would be:

      5(x + 27y) = 560

      Solution: The drink would cost NF 5.60.

      Here is a Python program that solves the puzzle numerically. It runs in 81ms.

      from enigma import (Polynomial, fdiv, find_zero, printf)
      
      # for a 4/5 full glass, with olive added last, the cost is k1, profit multiple is m1
      # for a 3/5 full glass, with olive added first, the cost is k2, profile multiple is m2
      # return (<olive volume>, <liquor cost>, <answer>)
      def solve(k1, m1, k2, m2):
      
        # volumes for a 4/5 and 3/5 glass
        (v4, v3) = (4**3, 3**3)
      
        # create a polynomial that gives the cost of liquor in terms of the volume of an olive
        # using the first equation:
        # k1 = m1 * (x + v4 * y)
        q = Polynomial([fdiv(k1, m1 * v4), fdiv(-1, v4)])
      
        # create the polynomial whose roots are the volume of an olive
        # using the second equation:
        # k2 = m2 * (x + (v3 - x) * y)
        p = q * Polynomial([v3, -1]) - Polynomial([fdiv(k2, m2), -1])
      
        # find a solution with a reasonably sized olive
        r =  find_zero(p, 0, 10)
        x = r.v
        y = q(x)
        # cost of a 3/5 glass, with an olive last, profit multiple m2
        k = m2 * (x + v3 * y)
        return (k, x, y)
      
      # solve for the required amounts
      (k, x, y) = solve(520, 2, 480, 5)
      
      printf("cost = NF {f:.02f} [x = {x:.02f}, y = {y:.02f}]", f=0.01 * k)
      

      If we change the first argument to [[ solve() ]] on line 30 to 530 we get the solution to the puzzle as originally set: approximately NF 5.72.

      Like

  • Unknown's avatar

    Jim Randell 8:05 am on 15 April 2019 Permalink | Reply
    Tags:   

    Teaser 2924: Snaking up 

    From The Sunday Times, 7th October 2018 [link] [link]

    A “Snakes and Ladders” board consists of a 10-by-10 grid of squares. In the first row (at the bottom) the squares are numbered from 1 to 10 from left to right, in the second row the squares are numbered 11 to 20 from right to left, in the third they are 21 to 30 from left to right again, and so on.

    An ant started on square 1, moved to square 2 and then, always moving to an adjacent square to the right or up, it finished in the top-right corner of the board. I have added up the total of the numbers on the squares it used and, appropriately, the total is a perfect square. In fact it is the square of one of the numbers the ant visited — the ant passed straight through it without turning.

    What was that total of the numbers used?

    [teaser2924]

     
    • Jim Randell's avatar

      Jim Randell 8:05 am on 15 April 2019 Permalink | Reply

      The ant makes 18 moves (9 across and 9 up). So we can make a path by choosing which of the 18 moves is an “up”, and the rest are all “across”.

      This Python program runs in 260ms.

      Run: [ @repl.it ]

      from enigma import (irange, subsets, is_square, find, printf)
      
      # construct the board
      b = list(irange(1, 100))
      for i in irange(10, 90, step=20):
        b[i: i + 10] = b[i + 9: i - 1: -1]
      
      # the ant makes 18 moves, 9 across (+1) and 9 up (+10)
      # so choose the up moves (move 0 is always across)
      for s in subsets(irange(1, 17), size=9):
        # construct the path
        p = 0
        path = [b[p]]
        for i in irange(0, 17):
          p += (10 if i in s else 1)
          path.append(b[p])
      
        # sum of the squares on the path is a perfect square...
        t = sum(path)
        r = is_square(t)
        if r is None: continue
        # ... of a number that is on the path
        i = find(path, r)
        if not (0 < i < 17): continue
        
        # the ant passes through the square without changing direction
        if (i - 1 in s) != (i in s): continue
      
        # output solution
        printf("sum = {t} (= {r}^2) {path}")
      

      Solution: The total of the numbers on the squares that the ant travelled through is 676.

      And: 676 = 26^2.

      There are three possible paths:

      (1, 2, 3, 18, 17, 16, 25, 26, 27, 28, 29, 30, 31, 50, 51, 70, 71, 90, 91)
      (1, 2, 3, 4, 17, 24, 25, 26, 27, 28, 33, 32, 31, 50, 51, 70, 71, 90, 91)
      (1, 2, 3, 4, 5, 16, 25, 26, 27, 28, 33, 32, 49, 52, 51, 70, 71, 90, 91)

      Like

  • Unknown's avatar

    Jim Randell 11:46 am on 14 April 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 472: [Marital law] 

    From The Sunday Times, 14th June 1970 [link]

    The monogamous and aptly named state of Swindlonabad has a number of inflexible marital laws, these being that:

    (a) Each male citizen must marry on his 21st birthday.

    (b) Each married man must contribute on his wedding day and each subsequent birthday to an Inheritance Trust which must be maintained at exactly the number of shekels equal to the square of the number of years he has lived.

    (c) When an individual’s trust fund can be precisely divided among all his legitimate unmarried sons, each son receiving a number of shekels equal to the square of that son’s age, the father retires and he and his family are maintained by the state.

    Now Abdul the Prolific fathered a child during each year of his married life, and all of these children survived to attend his retirement revels. Although only two of his many children were girls, he complained bitterly that such a misfortune should overtake him twice in a decade. At the time of his retirement only one of his daughters was under the age of ten.

    How old were the two daughters at that time?

    This puzzle was originally published with no title.

    [teaser472]

     
    • Jim Randell's avatar

      Jim Randell 11:46 am on 14 April 2019 Permalink | Reply

      Let’s consider the situation where Abdul is married for 21 years or more (i.e. his age is at least 42).

      Children over 20 have no claim on the trust fund, so he will have children with ages, 0, 1, 2, 3, …, 20. But two of them are girls, one of which is under 10, and the other is up to 10 years older than that, and they will have no claim.

      This Python program runs in 80ms.

      Run: [ @repl.it ]

      from enigma import irange, is_square, printf
      
      # total amount for children from 0 to 20 if they each have a claim
      T = sum(i * i for i in irange(0, 20))
      
      # consider the age of one of the daughters (less than 10)
      for a in irange(0, 9):
        # and the age of the older dauger (10 or more, and within 10 years)
        for b in irange(10, a + 10):
          # does this give a viable amount in the fund?
          A = is_square(T - a * a - b * b)
          if A is None or A < 42: continue
          # output solution
          printf("a={a} b={b} A={A}")
      

      Solution: The daughters were 9 and 17.

      Abdul retired on his 50th birthday, so his trust fund was 2500 shekels.

      He also had 29 children, one born every year from his 21st year to his 49th year.

      So the children’s ages range from 0 to 28. The daughters are aged 9 and 17, and only those sons aged less than 21 have a claim on the fund.

      And we can verify that the total claim is the same as the amount in the trust fund:

      >>> sum(i * i for i in diff(irange(0, 20), [9, 17]))
      2500
      

      The following code shows the total amount in the trust fund, the ages of the claimants and the total claim on the fund on each of Abdul’s birthdays from 21 to 50:

      from itertools import count
      from enigma import printf
      
      # record the ages of the sons
      sons = []
      
      # consider Abdul's age
      for A in count(21):
        # the total amount in the fund
        fund = A * A
      
        # count the total claim on the fund
        claim = sum(x * x for x in sons)
      
        printf("A={A}: fund={fund}, sons={sons}, claim={claim}")
        if claim == fund: break
      
        # increase the ages of the sons
        sons = list(x + 1 for x in sons if x < 20)
      
        # and each year a child is born
        # but at age 32 and 40 these are daughters
        if A not in (32, 40): sons.insert(0, 0)
      

      Which gives the following output:

      A=21: fund=441, sons=[], claim=0
      A=22: fund=484, sons=[0], claim=0
      A=23: fund=529, sons=[0, 1], claim=1
      A=24: fund=576, sons=[0, 1, 2], claim=5
      A=25: fund=625, sons=[0, 1, 2, 3], claim=14
      A=26: fund=676, sons=[0, 1, 2, 3, 4], claim=30
      A=27: fund=729, sons=[0, 1, 2, 3, 4, 5], claim=55
      A=28: fund=784, sons=[0, 1, 2, 3, 4, 5, 6], claim=91
      A=29: fund=841, sons=[0, 1, 2, 3, 4, 5, 6, 7], claim=140
      A=30: fund=900, sons=[0, 1, 2, 3, 4, 5, 6, 7, 8], claim=204
      A=31: fund=961, sons=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], claim=285
      A=32: fund=1024, sons=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], claim=385
      A=33: fund=1089, sons=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], claim=506
      A=34: fund=1156, sons=[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], claim=649
      A=35: fund=1225, sons=[0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], claim=815
      A=36: fund=1296, sons=[0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14], claim=1006
      A=37: fund=1369, sons=[0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], claim=1224
      A=38: fund=1444, sons=[0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], claim=1471
      A=39: fund=1521, sons=[0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], claim=1749
      A=40: fund=1600, sons=[0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18], claim=2060
      A=41: fund=1681, sons=[1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], claim=2406
      A=42: fund=1764, sons=[0, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], claim=2788
      A=43: fund=1849, sons=[0, 1, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], claim=2766
      A=44: fund=1936, sons=[0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20], claim=2740
      A=45: fund=2025, sons=[0, 1, 2, 3, 5, 6, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20], claim=2710
      A=46: fund=2116, sons=[0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20], claim=2676
      A=47: fund=2209, sons=[0, 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 15, 16, 17, 18, 19, 20], claim=2638
      A=48: fund=2304, sons=[0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20], claim=2596
      A=49: fund=2401, sons=[0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, 20], claim=2550
      A=50: fund=2500, sons=[0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20], claim=2500
      

      and here it is as a graph:

      Like

  • Unknown's avatar

    Jim Randell 12:47 pm on 13 April 2019 Permalink | Reply
    Tags: by: D W Pye   

    Brain-Teaser 471: [Flower beds] 

    From The Sunday Times, 7th June 1970 [link]

    Plott was showing Green his garden. “A fine lawn”, commented Green. “Thank you. It’s remarkable, too. The sides run exactly north-south and east-west.”

    They strolled to a flower bed cut in the lawn. “When I came here”, said Plott, “there was just a triangle. One side, of 15 feet, was parallel to the north side of the lawn, and from its western end the second side rand due south for 22 feet. Rather a miserable affair. So I constructed these squares outwards from two sides; the north edge of the small square ran exactly along the north side of the lawn, while one corner of the large square just touched the east side of the lawn — where the flagpole now stands. But I want to enlarge it again”.

    “If I might make a suggestion”, replied Green, “you could join up the outside corners of the squares and give the bed a nice five-sided outline”. Plott thought this a good idea.

    Next day he ran a line from the flagpole to the north-east corner of the small square, and then worked on the triangle formed by this line, to east side of the small square and the side of the large square running from the small square to the flagpole.

    How many square feet were in this new piece?

    This puzzle was originally published with no title.

    [teaser471]

     
    • Jim Randell's avatar

      Jim Randell 12:48 pm on 13 April 2019 Permalink | Reply

      This is mostly an exercise in following the instructions to draw the following diagram:

      Red line segments are 15 ft, green line segments 22 ft, and blue line segments √(709) ft (but we don’t need to know that).

      We start with the right-angled triangle with red, green, blue sides on the left, and then add the red and blue squares. This lets us construct the desired (yellow shaded) triangle, which we see has a red N-S “base” of 15 ft, and by placing a second red, green, blue triangle within the blue square, we see the desired triangle has a green W-E “height” of 22ft. So it has the same area as the original triangle.

      Solution: The area of the triangle is 165 sq. ft.

      Like

  • Unknown's avatar

    Jim Randell 11:29 pm on 11 April 2019 Permalink | Reply
    Tags:   

    Teaser 2951: Imprismed 

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

    A right regular prism has two ends with identical faces, joined by oblong rectangular faces. I have eight of them, with regular convex polygonal end-faces of 3, 4, 5, 6, 7, 8, 9 and 10 sides (triangle, square and so on). They sit on my flat desk (on oblong faces), and each prism has the same height.

    I chose three prisms at random, and was able to slide them into contact, broadside, in such a way that the middle one overhung both others (and could be lifted without disturbing them). Also, I was able to slide one outer prism to the other side, and the new “middle” prism was overhung by both others (and so vertically “imprisoned” by them).

    I was able to do all this again with three randomly chosen remaining prisms.

    Give the prior chance of this double selection (as a fraction in lowest terms).

    This puzzle appears in the books The Sunday Times Brain Teasers 1 (2019) and The Sunday Times Teasers Book 1 (2021).

    [teaser2951]

     
    • Jim Randell's avatar

      Jim Randell 11:30 pm on 11 April 2019 Permalink | Reply

      I’m not a great fan of this kind of puzzle. Partly because I don’t like probability much, but also because it is not easy to check that the answer you get works.

      I also think the wording for this particular puzzle could have been clearer. I started out with an incorrect interpretation, and got a different answer. If we consider the selection of an appropriate “special” set of three prisms (that can be arranged in the manner described in the puzzle text), then I think the puzzle is asking for the probability of selecting two consecutive “special” sets from the 8 prisms.

      Here is a Python program which works out the solution in 75ms.

      Run: [ @replit ]

      from enigma import (subsets, diff, ordered, fraction, printf)
      
      # prisms that project over another prism when placed side by side
      overhangs = {
        3: [],
        4: [],
        5: [3, 6, 7, 9, 10],
        6: [3, 7],
        7: [3],
        8: [3],
        9: [3, 6, 7, 10],
        10: [3, 7],
      }
      
      # over(x, y) = "x goes over y"
      over = lambda x, y: y in overhangs[x]
      
      # possible prisms
      prisms = sorted(overhangs.keys())
      
      # record special choices
      special = set()
      
      # choose the central prism
      for x in prisms:
        # and choose a left and right prism that are overhung by x
        for (l, r) in subsets(overhangs[x], size=2):
          # check there is a rearrangement that traps the new centre prism
          if over(l, r) or over(r, l):
            special.add(ordered(x, l, r))
      
      printf("{n} special sets", n=len(special))
      
      
      # record the total number of choices, and the number of that give two special sets
      t = n = 0
      
      # choose the first set of 3 prisms
      for s1 in subsets(prisms, size=3):
        # is it a special set?
        p1 = (ordered(*s1) in special)
      
        # choose the second set of 3 prisms
        for s2 in subsets(diff(prisms, s1), size=3):
          # is it a special set?
          p2 = (ordered(*s2) in special)
          if p1 and p2: n += 1
          t += 1
      
      # output the solution
      (a, b) = fraction(n, t)
      printf("chance = {n} / {t} = {a} / {b}")
      

      Solution: The probability of choosing two “special” sets is 3 / 140.


      Here is my analytical solution:

      There are 12 “special” arrangements (centre; outside) that allow a further “special” arrangement to be made from the remaining prisms. They group into 6 sets of mutually distinct pairs:

      (5; 3, 6) ↔ (9; 7, 10)
      (5; 3, 10) ↔ (9; 6, 7)
      (5; 6, 7) ↔ (9; 3, 10)
      (5; 6, 9) ↔ (10; 3, 7)
      (5; 7, 10) ↔ (9; 3, 6)
      (5; 9, 10) ↔ (6; 3, 7)

      There are also 4 “special” arrangements that do not allow a further “special” arrangement to be made:

      (5; 3, 7)
      (5; 3, 9)
      (5; 7, 9)
      (9; 3, 7)

      For the first choice of prisms there are C(8, 3) = 56 possible arrangements, and we must choose one of the arrangements that is part of a “special” pair.

      So, there is a probability of 12 / 56 = 3 / 14 of choosing a suitable first set of prisms.

      For the second choice there are C(8 − 3, 3) = 10 possible arrangements, but only one of these arrangements will be “special” – the arrangement that goes with the first choice to make one of the six “special” pairs given above.

      So overall probability of choosing two suitable sets is (3 / 14) × (1 / 10) = 3 / 140.

      Like

    • Robert Brown's avatar

      Robert Brown 7:44 am on 20 April 2019 Permalink | Reply

      Have you seen John Crabtree’s simple method? I’m also unhappy with probabilities, but wrote a simple program to count how many ways you can select 6 prisms from 8, and how many of these meet his algorithm. The ratio of these 2 numbers confirms the probability.

      Like

      • Jim Randell's avatar

        Jim Randell 2:39 pm on 20 April 2019 Permalink | Reply

        @Robert: Thanks for your comment.

        I try to provide a constructive solution where possible, so constructing the “special” sets, and then counting the number of desired outcomes from all possible outcomes seemed like the best way to understand the solution (and would be the approach least likely to contain a mistake). But it is good that other approaches are able to confirm the answer.

        For me the more difficult part was firstly interpreting what the puzzle was actually asking, and then constructing the “over” relation (to determine when one prism goes over another). Once that was done, counting the possibilities to come up with an answer was the easier part.

        I have got a manual approach to calculating the answer using probabilities, which I intend to post tomorrow along with the answer.

        I did also write code to run a million random trials in selecting six of the prisms to confirm the number I found (see the [[ teaser2951t.py ]] file on @replit).

        Like

    • Robert Brown's avatar

      Robert Brown 11:42 am on 22 April 2019 Permalink | Reply

      Jim
      I wasn’t being critical of your method, which corresponds to that used by the various people who solved it manually. Just drawing your attention to John’s clever method, which doesn’t use any lists – just a couple of rules. Rule one – 6 random selections don’t include 4 or 8 (probability 1/28) Rule 2 – dividing the 6 into 1st 3, then 2nd 3, prisms 6 & 10 must not be in the same group (probability 3/5).

      Like

      • Jim Randell's avatar

        Jim Randell 2:00 pm on 22 April 2019 Permalink | Reply

        It’s certainly neat. I suppose the issue I have is the need to demonstrate that the two rules generate exactly all possible pairs of “special” sets.

        Like

    • Robert Brown's avatar

      Robert Brown 7:42 am on 23 April 2019 Permalink | Reply

      After Rule 1, abc & def must use all of the other 6. Then after Rule 2 every pair within abc or def has one member overhanging the other.

      Like

  • Unknown's avatar

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

    Brain-Teaser 470: Jacob’s ladder 

    From The Sunday Times, 31st May 1970 [link]

    Joseph’s garage, built at ground level on to the side wall of his house, had uniform external dimensions of (exactly) 10 ft. high by 10 ft. wide.

    Wishing to paint from the outside a top-floor window-frame over the garage, he positioned his longest ladder (whose length was over 30 ft.) with its foot on the ground at such a distance from the garage that its top rested against the house wall at the maximum height possible.

    Discovering, however, that despite this he could not reach up to the window, he borrowed his neighbour Jacob’s ladder and, positioning it similarly, found that he could now reach comfortably.

    With either ladder the length, distance and height referred to were all integral numbers of inches.

    How much longer was Jacob’s ladder than Joseph’s, and how much higher on the wall did it reach?

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

    [teaser470]

     
    • Jim Randell's avatar

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

      For a ladder of length k, the maximum height we could achieve would be k, if we laid it flat against the wall, but we can’t do that because there is a garage in the way. If we position it at some distance away from the garage, so that it reaches over the garage we find that as we move the foot of the ladder towards the garage the other end will reach higher up the wall, until the garage gets in our way.

      If the foot of the ladder is at a distance d from the wall, and a height h up the wall, and touches the garage at a point 120 inches from the wall and 120 inches above the ground, then:

      h = 120d / (d − 120)

      and the length of the ladder k is given by:

      k = √(d² + h²)

      This program increases d (in inches from 120) looking for integer heights with integer length ladders.

      Run: [ @repl.it ]

      from enigma import (irange, is_square, printf)
      
      # consider increasing values for d > 120
      for d in irange(121, 240):
      
        # calculate the corresponding height h
        (h, r) = divmod(120 * d, d - 120)
        if r != 0: continue
      
        # calculate the length of the ladder
        k = is_square(d * d + h * h)
        if k is None: continue
        # ladder must be longer than 30 ft
        if not (k > 360): continue
      
        printf("ladder length = {k}, distance = {d}, height = {h}")
      

      Solution: Jacob’s ladder was 4 ft. 3 in. longer than Joseph’s, and reached 5 ft. 3 in. higher.

      In the diagram:

      Jacob’s ladder (blue) is 442 inches long (= 36 ft. 10 in.), and reaches a height of 408 inches (= 34 ft.) on the wall.

      Joseph’s ladder (red) is 391 inches long (= 32 ft. 7 in.) and reaches a height of 345 inches (= 28 ft. 9 in.) on the wall.

      There is a further possible ladder (green) which is 350 inches (= 29 ft. 2 in.) and would reach a height of 280 inches (= 23 ft. 4 in.) on the wall, but this ladder is not longer than 30 ft.

      We can also swap the distance and height to position the ladders, but this results in a maximum distance rather than a maximum height achieved.

      Like

  • Unknown's avatar

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

    Teaser 2925: The eternal triangle – Go figure! 

    From The Sunday Times, 14th October 2018 [link] [link]

    From my desk I saw the above when Leigh and Bob put 8392546137 and 4613725808 into two of the identical calculators used by my class. Everyone was told to press “clear”, then enter their unique three-figure pupil number (between 100 and 999) and divide this by the total number of display segments seen in it. If the result was a whole number they were to repeat the process with that result and its segment count (and so on until a decimal fraction part arose). Leigh, Bob and Geb each made four “divisions” this way. Using their three initial values as the sides of a triangle (Bob’s shortest, Geb’s longest), I told them to find its area.

    What was Leigh’s number?

    [teaser2925]

     
    • Jim Randell's avatar

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

      This Python program runs in 87ms.

      Run: [ @replit ]

      from enigma import (irange, nsplit, sqrt, subsets, printf)
      
      # segment count per digit
      #            0  1  2  3  4  5  6  7  8  9
      segments = [ 6, 2, 5, 5, 4, 5, 6, 3, 7, 6 ]
      
      # apply the process to n
      # return the number of applications
      def process(n):
        r = 0
        while n > 0:
          r += 1
          # count the segments
          s = sum(segments[d] for d in nsplit(n))
          (n, z) = divmod(n, s)
          if z != 0: return r
      
      # area of a triangle (using Heron's Formula)
      def heron(a, b, c):
        assert not (a < 0 or b < 0 or c < 0)
        r = (a + b - c) * (a + c - b) * (b + c - a)
        return (None if r < 0 else 0.25 * sqrt(r * (a + b + c)))
      
      # consider 3 digit numbers
      # and record those with a value of 4
      ns = list()
      for n in irange(100, 999):
        k = process(n)
        if k == 4:
          printf("[n={n}]")
          ns.append(n)
      
      # choose three of the numbers
      for (B, L, G) in subsets(ns, size=3):
        # check it forms a triangle
        A = heron(B, L, G)
        if not A: continue
        # output solution
        printf("B={B} L={L} G={G} [area={A:.3f}]")
      

      Solution: Leigh’s number was 756.

      There are only three 3-digit numbers that can be processed four times:

      640 → 40 → 4 → 1 → ½
      756 → 54 → 6 → 1 → ½
      810 → 54 → 6 → 1 → ½

      So the first number is Bob’s, the middle number is Leigh’s, and the last number is Geb’s.

      Used as sides of a triangle they enclose an area of √(51922261319), approximately 227864.568.

      Like

  • Unknown's avatar

    Jim Randell 8:22 am on 9 April 2019 Permalink | Reply
    Tags:   

    Brain-Teaser 469: [Safe combination] 

    From The Sunday Times, 24th May 1970 [link]

    Before his retirement, the Master Spy, enigmatic to the last, left instructions for opening his safe and recovering the Top Secret plans for Winning World Domination:

    “The combination is a 7-figure number, the sum of whose digits is 55. The first 4 figures make up a number divisible by 17, the sum of whose digits is also divisible by 17. The last 3 figures make up a number divisible by 7, the sum of whose digits is also divisible by 7.

    By now you should realise that there are 4 possible combinations. Since 3 of these all detonate a booby-trap, I’d better warn you that the correct number has no figure appearing more than 3 times”

    What is the combination of the safe?

    This puzzle was originally published with no title.

    [teaser469]

     
    • Jim Randell's avatar

      Jim Randell 8:23 am on 9 April 2019 Permalink | Reply

      We can treat this puzzle as a collection of alphametic expressions that can be handled by the [[ SubstitutedExpression() ]] solver from the enigma.py library.

      The following run file executes in 324ms.

      Run: [ @repl.it ]

      #! python3 -m enigma -rr
      
      # suppose the combination number is: ABCDEFG
      
      SubstitutedExpression
      
      --distinct=""
      --answer="ABCDEFG"
      
      # the digits sum to 55
      "A + B + C + D + E + F + G = 55"
      
      # the first four digits (and their sum) are divisible by 17
      "ABCD % 17 = 0"
      "(A + B + C + D) % 17 = 0"
      
      # the last three digits (and their sum) are divisible by 7
      "EFG % 7 = 0"
      "(E + F + G) % 7 = 0"
      
      # check no digit appears more than 3 times
      --code="check = lambda *s: all(s.count(d) < 4 for d in set(s))"
      "check(A, B, C, D, E, F, G)"
      

      Solution: The combination is 9979588.

      The four candidate numbers are: 9979777, 9979588, 9979966, 9979399.

      Like

    • GeoffR's avatar

      GeoffR 3:07 pm on 9 April 2019 Permalink | Reply

      
      % A Solution in MiniZinc
      include "globals.mzn";
      
      var 0..9:A; var 0..9:B; var 0..9:C; var 0..9:D; 
      var 0..9:E; var 0..9:F; var 0..9:G;
      
      constraint A >  0 /\ E > 0;
      
      var 1000000..9999999: ABCDEFG = 1000000*A + 100000*B + 10000*C + 1000*D + 100*E + 10*F + G;
      var 1000..9999: ABCD = 1000*A + 100*B + 10*C + D; 
      var 100..999: EFG = 100*E + 10*F + G;
      
      constraint A + B + C + D + E +  F + G == 55;
      
      constraint ABCD mod 17 == 0 /\ (A + B + C + D) mod 17 == 0;
      
      constraint EFG mod 7 == 0 /\ (E + F + G) mod 7 == 0;
      
      solve satisfy;
      
      output [ "Safe combination = " ++ show(ABCDEFG) ];
      
      % Safe combination = 9979966  << has 4 nines
      % Safe combination = 9979777  << has 4 sevens
      % Safe combination = 9979588  << has 3 nines  << the answer 
      % Safe combination = 9979399  << has 4 nines
      % ----------
      % ==========
      % Finished in 240msec
      

      Like

      • Jim Randell's avatar

        Jim Randell 5:18 pm on 9 April 2019 Permalink | Reply

        And we could add the following constraint to narrow the possibilities down to the single answer:

        constraint forall (d in 0..9) (at_most(3, [A, B, C, D, E, F, G], d));
        

        Like

  • Unknown's avatar

    Jim Randell 8:18 am on 8 April 2019 Permalink | Reply
    Tags: by: Brian Gladman   

    Teaser 2549: A round trip 

    From The Sunday Times, 31st July 2011 [link] [link]

    I own a circular field with six trees on its perimeter. One day I started at one tree and walked straight to the next, continuing in this way around the perimeter from tree to tree until I returned to my starting point. In this way I found that the distances between consecutive trees were 12, 12, 19, 19, 33 and 33 metres.

    What is the diameter of the field?

    [teaser2549]

     
    • Jim Randell's avatar

      Jim Randell 8:19 am on 8 April 2019 Permalink | Reply

      I assumed the trees were visited by taking a direct straight line between them, rather than walking along an arc of the field boundary.

      We can cut the field (like a pizza) into sectors from the trees to the centre point. The field can then be rearranged (like a pizza) with the sectors in any order we like, and retain its circular shape.

      In particular we can rearrange the circle into two semi-circles each involving a 12, 19, and 33 sector.

      If we draw the quadrilateral formed from the trees in one of these semi-circles we get:

      The length of the lines are: AB = a, BC = b, CD = c, AD = x, AC = y, BD = z.

      As the triangles ABD and ACD are inscribed in a semi-circle they are right-angled:

      x² = a² + z²
      x² = c² + y²

      so:

      z² = x² − a²
      y² = x² − c²

      and multiplying these together:

      y²z² = x4 − (a² + c²)x² + a²c²

      Also, ABCD is a cyclic quadrilateral, so by Ptolomy’s Theorem [ link ]:

      yz = bx + ac

      squaring both sides:

      y²z² = b²x² + 2abcx + a²c²

      equating both expressions for y²z² we get:

      x4 − (a² + c²)x = b²x + 2abcx

      dividing by x, and simplifying:

      x³ − (a² + b² + c²)x − 2abc = 0

      We can look for a solution to this equation numerically:

      from enigma import (Polynomial, find_values, printf)
      
      # parameters
      (a, b, c) = (12, 19, 33)
      
      # form the polynomial
      p = Polynomial([-2 * a * b * c, -(a * a + b * b + c * c), 0, 1])
      
      # find a numerical solution in the required range
      (m, M) = (max(a, b, c), a + b + c)
      for r in find_values(p, 0, m, M):
        printf("diameter = {r.v:.3f} m")
      

      Solution: The diameter of the field is 44 metres.

      If there is an integer solution k, then the cubic polynomial is divisible by (x − k), so k will be a smallish divisor of the constant term in the polynomial, in this case 2abc.

      from enigma import (Polynomial, irange, printf)
      
      # parameters
      (a, b, c) = (12, 19, 33)
      
      # form the polynomial
      p = Polynomial([-2 * a * b * c, -(a * a + b * b + c * c), 0, 1])
      
      # possible range of solutions
      (m, M) = (max(a, b, c), a + b + c)
      
      # find integer roots in in the required range
      for x in p.roots(domain="Z", include="+"):
        if not (x < m or x > M):
          printf("diameter = {x} m")
      

      In fact using: a = 12, b = 19, c = 33 we get the following polynomial:

      x³ − 1594x − 15048 = 0

      which can be factorised as:

      (x − 44)(x² + 44x + 342) = 0

      Giving a positive root of 44, and negative roots of −22 ± √(142).

      There are only 5 divisors to be checked in the required range.

      Like

    • Jim Randell's avatar

      Jim Randell 11:28 pm on 8 April 2019 Permalink | Reply

      Here is an alternative approach that uses a bit less analysis, and works with any viable collection of distances.

      For a sector with a distance of d in a circle with radius r we can use the Cosine Rule [ link ] to calculate the angle at the centre of the circle:

      d² = 2r²(1 − cos(𝛉))
      cos(𝛉) = 1 − (d² / 2r²)

      We then just need to find a value for r, which makes the sum of the angles for all sectors achieve a value of 360°.

      from math import (acos, pi, fsum)
      from enigma import (fdiv, find_values, printf)
      
      # use the cosine rule to compute the angle at the centre of
      # the circle of radius r, for distance d
      angle = lambda r, d: acos(1.0 - 0.5 * fdiv(d, r)**2)
      
      # distances
      ds = (12, 12, 19, 19, 33, 33)
      
      # find a radius that makes the angles sum to 2pi
      f = lambda r: fsum(angle(r, d) for d in ds)
      for s in find_values(f, 2 * pi, 0.5 * max(ds), 0.5 * fsum(ds)):
        # output solution
        printf("diameter = {d:.3f} m", d=2.0 * s.v)
      

      Like

  • Unknown's avatar

    Jim Randell 11:01 am on 7 April 2019 Permalink | Reply
    Tags: ,   

    Brainteaser 1542: Precisely what do I mean? 

    From The Sunday Times, 29th March 1992 [link]

    There is a row of 10 boxes and each box contains one object, which is a knife, a fork or a spoon. Each of the three utensils is in at least one box. Here are five true statements to help you answer the questions below:

    1. A knife is in more boxes than a spoon is in;
    2. A spoon is in more boxes than a fork is in;
    3. A knife is not in precisely five boxes;
    4. A spoon is not in precisely three boxes;
    5. A fork is not in precisely half the number of boxes a spoon is in.

    How many boxes contain a knife?

    How many boxes contain a spoon?

    This puzzle is included in the book Brainteasers (2002), in which it appears in the following (slightly different) form:

    There is a row of ten boxes and each box contains one object, which is a knife, a fork or a spoon. There is at least one of each utensil. Here are five true statements to help you work out how many of each there are:

    • A knife is in more boxes than a spoon is in;
    • A spoon is in more boxes than a fork is in;
    • A knife is not in precisely five boxes;
    • A spoon is not in precisely three boxes;
    • A fork is not in precisely half the number of boxes a spoon is in.

    How many of each utensil are there?

    However I think both these formulations are flawed, in that under any reasonable interpretation there are no solutions. In the comments I present a variation that can be solved.

    [teaser1542]

     
    • Jim Randell's avatar

      Jim Randell 11:05 am on 7 April 2019 Permalink | Reply

      Having read the solution given in the book, I think the spirit of the puzzle can be maintained by phrasing it slightly differently:

      The National Museum of Cutlery in the small country of Ambiguity has an exhibit consisting of a row of ten boxes.

      Each box contains one object, which is either a knife, a fork or a spoon. There is at least one of each utensil.

      On a recent visit I heard five natives make the following true statements:

      1. A knife is in more boxes than a spoon is in.
      2. A spoon is in more boxes than a fork is in.
      3. A knife is not in precisely five boxes.
      4. A spoon is not in precisely three boxes.
      5. A fork is not in precisely half the number of boxes a spoon is in.

      How many of each utensil are there?

      And here is my solution:

      Suppose there are K knives, F forks and S spoons, each number has a value from 1 to 9.

      Looking at the statements:

      “A knife is in more boxes than a spoon is in”, seems to be an oddly worded way of saying: “there are more knives than spoons”:

      K > S

      Similarly: “A spoon is in more boxes than a fork is in”, seems to be saying:

      S > F

      We then have three statements of the form: “an X is not in precisely N boxes”

      I think there are two reasonable interpretations of this:

      (a) “The number of boxes containing an X, is not exactly N”

      i.e.:

      X ≠ N

      or:

      (b) “There are exactly N boxes, containing an object that is not an X”

      i.e.:

      10 − X = N

      The following Python 3 program considers these possible interpretations for the last three statements. It runs in 80ms.

      Run: [ @repl.it ]

      from enigma import (irange, join, printf)
      
      # decompose <t> into <k> increasing values
      def decompose(t, k, m=1, s=[]):
        if k == 1:
          if not (t < m):
            yield s + [t]
        else:
          for x in irange(m, t):
            yield from decompose(t - x, k - 1, x + 1, s + [x])
      
      # consider interpretations for:
      # "the number of boxes containing an <x> is <n>/<d>"
      def interpretations(x, n, d=1):
        # (a) "the number of boxes containing an <x> is exactly <n>/<d>"
        if d * x != n: yield 'a'
        # (b) "there are exactly <n>/<d> boxes containing an object that is not an <x>"
        if d * (10 - x) == n: yield 'b'
      
      # find possible values for F < S < K
      for (F, S, K) in decompose(10, 3):
        # consider possible interpretations for the last three statements
        ss = list(join(interpretations(*args)) for args in [(K, 5), (S, 3), (F, S, 2)])
        # each must have some interpretation
        if not all(ss): continue
        # output solution
        printf("F={F} S={S} K={K} {ss}")
      

      Solution: There is 1 fork, 4 spoons, 5 knives.

      The constraint (F < S < K) narrows the solution down to 4 possibilities:

      F=1, S=2, K=7
      F=1, S=3, K=6
      F=1, S=4, K=5
      F=2, S=3, K=5

      Only in the case (F=1, S=4, K=5) do the last three statements all have viable interpretations. These are:

      3. “A knife is not in precisely 5 boxes” = “There are exactly 5 boxes containing an object that is not a knife”
      4. “A spoon is not in precisely 3 boxes” = “The exact number of boxes containing a spoon is not 3”
      5. “A fork is not in precisely half the number of boxes a spoon is in” = “The exact number of boxes containing a fork is not half the exact number of boxes containing a spoon”

      or:

      3. “10 − K = 5”
      4. “S ≠ 3”
      5. “F ≠ S / 2”

      We can see each of these is a true statement, but they do not all use the same interpretation of the statement form. (Statement 3 uses the (b) interpretation. Statements 4, 5 use the (a) interpretation). This is why I changed the puzzle wording, so that the statements are made by different people. To have them made by the same person implies a consistent interpretation and gives no viable solutions.

      Like

  • Unknown's avatar

    Jim Randell 9:25 am on 5 April 2019 Permalink | Reply
    Tags:   

    Teaser 2950: Ten digits 

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

    Without repeating a digit I have written down three numbers, all greater than one. Each number contains a different number of digits. If I also write down the product of all three numbers, then the total number of digits I have used is ten. The product contains two pairs of different digits, neither of which appear in the three original numbers.

    What is the product?

    This puzzle appears in the books The Sunday Times Brain Teasers 1 (2019) and The Sunday Times Teasers Book 1 (2021).

    [teaser2950]

     
    • Jim Randell's avatar

      Jim Randell 9:26 am on 5 April 2019 Permalink | Reply

      The product has to be long enough to accommodate two pairs of different digits in, so it must be at least 4 digits long.

      But the total multiplication sum only uses 10 digits, so the three original numbers can use at most 6 digits, and as the number of digits in each multiplicand is different they must use at least 6 digits, so the sum looks like one of these:

      A × BC × DEF = XXYY
      A × BC × DEF = XYXY
      A × BC × DEF = XYYX

      We can solve these using the [[ SubstitutedExpression() ]] solver from the enigma.py library (although it is not especially quick). The following run file executes in 619ms.

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --invalid="0,ABDX"
      --invalid="1,A"
      
      "A * BC * DEF in { XXYY, XYXY, XYYX }"
      
      --answer="A * BC * DEF"
      

      Solution: The product is 8778.

      The full sum is:

      3 × 14 × 209 = 8778

      The solution uses the XYYX pattern for the product, and is the only solution using that pattern.

      However, without the restriction that A is greater than 1 we can find a further solution using the XXYY pattern:

      1 × 36 × 275 = 9900

      And there are no solutions that use the remaining XYXY pattern. (This can be seen by observing that the product has a prime factor of 101, and we cannot have a three digit multiple of 101 that does not have repeated digits).

      Like

      • Jim Randell's avatar

        Jim Randell 10:35 am on 5 April 2019 Permalink | Reply

        Here is a faster solution in Python. It considers possible values for the result of the multiplication, and then factors the result into 1-,2-,3-digit numbers.

        It runs in 96ms.

        from enigma import (irange, subsets, divisors_pairs, nsplit, printf)
        
        # choose X and Y
        for (X, Y) in subsets(irange(0, 9), size=2, select='P'):
          if X == 0: continue
        
          # consider possible results
          for (i, j) in [(1100, 11), (1010, 101), (1001, 110)]:
            n = X * i + Y * j
        
            # find 1-, 2-, 3- digit factors of n
            for (A, m) in divisors_pairs(n):
              if A < 2: continue
              if A > 9: break
              if len({A, X, Y}) != 3: continue
        
              for (BC, DEF) in divisors_pairs(m):
                if BC < 10: continue
                if BC > 99: break
                if not (99 < DEF < 1000): continue
                (B, C) = nsplit(BC)
                (D, E, F) = nsplit(DEF)
                if len({A, B, C, D, E, F, X, Y}) != 8: continue
        
                # output solution
                printf("{A} * {BC} * {DEF} = {n}")
        

        Like

    • GeoffR's avatar

      GeoffR 11:28 am on 11 April 2019 Permalink | Reply

      % A Solution in MiniZinc
      include "globals.mzn";
      
      % three numbers are A, BC and DEF, plus 2 digit pairs from X and Y
      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:X; var 0..9:Y;
      
      constraint A > 1 /\ B > 0 /\ D > 0 /\ X > 0 /\ Y > 0;
      constraint all_different ([ A, B, C, D, E, F, X, Y]);
       
      var 10..99: BC = 10*B + C;
      var 100..999: DEF = 100*D + 10*E + F;
      
      % possible arrangements of product are XXYY, XYXY and XYYX
      constraint (A * BC * DEF) == (1000*X + 100*X + 10*Y + Y) 
      \/ (A * BC * DEF) == (1000*X + 100*Y + 10*X + Y) 
      \/ (A * BC * DEF) == (1000*X + 100*Y + 10*Y + X); 
      
      solve satisfy;
      
      output [ "Product = " ++ show(A * BC * DEF) ];
      
      

      Like

    • GeoffR's avatar

      GeoffR 8:58 am on 8 February 2024 Permalink | Reply

      
      # Sum digit pattern is A × BC × DEF = XXYY, XYXY or XYYX
      # LHS of sum
      for A in range(2, 10):
        for BC in range(12, 99):
          B, C = BC //10, BC % 10
          if A in (B, C):continue
          for DEF in range(123, 988):
            D, E, F = DEF // 100, DEF // 10 % 10, DEF % 10
            if len({A, B, C, D, E, F}) == 6:
                
              # RHS of  sum
              prod = A * BC * DEF
              if not 1000 < prod < 9999:continue
              M, N = prod // 1000, prod // 100 % 10
              P, Q = prod // 10 % 10, prod % 10
              # Digit pattern of MNPQ is XXYY, XYXY or XTTX
              if len({M, N, P, Q}) == 2:
                if (M == N and P == Q) or (M == P and N == Q) \
                   or (M == Q and N == P):   
                 if len({A, B, C, D, E, F, M, N, P, Q}) == 8:   
                    print(f"Sum: {A} x {BC} x {DEF} = {prod}.")
      
      # Sum: 3 x 14 x 209 = 8778.
      

      Like

    • Frits's avatar

      Frits 3:21 pm on 8 February 2024 Permalink | Reply

          
      # dictionary of product a * bc with different digits (not ending on 1)
      d = dict()
      for i in range(2, 10):
        for j in range(10, 50):
          if i < j and i * j < 100 and (i * j) % 10 != 1 and j % 10 and \
             len(set(ij := str(i) + str(j))) == len(ij):
            d[i * j] = d.get(i * j, []) + [(str(i), str(j))] 
                   
      # A * BC * DEF = RHS
      # RHS = XYXY is not possible as XYXY is a multiple of 101
      
      # A number is divisible by 11 if the difference between the sum of its digits
      # in odd places and the sum of the digits in even places is either 0 or 
      # a multiple of 11
      # thus RHS is a multiple of 11 for XXYY and XYYX
      for i in range(10, 91):
        DEF = 11 * i
        sDEF = str(DEF)
        if sDEF[-1] == '0' or len(set(sDEF)) != 3: continue
        
        # ABC * DEF = RHS
        for ABC in range(max(20, (999 // DEF) + 1), (9999 // DEF) + 1):
          sRHS = str(ABC * DEF)
          
          if len(set(sRHS)) != 2 or any(x in sRHS for x in sDEF) or \
             sRHS.count(sRHS[0]) != 2: continue
          
          # is ABC a valid product
          if ABC not in d: continue  
          for a, b in d[ABC]: 
            # different digits
            if len(set(s := (a + b + sDEF + sRHS))) != len(s) - 2: continue 
            print(f"answer: {sRHS} ({a} * {b} * {DEF})")  
      

      Like

  • Unknown's avatar

    Jim Randell 8:02 am on 5 April 2019 Permalink | Reply
    Tags:   

    Teaser 2926: Coins of Obscura 

    From The Sunday Times, 21st October 2018 [link] [link]

    George and Martha were on holiday in Obscura where coins are circular with radii equal to their whole number value in scurats. They had coffees and George took out some loose change. He placed one 10 scurat and two 15 scurat coins on the table so that each coin touched the other two and a smaller coin between them that touched all three. He then placed a fifth coin on top of these four which exactly covered them and the total value of the five coins was exactly enough to pay the bill.

    How much was the coffee bill?

    [teaser2926]

     
    • Jim Randell's avatar

      Jim Randell 8:02 am on 5 April 2019 Permalink | Reply

      I think by “exactly covered” the setter means that the fifth coin was the smallest possible circle that would cover the original three coins.

      If you’ve encountered “Soddy Circles” the fourth and fifth coins correspond to the inner and outer Soddy circles formed from the first three coins.

      There is a (relatively) straightforward expression that can be used to calculate the radii of these circles (see: [ Descartes Theorem ]).

      Here is a useful reference for Soddy Circles: [ link ]

      This Python program runs in 89ms.

      Run: [ @replit ]

      from enigma import (is_square, div, printf)
      
      # calculate the radius of the inner and outer Soddy circles
      # (we are only interested in integer solutions)
      def soddy(r1, r2, r3):
        x = r1 * r2 * r3
        y = is_square(x * (r1 + r2 + r3))
        if y is None: return (None, None)
        z = r1 * r2 + r1 * r3 + r2 * r3
        return (div(x, 2 * y + z), div(x, 2 * y - z))
      
      # initial parameters
      (r1, r2, r3) = (10, 15, 15)
      
      # the radii of the Soddy circles
      (r, R) = soddy(r1, r2, r3)
      assert not (r is None or R is None)
      printf("[r1={r1} r2={r2} r3={r3} -> r={r} R={R}]")
      
      # add them all together
      t = r1 + r2 + r3 + r + R
      printf("total = {t}")
      

      Solution: The bill came to 72 scurats.

      The additional coins have values of 2 and 30.

      Here is a diagram. The original coins are shown in black, the inner and outer Soddy Circles (corresponding to the fourth and fifth coins) are shown in red:

      Like

  • Unknown's avatar

    Jim Randell 7:37 am on 4 April 2019 Permalink | Reply
    Tags: by: Donald Entwisle   

    Brainteaser 1538: Times square 

    From The Sunday Times, 1st March 1992 [link]

    Alf: Listen to this: “SUN times DAY equals TIMES“.

    Beth: Sounds like a lot of nonsense to me.

    Alf: Let me write it down for you. Like this:

    SUN × DAY = TIMES

    In this sum are 10 different letters representing digits 0 to 9 and in my answer SUN minus DAY is a perfect square. That should help you.

    Beth: That’s a tall order, but I’ll have a go. Where’s my calculator.

    Beth did find Alf’s solution. What was their number for TIMES?

    This puzzle is included in the book Brainteasers (2002), in which it appears in the following modified form:

    With the usual letters-for-digits convention:

    SUN – DAY

    is the square of a prime, and:

    SUN × DAY = TIMES

    What number is TIMES?

    (We do not actually need to know that the square is the square of a prime, but it cuts down the work considerably).

    [teaser1538]

     
    • Jim Randell's avatar

      Jim Randell 7:38 am on 4 April 2019 Permalink | Reply

      The wording (but not most of the meaning) of this Teaser was changed considerably for the book. In the original puzzle we were told that (SUN − DAY) was a square number, but not that it was the square of a prime.

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

      This run file executes in 235ms.

      Run: [ @repl.it ]

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --answer="TIMES"
      
      "is_prime(is_square(SUN - DAY))"
      
      "SUN * DAY = TIMES"
      

      Solution: TIMES = 50862.

      We can remove the call to [[ is_prime() ]] to solve the original puzzle. The answer is the same.

      Without the subtraction constraint at all, the multiplication sum has three solutions:

      % python enigma.py SubstitutedExpression "SUN * DAY = TIMES"
      (SUN * DAY = TIMES)
      (219 * 308 = 67452) / A=0 D=3 E=5 I=7 M=4 N=9 S=2 T=6 U=1 Y=8
      (294 * 173 = 50862) / A=7 D=1 E=6 I=0 M=8 N=4 S=2 T=5 U=9 Y=3
      (254 * 378 = 96012) / A=7 D=3 E=1 I=6 M=0 N=4 S=2 T=9 U=5 Y=8
      [3 solutions]
      

      Like

  • Unknown's avatar

    Jim Randell 9:10 am on 3 April 2019 Permalink | Reply
    Tags:   

    Teaser 2927: On a roll 

    From The Sunday Times, 28th October 2018 [link] [link]

    My son saw the “average sheets per roll” printed on our new pack of four toilet rolls. Curious, he counted each roll’s total sheets by overlaying lines of ten sheets to and fro, tallying layers, and then adding any extra sheets. These totals were four consecutive three-figure numbers, including the printed “average sheets per roll”. For each total, he noticed that there was the same single-figure number of choices for a number of sheets per layer, requiring at least two layers, which would leave no extra sheets. Re-counting the toilet roll with the “average sheets per roll”, he used a two-figure number of sheets per layer and tallied a two-figure number of such layers, with no extras.

    What was the “average sheets per roll”?

    [teaser2927]

     
    • Jim Randell's avatar

      Jim Randell 9:10 am on 3 April 2019 Permalink | Reply

      This Python program runs in 81ms.

      Run: [ @repl.it ]

      from enigma import (tau, irange, divisors_pairs, printf)
      
      # store the last 4 divisor counts
      ds = list()
      
      # consider increasing 3-digit numbers
      for n in irange(100, 996):
      
        # count the number of divisors (excluding 1 * n)
        d = tau(n) - 1
        ds.append(d)
        if len(ds) < 4: continue
      
        # look for sequences with the same number of (1-digit) choices
        if len(set(ds)) == 1 and ds[0] < 10:
          # now consider divisors pairs that are both 2-digits
          rs = list()
          for m in irange(n - 3, n):
            for (a, b) in divisors_pairs(m):
              if 9 < a < 100 and 9 < b < 100:
                rs.append((m, a, b))
      
          if rs:
            # output solution
            printf("rolls = {ns}, choices = {ds}", ns=list(irange(n - 3, n)))
            for (m, a, b) in rs:
              printf("  avg = {m} = {a} * {b}")
            # we're done
            break
      
        ds.pop(0)
      

      Solution: The average sheets per roll number is 242.

      The four toilet rolls have 242, 243, 244, 245 sheets. (So the average number of sheets per roll in the pack is higher that the stated average sheets per roll).

      Each roll has 5 ways to lay out the sheets in piles:

      242 = 2×121, 11×22, 22×11, 121×2, 242×1
      243 = 3×81, 9×27, 27×9, 81×3, 243×1
      244 = 2×122, 4×61, 61×4, 122×2, 244×1
      245 = 5×49, 7×35, 35×7, 49×5, 245×1

      And the “average” roll (with 242 sheets) can be laid out as 11× 22 sheets, or 22× 11 sheets.

      This is the only solution with 3-digit values.

      I checked on a 4-pack of loo rolls we have in the house, and they had an average sheet count of 221, which is not too far from the answer.

      For 4-digit values for the number of sheets per roll there are 3 different sequences that work, but only one of these has a unique answer for the average sheet count.

      Like

  • Unknown's avatar

    Jim Randell 9:28 am on 2 April 2019 Permalink | Reply
    Tags: by: B A Hill   

    Brain-Teaser 468: [Football championship] 

    From The Sunday Times, 17th May 1970 [link]

    In a home association football championship, where each of the four countries plays the others once, the teams were very evenly matched. The result was that all four countries gained the same number of points and all had the same goal average.

    England were the highest scorers in any one match, scoring 6 when beating Northern Ireland, and this also proved to be the match with the greatest number of goals. Second highest scorers were Northern Ireland, scoring 5 when beating Scotland, but there were more goals in their match with Wales when they scored 4.

    In order to decide the champions the team scoring the highest number of goals in the championship were adjudged the winners. There was one outright winner with only 2 goals separating the top and bottom teams.

    What was the aggregate number of goals for each team?

    This puzzle was originally published with no title.

    [teaser468]

     
    • Jim Randell's avatar

      Jim Randell 9:30 am on 2 April 2019 Permalink | Reply

      Using the [[ Football() ]] helper class from the enigma.py library we can find a solution to this puzzle.

      I assumed that 2 points were awarded for a win, and 1 for a draw. (With 3 points for a win there is no solution).

      This Python program runs in 295ms.

      Run: [ @repl.it ]

      from itertools import product
      from enigma import (Football, seq_all_same, irange, printf)
      
      # the scoring system
      football = Football(games="wdl", points=dict(w=2, d=1))
      
      # the teams
      (E, N, S, W) = (0, 1, 2, 3)
      
      # the match outcomes we know: E beat N, N beat S
      ms = { (E, N): 'w', (N, S): 'w' }
      
      # outcomes for the remaining four matches
      for (ms[(E, S)], ms[(E, W)], ms[(N, W)], ms[(S, W)]) in football.games(repeat=4):
      
        # make the tables
        tE = football.table(*football.extract(ms, E))
        tN = football.table(*football.extract(ms, N))
        tS = football.table(*football.extract(ms, S))
        tW = football.table(*football.extract(ms, W))
      
        # all the points are the same
        if not seq_all_same(x.points for x in (tE, tN, tS, tW)): continue
      
        # E vs N was won 6 - x, and this match had the highest number of goals (t)
        ss = dict()
        for x in irange(0, 5):
          ss[(E, N)] = (6, x)
          t = 6 + x
      
          # N vs S was won 5 - y
          for y in irange(0, 4):
            if not (5 + y < t): continue
            ss[(N, S)] = (5, y)
      
            # but there were more goals in the N vs W match, 4 - z
            for z in irange(y + 2, x + 1):
              if not (football.outcomes([(4, z)], [0])[0] == ms[(N, W)]): continue
              ss[(N, W)] = (4, z)
      
              # possible scores with fewer than t total goals and no side scoring more than 4
              scores = dict()
              scores['w'] = list((x, y) for x in irange(1, 4) for y in irange(0, x - 1) if x + y < t)
              scores['l'] = list((y, x) for (x, y) in scores['w'])
              scores['d'] = list((x, x) for x in irange(0, min((t - 1) // 2, 4)))
      
              # goals for/against N
              (fN, aN) = football.goals(*football.extract(ss, N))
      
              # consider scores in the remaining matches
              for (ss[(E, S)], ss[(E, W)], ss[(S, W)]) in product(scores[ms[(E, S)]], scores[ms[(E, W)]], scores[ms[(S, W)]]):
      
                # goals for/against E, S, W
                (fE, aE) = football.goals(*football.extract(ss, E))
                (fS, aS) = football.goals(*football.extract(ss, S))
                (fW, aW) = football.goals(*football.extract(ss, W))
                # check all goal averages are the same
                if not all(fN * a == f * aN for (f, a) in [(fE, aE), (fS, aS), (fW, aW)]): continue
      
                # sort the goals scored list
                fs = sorted([fE, fN, fS, fW], reverse=1)
                # there is a single outright winner
                if not (fs[0] > fs[1]): continue
                # and only 2 goals between the top and bottom teams
                if not (fs[0] - fs[-1] == 2): continue
      
                # output the table
                printf("E: {tE} f={fE} a={aE}")
                printf("N: {tN} f={fN} a={aN}")
                printf("S: {tS} f={fS} a={aS}")
                printf("W: {tW} f={fW} a={aW}")
                printf()
      
                # output the scores in the matches
                football.output_matches(ms, ss, teams="ENSW")
      

      Solution: Northern Ireland scored 12 goals. Wales scored 11 goals. England and Scotland each scored 10 goals.

      There is only one set of match outcomes that gives the required result:

      E vs N = 6-3
      E vs S = 1-4
      E vs W = 3-3
      N vs S = 5-2
      N vs W = 4-4
      S vs W = 4-4

      Each team ends up with 3 points (E, N, S from 1w+1d, W from 3d), and with the same number of goals for and against (giving a goal average of exactly 1).

      Like

  • Unknown's avatar

    Jim Randell 8:57 am on 1 April 2019 Permalink | Reply
    Tags:   

    Teaser 2928: Golf balls 

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

    Three friends play 18 holes of golf together every week. They have a large supply of golf balls numbered from 1 to 5. At the beginning of a year, they each start playing with a new ball, but all three ball numbers are different. Alf uses the same ball number for exactly 21 holes before changing to the next higher number (or to number 1 if he was using a number 5). He continues to use each number for exactly 21 holes. The same applies to Bert, except that he changes his ball number in the same way after every 22 holes, and to Charlie who changes his ball number after every 23 holes.

    Last year, there was just one occasion when they all used the same ball number on a hole.

    What was the number of the hole on that occasion?

    [teaser2928]

     
    • Jim Randell's avatar

      Jim Randell 8:59 am on 1 April 2019 Permalink | Reply

      This Python program finds the solution constructively in 79ms.

      Run: [ @replit ]

      from enigma import (irange, subsets, singleton, printf)
      
      # increment ball count, and ball if necessary
      def inc(i, x, X):
        i += 1
        if i == X:
          x = (1 if x == 5 else x + 1)
          i = 0
        return (i, x)
      
      # find (week, hole) pairs
      def solve(A, B, C, a, b, c, n):
        i = j = k = 0
        # consider number of weeks
        for w in irange(1, n):
          # and each hole
          for h in irange(1, 18):
            if a == b == c:
              yield (w, h, b)
            # increment ball counters
            (i, a) = inc(i, a, A)
            (j, b) = inc(j, b, B)
            (k, c) = inc(k, c, C)
      
      # choose starting balls for A, B, C
      # suppose A's ball is 1, we only have to choose B and C
      a = 1
      for (b, c) in subsets((2, 3, 4, 5), size=2, select='P'):
        # in 2017 there were 52 whole weeks, + 1 extra Sunday
        rs = singleton(solve(21, 22, 23, a, b, c, 53))
        if rs:
          (w, h, x) = rs
          printf("a={a} b={b} c={c}: week={w}, hole={h}, ball={x}")
      

      Solution: Hole number 10.

      It would happen on week number 53.

      Like

  • Unknown's avatar

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

    Teaser 2949: Mystery numbers 

    From The Sunday Times, 31st March 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 one of them, which I have indicated by X.

    This gave me the image above.

    What were my two original numbers?

    [teaser2949]

     
    • Jim Randell's avatar

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

      We can feed this problem directly to the [[ SubstitutedDivision() ]] solver from the enigma.py library.

      This run file executes in 153ms.

      Run: [ @repl.it ]

      #! python -m enigma -rr
      
      SubstitutedDivision
      
      "XX??X / ?X = ????"
      
      "XX - ?X = ??"
      "??? - ?? = ??"
      "??? - ?X? = ?"
      "?X - ?X = 0"
      

      Solution: The two original numbers were: 23 and 33603.

      Like

      • Jim Randell's avatar

        Jim Randell 4:32 pm on 31 March 2019 Permalink | Reply

        Although the run file given above does find the correct answer, which can be verified by inspection. I think there is a little bit more work to do to ensure that the erased digits are all different from the digit X.

        Here is a run file that uses symbols for the erased digits (instead of the wildcard “?”), and includes an extra check to make sure they are all different from X.

        #! python -m enigma -rr
        
        #          D E F G
        #      -----------
        #  C X ) X X A B X
        #        H X
        #        ---
        #        I J A
        #          K M
        #        -----
        #          N P B
        #          Q X R
        #          -----
        #              S X
        #              S X
        #              ===
        
        SubstitutedDivision
        
        "XXABX / CX = DEFG"
        
        "XX - HX = IJ"
        "IJA - KM = NP"
        "NPB - QXR = S"
        "SX - SX = 0"
        
        --distinct="XA,XB,XC,XD,XE,XF,XG,XH,XI,XJ,XK,XM,XN,XP,XQ,XR,XS"
        

        Like

    • GeoffR's avatar

      GeoffR 12:34 pm on 21 April 2019 Permalink | Reply

      % A Solution in MiniZinc  
      include "globals.mzn";
      
      %           D E F G
      %       -----------
      %   C X ) X X A B X
      %         H X
      %         ---
      %         I J A
      %           K M
      %         -----
      %           N P B
      %           Q X R
      %           -----
      %               S X
      %               S X
      %               ===
      
      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:N; var 0..9:P; var 0..9:Q;
      var 0..9:R; var 0..9:S; var 0..9:X; 
      
      constraint D > 0 /\ C > 0 /\ X > 0 /\ I > 0 /\ K > 0 
      /\ N > 0 /\ Q > 0 /\ S > 0;
      
      var 10..99: XX = 11*X;
      var 10..99: HX = 10*H + X;
      
      var 10..99: CX = 10*C + X;
      var 10..99: KM = 10*K + M;
      var 10..99: IJ = 10*I + J;
      var 10..99: NP = 10*N + P;
      var 10..99: SX = 10*S + X;
      
      var 100..999: XXA = 110*X + A;
      var 100..999: IJA = 100*I + 10*J + A;
      var 100..999: NPB = 100*N + 10*P + B;
      var 100..999: QXR = 100*Q + 10*X + R;
      
      var 1000..9999: DEFG = 1000*D + 100*E + 10*F + G;
      var 10000..99999: XXABX = 11001*X + 100*A + 10*B;
      
      % main sum
      constraint CX * DEFG == XXABX;
      
      % partial products and subtractions
      constraint D * CX == HX /\ XX - HX == IJ;
      
      constraint E * CX == KM /\ IJA - KM == NP;
      
      constraint F * CX == QXR /\ NPB - QXR == S;
      
      constraint G * CX == SX;
      
      solve satisfy;
       
      % A = 6; B = 0; C = 2; D = 1; E = 4; F = 6; G = 1;
      % H = 2; I = 1; J = 0; K = 9; M = 2; N = 1; P = 4;
      % Q = 1; R = 8; S = 2; X = 3;
      % ----------
      % ==========
      % Finished in 271msec
      
      % The only full division sum is :
      
      %        1 4 6 1
      %     -----------     
      %  2 3)3 3 6 0 3
      %      2 3
      %      ---
      %      1 0 6
      %        9 2
      %      -----
      %        1 4 0
      %        1 3 8
      %        -----
      %            2 3
      %            2 3
      %            ===     
      % My two original numbers were therefore 23 and 33603.
      

      Like

  • Unknown's avatar

    Jim Randell 7:10 am on 30 March 2019 Permalink | Reply
    Tags:   

    Brainteaser 1510: Sum puzzle 

    From The Sunday Times, 18th August 1991 [link]

    In this addition sum nine digits are each represented by a different letter and the remaining one digit it represented in various places by nine letters.

    When the 47-figure number:

    INTHISADDITIONSUMNINEDIGITSAREEACHREPRESENTEDBY

    is added to the 46-digit number:

    ONELETTERANDONEDIGITISREPRESENTEDBYNINELETTERS

    the answer is the 47-figure number:

    TDODRRITECIPADAABSDLOTRSORANOHMIAGSAOTUDAYDOEOE

    What is the SOLUTION?

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

    [teaser1510]

     
    • Jim Randell's avatar

      Jim Randell 7:11 am on 30 March 2019 Permalink | Reply

      Potentially we could just feed the entire sum as a single expression to the [[ SubstitutedExpression() ]] solver from the enigma.py library, but generating and considering all the possibilities for the 15 digits in the terms of the sum is going to take some time.

      So to help it along I provided some additional expressions, which are the sums formed taking some of the columns (in pairs, to reduce the amount of typing), linked together by carries. After 9 pairs we have mentioned each letter at least once, and the solver finds the solution in less than 200ms.

      This run-file executes in 183ms.

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --distinct=""
      --answer="SOLUTION"
      
      # use lowercase symbols for carries
      --symbols="ABCDEGHILMNOPRSTUYabcdefghi"
      --invalid="0,IOT"
      --invalid="2-9,abcdefghi"
      
      # neaten up the output
      --template=""
      --solution="ABCDEGHILMNOPRSTUY"
      
      # the entire sum
      "INTHISADDITIONSUMNINEDIGITSAREEACHREPRESENTEDBY + ONELETTERANDONEDIGITISREPRESENTEDBYNINELETTERS = TDODRRITECIPADAABSDLOTRSORANOHMIAGSAOTUDAYDOEOE"
      
      # verify the digit count in the solution
      --code="v = lambda ds: sorted(ds.count(d) for d in irange(0, 9))"
      
      "v([A, B, C, D, E, G, H, I, L, M, N, O, P, R, S, T, U, Y]) == [1, 1, 1, 1, 1, 1, 1, 1, 1, 9]"
      
      # to speed things up we break down the sum in a sequence of partial
      # sums starting from the rightmost column (in groups of 2)
      "BY + RS + 0 = aOE"
      "ED + TE + a = bOE"
      "NT + ET + b = cYD"
      "SE + EL + c = dDA"
      "RE + IN + d = eTU"
      "EP + YN + e = fAO"
      "HR + DB + f = gGS"
      "AC + TE + g = hIA"
      "EE + EN + h = iHM"
      # by this stage we have used all the letters at least once
      

      Solution: SOLUTION = 78665482

      The assignment of letters to digits is:

      A=9 D=0 E=3 I=4 N=2 O=8 R=1 S=7 T=5; {BCGHLMPUY}=6

      so the sum is:

        42564790045482766242304645791339661361373253066
      +  8236355319208230464547136137325306624236355317
        -----------------------------------------------
      = 50801145364690996706851781928664967985609608383
        ===============================================
      

      This is the only solution, even if the 18 symbols are grouped together differently (i.e. not 9 symbols standing for 1 digit each, and 9 all standing for the same remaining digit).

      Like

      • Jim Randell's avatar

        Jim Randell 3:50 pm on 27 April 2023 Permalink | Reply

        Instead of splitting the sum manually we can use the [[ SubstitutedExpression.split_sum ]] solver from the enigma.py library to do it for us.

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

        #! python3 -m enigma -rr
        
        SubstitutedExpression.split_sum
        
        --distinct=""
        --invalid="0,IOT"
        --answer="SOLUTION"
        --split=4
        
        # the entire sum
        "INTHISADDITIONSUMNINEDIGITSAREEACHREPRESENTEDBY + ONELETTERANDONEDIGITISREPRESENTEDBYNINELETTERS = TDODRRITECIPADAABSDLOTRSORANOHMIAGSAOTUDAYDOEOE"
        
        # verify the digit count in the solution (9 digits have 1 symbol, 1 digit has 9 symbols)
        --code="check = lambda ds: multiset.from_seq(ds.count(d) for d in irange(0, 9)) == {1: 9, 9: 1}"
        --extra="check([A, B, C, D, E, G, H, I, L, M, N, O, P, R, S, T, U, Y])"
        
        # neaten up the output
        --template=""
        

        Like

  • Unknown's avatar

    Jim Randell 7:44 am on 29 March 2019 Permalink | Reply
    Tags:   

    Teaser 2929: My PIN numbers 

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

    Using all but one of the digits 0 to 9, and systematically replacing them by a letter, my PIN numbers become ONE, TWO, FIVE and SEVEN.

    These numbers are such that:

    ONE is odd;
    TWO is even;
    FIVE is odd and divisible by 5;
    SEVEN is divisible by 7;
    ONE + TWO + TWO = FIVE

    If I told you which digit was not used, you should be able to work out my PIN numbers.

    What PIN number is represented by SEVEN?

    [teaser2929]

     
    • Jim Randell's avatar

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

      This Python program links together a couple of routines from the enigma.py library. First we use the [[ SubstitutedExpression() ]] solver to find solutions to the alphametic expressions, then use use the [[ filter_unique() ]] function to select solutions that have a unique unused digit.

      It runs in 90ms.

      Run: [ @replit ]

      from enigma import (SubstitutedExpression, filter_unique, unpack, printf)
      
      # the conditions
      p = SubstitutedExpression(
        [
          "ONE % 2 = 1",
          "TWO % 2 = 0",
          "FIVE % 10 = 5",
          "SEVEN % 7 = 0",
          "ONE + TWO + TWO = FIVE",
        ],
        # X is the unused digit
        answer="(X, ONE, TWO, FIVE, SEVEN)",
        # leading zeros are allowed
        d2i={},
        # [optional] output the individual solutions to the conditions
        template="[X={X}, ONE={ONE} TWO={TWO} FIVE={FIVE} SEVEN={SEVEN}]",
        header="",
        solution="",
      )
      
      # find solutions unique by X
      rs = filter_unique(p.answers(), unpack(lambda x, p1, p2, p5, p7: x)).unique
      
      # output solutions
      for (x, p1, p2, p5, p7) in rs:
        printf("unused={x} -> ONE={p1:03d} TWO={p2:03d} FIVE={p5:04d} SEVEN={p7:05d}")
      

      Solution: SEVEN = 95452.

      Like

    • GeoffR's avatar

      GeoffR 4:11 pm on 29 March 2019 Permalink | Reply

      This programme finds four answers, three of which have the same unused digit 4, whilst the last answer has the unique unused digit 3, which gives the answer ie SEVEN = 95452

      
      % A Solution in MiniZinc
      include "globals.mzn";
      
      enum letters = {O, N, E, T, W, F, I, V, S};  
      array [letters] of var 0..9: v;
      
      constraint all_different(v);
      
      % ONE is odd
      constraint (100*v[O] + 10*v[N] + v[E]) mod 2 == 1;
      
      % TWO is even
      constraint (100*v[T]  + 10*v[W] + v[O] ) mod 2 == 0;
      
      % FIVE is odd and divisible by 5
      constraint (1000*v[F] + 100*v[I] + 10*v[V] + v[E]) mod 2 == 1 
      /\ (1000*v[F] + 100*v[I] + 10*v[V] + v[E]) mod 5 == 0;
      
      % ONE + TWO + TWO = FIVE
      constraint (100*v[O] + 10*v[N] + v[E]) + 2 * (100*v[T] + 10*v[W]
       + v[O] ) == (1000*v[F] + 100*v[I] + 10*v[V] + v[E]);
      
      % SEVEN is divisible by 7
      constraint (10000*v[S] + 1000*v[E] + 100*v[V] + 10*v[E]
       + v[N]) mod 7 == 0; 
      
      % Set of all ten digits
      var set of int: s1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
      
      % Set of digits used in the solution
      var set of int: s2 = {v[O], v[N], v[E], v[T], v[W],
       v[F], v[I], v[V], v[S]};
       
      % The unused digit
      var set of int: s3 == s1 diff s2;  
      
      solve satisfy;
      
      output [" ONE = " ++ show(v[O]), show(v[N]), show(v[E])]
      ++ ["  TWO = " ++ show(v[T]), show(v[W]), show(v[O])]
      ++ ["  FIVE = " ++ show(v[F]), show(v[I]), show(v[V]), show(v[E])]
      ++ ["\n SEVEN = " ++ show(v[S]),show(v[E]),show(v[V]),show(v[E]),show(v[N]) 
      ++ " - unused digit set: " ++ show(s3) ];
      
      %  ONE = 035  TWO = 820  FIVE = 1675  
      %  SEVEN = 95753 - unused digit set: 4..4
      %-----------------------------------------
      %  ONE = 095  TWO = 820  FIVE = 1735  
      %  SEVEN = 65359 - unused digit set: 4..4
      % -----------------------------------------
      %  ONE = 065  TWO = 830  FIVE = 1725  
      %  SEVEN = 95256 - unused digit set: 4..4
      %  ----------------------------------------
      %  ONE = 025  TWO = 860  FIVE = 1745 
      %  SEVEN = 95452 - unused digit set: 3..3 <<< answer
      % ----------
      % ==========
      % Finished in 234msec
      
      

      Like

  • Unknown's avatar

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

    Brain-Teaser 467: [Registration numbers] 

    From The Sunday Times, 10th May 1970 [link]

    There was a christening at our house last Sunday and there were three visitors’ cars in the drive.

    The car registration numbers of these three cars (disregarding any letters) each a three-digit prime number and among these numbers each of the digits 1 to 9 was used once only.

    This in itself was quite remarkable, but the sum of there three three-digit primes gave the three digit registration number of my own car.

    What were the three registration numbers of the visitors’ cars?

    This puzzle was originally published with no title.

    [teaser467]

     
    • Jim Randell's avatar

      Jim Randell 7:49 am on 28 March 2019 Permalink | Reply

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

      This run-file executes in 82ms.

      #! python -m enigma -rr
      
      SubstitutedExpression
      
      --digits="1-9"
      --answer="(ABC, DEF, GHI)"
      
      # the three 3-digit primes
      "is_prime(ABC)"
      "is_prime(DEF)"
      "is_prime(GHI)"
      
      # their sum is also a 3-digit number
      "ABC + DEF + GHI < 1000"
      
      # put them in order
      "ABC < DEF < GHI"
      

      Solution: The registration numbers are: 149, 263, 587.

      So, the setters registration number is 999.

      Like

    • GeoffR's avatar

      GeoffR 4:00 pm on 28 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);
      
      predicate is_prime(var int: x) = 
      x > 1 /\ forall(i in 2..1 + ceil(sqrt(int2float(ub(x))))) ((i < x) -> (x mod i > 0));
      
      var 100..999: ABC = 100*v[A] + 10*v[B] + v[C];
      var 100..999: DEF = 100*v[D] + 10*v[E] + v[F];
      var 100..999: GHI = 100*v[G] + 10*v[H] + v[I];
      var 100..999: XYZ;    % my car registration number
      
      constraint ABC + DEF + GHI == XYZ /\ GHI > DEF /\ DEF > ABC;
      
      constraint is_prime(ABC) /\ is_prime(DEF) /\ is_prime(GHI);
      
      solve satisfy;
      
      output[ "The three registration numbers of the visitors’ cars were " ++ show(ABC) 
      ++ ", " ++ show(DEF) ++ " and " ++ show(GHI) ]; 
      
      % The three registration numbers of the visitors’ cars were 149, 263 and 587
      
      
      

      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