Teaser 2661: Three clocks
From The Sunday Times, 22nd September 2013 [link] [link]
I have three digital clocks, each showing the time as a four-digit display “hhmm” on the 24-hour scale. One keeps perfect time, one runs fast at a constant rate (less than a minute per day) and the third runs slow at exactly the same rate. Every six months I simultaneously reset the faulty clocks to the correct time. Recently I noticed that each clock displayed the same collection of digits but in different orders. In fact, on the fast clock no digit was in the correct place.
What time did the correct clock show at that moment?
[teaser2661]
Jim Randell 8:22 am on 13 February 2024 Permalink |
If the clocks are reset every 6 months then that is at most 184 days apart. So the inaccurate clocks are less than 184 minutes adrift from the accurate clock.
This Python program collects together times that use the same digits but rearranged, and then looks for a collection of at least 3 different times, chooses a correct time, and looks for a fast time that is a derangement of the correct time. From this we calculate the difference window for the inaccurate clocks, and we can look for a corresponding slow time that appears in the same collection.
It runs in 67ms. (Internal runtime is 9.8ms).
Run: [ @replit ]
from enigma import (defaultdict, irange, cproduct, ordered, dot, printf) # collect possible times by digit content d = defaultdict(list) for (hh, mm) in cproduct([irange(0, 23), irange(0, 59)]): ds = divmod(hh, 10) + divmod(mm, 10) d[ordered(*ds)].append(ds) # digit position values (in minutes, left to right) pos = (600, 60, 10, 1) # look for sets of digits corresponding to at least 3 times for (k, vs) in d.items(): if len(vs) < 3: continue # choose the correct time for corr in vs: mc = dot(corr, pos) # choose a fast time for fast in vs: # which must be a derangement of corr if fast == corr or any(x == y for (x, y) in zip(fast, corr)): continue # calculate the window of difference (in minutes) md = (dot(fast, pos) - mc) % 1440 if md > 183: continue # look for possible slow times (difference may be +/- 1) for w in [-1, 0, +1]: ms = (mc - md + w) % 1440 (hh, mm) = divmod(ms, 60) slow = divmod(hh, 10) + divmod(mm, 10) if slow not in vs: continue # output solution printf("correct = {corr}; fast = {fast}; slow={slow}")Solution: The correct clock was showing: 2301.
And the inaccurate clocks are adrift from the accurate clock by 150 – 151 minutes.
For example, using fractional minutes we can suppose the accurate clock is showing:
If the time difference with the inaccurate clocks is 150.5 minutes (= 2h30.5m) then the fast clock is showing:
and the slow clock is showing:
Each display uses the digits: 0, 1, 2, 3.
LikeLike
Frits 4:39 am on 23 February 2024 Permalink |
I have a different version that matches Jim’s speed (but with more code).
from enigma import SubstitutedExpression # invalid digit / symbol assignments d2i = dict() for d in range(0, 10): vs = set() if d > 1: vs.update('X') if d > 2: vs.update('AFSW') if d > 5: vs.update('CHU') d2i[d] = vs # return time difference in minutes between h1:m1 and an earlier h2:m2 def diff_minutes(h1, m1, h2, m2): d = 60 * (h1 - h2) + m1 - m2 return d if d > 0 else 1440 + d # remove elements from list <s2> from list <s1> # eg diff_lists([1,3,1,2], [2,0,1]) results in [3,1] def diff_lists(s1, s2): for x in s2: if x in s1: s1.remove(x) return s1 # correct : AB:CD # fast : FG:HI # slow : ST:UV # the alphametic puzzle p = SubstitutedExpression( [ "AB < 24", # ----- logic for fast clock FG:HI ------ # speeding things up: check for <I> "(D + Z) % 10 in {A, B, C, D}", # add XYZ minutes for fast clock "0 < XYZ < 184", "(60 * AB + CD + XYZ) % 1440 = OPQR", "OPQR // 60 = FG", "OPQR % 60 = HI", # the same collection of digits "sorted([A, B, C, D]) == sorted([F, G, H, I])", # ----- logic for slow clock ST:UV ------ # 2 * correct = fast + slow + 1 - W with 0 <= W <= 2 "(2 * (60 * AB + CD) - (60 * FG + HI) - 1 + W) % 1440 = KLMN", "KLMN // 60 = ST", "KLMN % 60 = UV", # the same collection of digits "sorted([A, B, C, D]) == sorted([S, T, U, V])", ], answer="ABCD", d2i=d2i, # on the fast clock no digit was in the correct place distinct=("AF", "BG", "CH", "DI"), env=dict(diff_minutes=diff_minutes, diff_lists=diff_lists), reorder=0, verbose=0, # use 256 to see the generated code ) # print answers for ans in sorted(p.answers()): print(f"answer: {ans}")LikeLike