Tagged: by: Quentin Fowler Toggle Comment Threads | Keyboard Shortcuts

  • Unknown's avatar

    Jim Randell 10:08 am on 20 December 2022 Permalink | Reply
    Tags: by: Quentin Fowler   

    Teaser 1848: Double celebration 

    From The Sunday Times, 15th February 1998 [link]

    It was quite a year. I’d already had my 60th birthday, and my wife Margaret was due to have hers later in the year. The following year was our 10th wedding anniversary. But all that is beside the point … almost.

    By her first marriage, Margaret had two daughters. By an amazing coincidence, Helen was born on Margaret’s birthday, and then, two years later, Joanna was born on Margaret’s and Helen’s birthday. Furthermore, Margaret and Helen were both born on the same day of the week… but if I had told you how old Margaret was when Helen was born you could have worked that out for yourself.

    Now, the question is…

    What was the double celebration that was due to take place later in the year?

    This puzzle was the first to use the name Teaser (which has continued up to the present). Prior to this they were named Brainteaser (1982 – 1998) (and before that Brain teaser (1981 – 1982) and Brain-Teaser (1961 – 1981)).

    [teaser1848]

     
    • Jim Randell's avatar

      Jim Randell 10:10 am on 20 December 2022 Permalink | Reply

      Originally I considered that the setter (recounting the story) and his wife must be born sometime between 1875 and 1937. But if we consider the full range the puzzle becomes unsolvable. So instead I started from 1901.

      Since the only possible multiple celebration we know about is Margaret’s 60th birthday with one (or more) of the daughters, I am assuming we need to work out possible ages for the daughters.

      Instead of testing every day in every year I choose two representative dates, one before any potential leap day (I chose 1st January) and one after any potential leap day (I chose 1st March).

      This Python program runs in 57ms. (Internal runtime is 983µs).

      Run: [ @replit ]

      from datetime import date
      from enigma import (cproduct, irange, diff, printf)
      
      # record ages that have the same day of the week, and those that do not
      same_dow = set()
      diff_dow = set()
      
      # consider birth dates for M
      for (y, m) in cproduct([irange(1901, 1937), (1, 3)]):
        M = date(y, m, 1)
        M_dow = M.isoweekday()
        # consider M's age at the time of H's birth
        for d in irange(18, 51):
          H = date(y + d, m, 1)
          if H is None: continue
          if H.isoweekday() == M_dow:
            same_dow.add(d)
          else:
            diff_dow.add(d)
      
      # look for ages that always give the same day of the week
      for d in diff(same_dow, diff_dow):
        H = 60 - d
        J = H - 2
        printf("d={d}: M=60 -> H={H} J={J}")
      

      Solution: The double celebration was Margaret’s 60th birthday and Joanna’s 30th birthday.

      The only possible age difference that guarantees the mother and child are born on the same day is 28 years (providing we don’t span 1900, which was not a leap year).

      So Helen was born on Margaret’s 28th birthday, and Joanna was born 2 years later on Margaret’s 30th birthday.

      Hence when Margaret is 60, Helen will be 32 and Joanna will be 30.

      Like

  • Unknown's avatar

    Jim Randell 1:03 pm on 13 December 2022 Permalink | Reply
    Tags: by: Quentin Fowler   

    Teaser 2001: Unfamiliar territory 

    From The Sunday Times, 21st January 2001 [link]

    I was forced to make an emergency landing somewhere in Latin America. I got out of the plane, crossed a terrain interrupted by a higgledy-piggledy coating of identical bright marble cubes and found myself in a town. I learnt that the citizens had 10 different characters for digits. I then spotted what I took to be the plinth for a statue; it consisted of six layers. I learnt that each layer was made up of one solid square of cubes like those I had seen earlier. Beside this edifice was what I took to be an explanatory notice; included in it was the following, which I was told was a list of the number of cubes in each successive layer:

    ICNGTC
    EEAGTR
    RTGSEG
    IIIGNAE
    ERGINNO
    RAIGGSS

    My informant told me I should be able to work out the value of each character.

    “Thank you for that”, I said, “but can you tell me the name of your country?”

    “Why yes”, he replied, “you are now in 86997 321542387

    Where did I make my forced landing?

    Teaser 2001 was originally published in the year 2001. It is the only Teaser puzzle to have this property.

    [teaser2001]

     
    • Jim Randell's avatar

      Jim Randell 1:04 pm on 13 December 2022 Permalink | Reply

      We can use the [[ SubstitutedExpression() ]] solver from the enigma.py library to find the assignments of letters to digits, and then use the [[ translate() ]] function to decode the required answer.

      This Python program runs in 68ms. (Internal runtime is 17.9ms).

      Run: [ @replit ]

      from enigma import (SubstitutedExpression, sprintf as f, translate, printf)
      
      # the following are encoded square numbers
      sqs = "ICNGTC EEAGTR RTGSEG IIIGNAE ERGINNO RAIGGSS".split()
      
      # construct the alphametic puzzle
      p = SubstitutedExpression(list(f("is_square_p({x})") for x in sqs))
      
      # solve it
      for s in p.solve(verbose=0):
        # map digits (as strings) to letters
        r = dict((str(v), k) for (k, v) in s.items())
        # decode the phrase
        t = translate("86997 321542387", r)
        # output the solution
        printf("answer = {t}")
      

      Solution: The plane landed in: TERRA INCOGNITA.

      And the squares are:

      ICNGTC = 312481 = 559²
      EEAGTR = 667489 = 817²
      RTGSEG = 984064 = 992²
      IIIGNAE = 3334276 = 1826²
      ERGINNO = 6943225 = 2635²
      RAIGGSS = 9734400 = 3120²

      The answer published with Teaser 2003 says: “TERRA INCOGNITO (sic)”, although clearly each word of the answer must end with the same letter.

      Like

    • GeoffR's avatar

      GeoffR 5:33 pm on 13 December 2022 Permalink | Reply

      
      % A Solution in MiniZinc 
      include "globals.mzn";
      
      var 1..9:I; var 0..9:C; var 0..9:N; var 0..9:G; var 0..9:T; 
      var 1..9:E; var 0..9:A; var 1..9:R; var 0..9:S; var 0..9:O; 
      
      constraint all_different ([I, C, N, G, T, E, A, R, S, O]);
      
      predicate is_sq(var int: y) =
      exists(z in 1..ceil(sqrt(int2float(ub(y))))) (z*z = y );
      
      function var int: num6 (var int: u, var int: v, var int: w, var int: x, 
      var int: y, var int: z) = 100000*u + 10000*v + 1000*w + 100*x + 10*y + z;
      
      function var int: num7 (var int: t,var int: u, var int: v, var int: w, var int: x, 
      var int: y, var int: z) = 1000000*t + 100000*u + 10000*v + 1000*w + 100*x + 10*y + z;
      
      % Three 6-digit squares
      var 100000..999999:ICNGTC = num6(I, C, N, G, T, C);
      var 100000..999999:EEAGTR = num6(E, E, A, G, T, R);
      var 100000..999999:RTGSEG = num6(R, T, G, S, E, G);
      constraint sum([is_sq(ICNGTC), is_sq(EEAGTR), is_sq(RTGSEG)]) == 3;
      
      % Three 7-digit squares
      var 1000000..9999999:IIIGNAE = num7(I, I, I, G, N, A ,E);
      var 1000000..9999999:ERGINNO = num7(E, R, G, I, N, N, O);
      var 1000000..9999999:RAIGGSS = num7(R, A, I, G, G, S, S);
      constraint sum([is_sq(IIIGNAE), is_sq(ERGINNO), is_sq(RAIGGSS)]) == 3;
      
      solve satisfy;
      
      output[ "[I,C,N,G,T,E,A,R,S,O] = " ++ show([I,C,N,G,T,E,A,R,S,O]) ];
      
      % [I, C, N, G, T, E, A, R, S, O] = 
      % [3, 1, 2, 4, 8, 6, 7, 9, 0, 5]
      % ----------
      % ==========
      % Landing Location is [8,6,9,9,7  3,2,1,5,4,2,3,8,7]
      %      -  which means [T E R R A  I N C O G N I T A]
      
      
      

      Like

    • GeoffR's avatar

      GeoffR 12:29 pm on 14 December 2022 Permalink | Reply

      A two-stage solution in Python. It finds the digits / letters representation first. It then forms a dictionary to translate the landing code, using the ‘translate’ function from the enigma.py library.

      
      from itertools import permutations
      from enigma import is_square, translate
      
      for p1 in permutations('1234567890', 5):
          I, C, N, G, T = p1
          if I == '0':continue
      
          # Three 6-digit squares
          ICNGTC = int(I + C + N + G + T + C)
          if not is_square(ICNGTC): continue
          q1 = set('1234567890').difference([I, C, N, G, T])
          for p2 in permutations(q1):
              E, A, R, S, O = p2
              if '0' in (E, R): continue
              EEAGTR = int(E + E + A + G + T + R)
              if not is_square(EEAGTR):continue
              RTGSEG = int(R + T + G + S + E + G)
              if not is_square(RTGSEG):continue
      
              # Three 7-digit squares
              IIIGNAE = int(I + I + I + G + N + A + E)
              if not is_square(IIIGNAE):continue
              ERGINNO = int(E + R + G + I + N + N + O)
              if not is_square(ERGINNO):continue
              RAIGGSS = int(R + A + I + G + G + S + S)
              if not is_square(RAIGGSS):continue
              
              # output letters/digits - for a dictionary
              print(f"'I'={I}, 'C'={C}, 'N'={N}, 'G'={G}, 'T'={T}")
              print(f"'E'={E}, 'A'={A}, 'R'={R}, 'S'={S}, 'O'={O}")
              # 'I'=3, 'C'=1, 'N'=2, 'G'=4, 'T'=8
              # 'E'=6, 'A'=7, 'R'=9, 'S'=0, 'O'=5
      
      # 2nd stage - use output to form a dictionary - digits to letters
      DL = { '1': 'C', '2': 'N', '3': 'I', '4': 'G', '5': 'O', \
             '6': 'E', '7': 'A', '8': 'T', '9': 'R', '0': 'S'}
      
      # Translate landing code
      t = translate("86997 321542387", DL)
      print(f"Answer = {t}")
      # Answer = TERRA INCOGNITA
      
      

      Like

  • Unknown's avatar

    Jim Randell 2:26 pm on 14 November 2021 Permalink | Reply
    Tags: by: Quentin Fowler   

    Teaser 2505: [Letter values] 

    From The Sunday Times, 26th September 2010 [link] [link]

    I have taken 15 letters of the alphabet and given each of them a numerical value. They are not all positive, they are not all whole numbers and they are not all different. In fact, four of the letters have the same positive value.

    Using these values, I can work out the total value of some words by adding up the values of their letters.

    So, ONE has total value 1, TWO has total value 2, and so on up to SEVENTEEN, which has total value 17.

    What is the value of NOUGHT?

    This puzzle was originally published with no title.

    [teaser2505]

     
    • Jim Randell's avatar

      Jim Randell 2:27 pm on 14 November 2021 Permalink | Reply

      See also: Teaser 1908, Teaser 2756, Enigma 1602, Enigma 1278, Enigma 1292.

      It turns out that choosing 2 symbols to be the same, and then checking for other values with the same value as the 2 we chose is much faster than trying all combinations of 4 symbols.

      The following Python program runs in 105ms.

      Run: [ @replit ]

      from enigma import (irange, int2words, union, matrix, subsets, trim, join, map2str, printf)
      
      # we are interested in the values of the words "one" ... "seventeen"
      words = dict((i, int2words(i)) for i in irange(1, 17))
      
      # determine symbols used
      symbols = sorted(union(words.values()))
      n = len(symbols)
      
      # a function for making equations
      eq = matrix.equation(symbols)
      
      eqs = list(eq(w, i) for (i, w) in words.items())
      
      # choose the first k symbols to have the same (positive) value
      k = 2
      for ss in subsets(trim(symbols, tail=4 - k), size=k, fn=list):
        s0 = ss[0]
        eqs_ = list(eq ({s0: -1, s: 1}) for s in ss[1:])
      
        try:
          vs = matrix.linear(eqs + eqs_)
        except ValueError:
          continue
      
        # check the shared value is positive, and used exactly 4 times
        m = dict(zip(symbols, vs))
        v = m[s0]
        sv = sorted(s for s in symbols if m[s] == v)
        if not (v > 0 and len(sv) == 4 and sv[:k] == ss): continue
      
        # output solution
        ans = sum(m[s] for s in 'nought')
        printf("nought={ans} {vs} {sv}",
          vs=map2str(m, sep=" ", enc="[]"),
          sv=join(sv, sep="=", enc="[]"),
        )
      

      Solution: NOUGHT = 23/2 (= 11.5).

      The values are:

      E = I = S = W = 0
      F = R = U = V = 5/2
      G = 15/2
      H = −5
      L = 4
      N = 9/2
      O = −7/2
      T = 11/2
      X = 6

      So the four letters that share a positive value are F, R, U, V.

      (E, I, S, W, also share a value, but this is zero).


      We immediately see that E = 0. (As 14 = 4 + 10, 16 = 6 + 10, 17 = 7 + 10), and then I = 0 (as 13 = 3 + 10). So we could exclude these from the letters we consider when we choose some of them to be the same, to give a slight speed improvement.

      This observation can also form the start of a manual solution.

      Like

      • Frits's avatar

        Frits 3:33 pm on 15 November 2021 Permalink | Reply

        @Jim, symbols[:n + k – 4] makes more sense to me. fi, now you miss the situation e, v, w and x being the same.

        Like

        • Jim Randell's avatar

          Jim Randell 3:45 pm on 15 November 2021 Permalink | Reply

          @Frits: Yes it should be [:n + k − 4].

          I might add a [[ trim(s, head, tail) ]] function to enigma.py to make it easier to avoid these “off-by-1” errors (which are all too easy to make with Python indices).

          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