Teaser 3229: Fishy scales
From The Sunday Times, 11th August 2024 [link] [link]
For loads under 99.5 kg, my scales have three 7-segment digits. The left and centre digits show the weight; the right digit shows “r” for rounded to whole kg or “E” for exact kg. The examples show 69 kg rounded, and 0 kg exactly. Overload displays “888”.
The scales are accurate, but one of the segments in one of the digits is faulty and is always illuminated. For example, two fish boxes were recently loaded together and “68E” appeared. A fish slid off and “62E” appeared. A third box was added and “99E” appeared. The fallen fish was then put back in its box. Curiously, the display didn’t change. Then the first two boxes were removed. A new reading appeared, with rightmost digit “E”.
Find the reading displayed for the third box alone.
[teaser3229]










Jim Randell 7:21 am on 11 August 2024 Permalink |
The faulty segment must be lit in all the readings given, and the first likely scenario I tried gave a viable solution, so the puzzle was solved manually in a few minutes. However the following Python program performs an exhaustive exploration of the problem space.
The final digit of the display reads “E”, “r” or “8”, and it is not possible for a single incorrect segment to change one of these displays to a different viable digit. So all the readings must end in “E”, and so we are dealing with exact integer weights, less than 100 kg. This is enough to explore the problem space without requiring any additional analysis.
The following Python program runs in 72ms. (Internal runtime is 4.1ms).
from enigma import (irange, intersect, append, join, printf) # segments on a 7-segment display segs = { 0: {0, 1, 2, 4, 5, 6}, 1: {2, 5}, 2: {0, 2, 3, 4, 6}, 3: {0, 2, 3, 5, 6}, 4: {1, 2, 3, 5}, 5: {0, 1, 3, 5, 6}, 6: {0, 1, 3, 4, 5, 6}, 7: {0, 2, 5}, 8: {0, 1, 2, 3, 4, 5, 6}, 9: {0, 1, 2, 3, 5, 6}, 'E': {0, 1, 3, 4, 6}, 'r': {3, 4}, } # segment display for integer weight <w>, with digit <d> segment <s> always lit def display(w, d=None, s=None): if w > 99: return [segs[8]] * 3 ds = list(segs[k] for k in divmod(w, 10)) ds.append(segs['E']) # adjust the faulty segment if d is not None: ds[d] = append(ds[d], s) return ds # output a display (? for a mangled digit) def output(ds): r = dict((frozenset(v), k) for (k, v) in segs.items()) # reverse the segment map return join(r.get(frozenset(x), '?') for x in ds) # the given displays (d68E, d62E, d99E) = (display(x) for x in (68, 62, 99)) # choose the faulty segment for (d, xs) in enumerate(zip(d68E, d62E, d99E)): for s in intersect(xs): # consider the weight of box 1 and 2 (including the fish) for b12 in irange(2, 98): # display for (box 1 + box 2) is "68E" if display(b12, d, s) != d68E: continue # consider the weight of the fish for f in irange(1, b12 - 1): # display for (box 1 + box 2 - fish) is "62E" if display(b12 - f, d, s) != d62E: continue # consider the weight of box 3 for b3 in irange(1, 99 - b12): # display of (box 1 + box 2 - fish + box 3) is "99E" if display(b12 - f + b3, d, s) != d99E: continue # but display does not change if the fish is returned to its box if display(b12 + b3, d, s) != d99E: continue # final display is just b3 fsegs = display(b3, d, s) # output solution printf("{disp} = {fsegs} [d={d} s={s}; b12={b12} f={f} b3={b3}]", disp=output(fsegs))Solution: The reading for the third box alone was: “33E”.
The faulty segment is segment 2 (top right) of the second (middle) digit of the display.
The first two boxes together (including the fish) weigh 66 kg. The display (incorrectly) reads “68E”.
The fish weighs 4 kg, so when it is removed the total weight is 62 kg. The display (correctly) reads “62E”.
The third box weighs 33 kg, so when this is added the total weight is now 95 kg. The display (incorrectly) reads “99E”.
The fish is then returned to its box, so the total weight is now 99 kg. The display (correctly) reads “99E” (again).
The first 2 boxes (including the fish) are now removed, leaving only the third box. The display (correctly) reads “33E”.
LikeLike