From The Sunday Times, 8th November 1981 [link]
The exclusive Ichthyophage Club was invited to hold its annual dinner at a resort on the Costa Fortuna last summer. Several members accepted the invitation, and each was asked to bring one of the local seafood specialities as their contribution to the feast.
The fare consisted of:
• the local edible starfish, which has five legs,
• the squid, which has ten,
• and octopus.
Each guest provided one such creature, and in fact more people provided octopus than provided starfish.
A chef was hired locally. He arranged the food so that each guest received a plateful consisting of the same number of legs — at least one leg from each species — but no guest’s plate was made up in the same way as any other guest’s plate. In other words, no guest had the same combination of legs on his plate as any other guest did.
When the food had been arranged in this way, the chef was grieved to find that all the legs had been used, leaving no edible fragments for him to take home to his family.
How many guests were there?
How many brought starfish, how many brought squid, and how many brought octopus?
This puzzle is included in the book The Sunday Times Book of Brainteasers (1994).
[teaser1006]
Jim Randell 7:33 am on 12 April 2026 Permalink |
Here is a declarative solution using the [[
SubstitutedExpression]] solver from the enigma.py library.It runs in 134ms. (Internal runtime of the generated code is 41ms).
Run: [@codepad]
Solution: The prime number in Martha’s grid that is not a prime when reversed is 173.
As: 173 is prime, but 371 = 7 × 53.
Here are the grids:
The numbers in the grids are:
We can get a second set of grids by writing the rows of these grids as columns and vice versa.
LikeLike
Jim Randell 2:51 pm on 12 April 2026 Permalink |
Splitting out the condition that George and Martha’s grids differ in exactly one position, into multiple expressions, allows us to get a run-file with an internal run time of just 1.8ms.
The run time can be further reduced (to 1.3ms) with the observation that 5 cannot occur at the end of a prime, or at the beginning of a bi-directional prime.
LikeLiked by 1 person
Ruud 8:31 am on 12 April 2026 Permalink |
import istr primes13579 = {i for i in istr.primes(100, 1000) if all(c in [1, 3, 5, 7, 9] for c in i)} reversible_primes13579 = {i for i in primes13579 if i.reversed().is_prime()} def grid(number_reversible): for rows in istr.permutations(primes13579, 3): all8 = list(rows) for i in range(3): all8.append(rows[0][i] | rows[1][i] | rows[2][i]) all8.append(rows[0][0] | rows[1][1] | rows[2][2]) all8.append(rows[0][2] | rows[1][1] | rows[2][0]) if len(set(all8)) == 8: # all different? if all(n in primes13579 for n in all8) and sum(n in reversible_primes13579 for n in all8) == number_reversible: yield all8 georges = list(grid(number_reversible=8)) for martha in grid(number_reversible=7): for george in georges: diff = sum(g != m for g, m in zip(george[0] | george[1] | george[2], martha[0] | martha[1] | martha[2])) if diff == 1: for p in martha: if p not in reversible_primes13579: print(p) for g, m in zip(george[:3], martha[:3]): print(" ", g, m) print()LikeLiked by 1 person
GeoffR 5:20 pm on 12 April 2026 Permalink |
# ST 3316 by Claude AI from itertools import product sieve = bytearray([1]) * 1000 sieve[0] = sieve[1] = 0 for i in range(2, 32): if sieve[i]: sieve[i*i::i] = bytes(len(sieve[i*i::i])) ODD = (1,3,5,7,9) P = {t: sieve[100*t[0]+10*t[1]+t[2]] for t in product(ODD, repeat=3)} R = {t: sieve[100*t[2]+10*t[1]+t[0]] for t in product(ODD, repeat=3)} E = {t: P[t] and R[t] for t in product(ODD, repeat=3)} def search(check): found = [] for a,b,c in product(ODD, repeat=3): if not check[(a,b,c)]: continue for d,e,f in product(ODD, repeat=3): if not check[(d,e,f)]: continue for g,h,i in product(ODD, repeat=3): if (check[(g,h,i)] and check[(a,d,g)] and check[(b,e,h)] and check[(c,f,i)] and check[(a,e,i)] and check[(c,e,g)]): nums = {100*a+10*b+c, 100*d+10*e+f, 100*g+10*h+i, 100*a+10*d+g, 100*b+10*e+h, 100*c+10*f+i, 100*a+10*e+i, 100*c+10*e+g} if len(nums) == 8: found.append((a,b,c,d,e,f,g,h,i)) return found george = search(E) seen = set() for gg in george: for pos in range(9): for digit in ODD: if digit == gg[pos]: continue mg = list(gg); mg[pos] = digit a,b,c,d,e,f,g,h,i = mg tris = [(a,b,c),(d,e,f),(g,h,i),(a,d,g),(b,e,h),(c,f,i),(a,e,i),(c,e,g)] if not all(P[t] for t in tris): continue nums = [100*t[0]+10*t[1]+t[2] for t in tris] if len(set(nums)) != 8: continue flags = [R[t] for t in tris] if sum(flags) == 7: ans = nums[flags.index(False)] if ans not in seen: seen.add(ans) print(f"Grid: {mg[:3]} / {mg[3:6]} / {mg[6:]}") print(f" Odd prime out: {ans} (reversal {int(str(ans)[::-1])} is not prime)") print(f"\nAnswer: {sorted(seen)}")LikeLike
Jim Randell 6:27 pm on 12 April 2026 Permalink |
Claude doesn’t seem to believe that comments are useful in code.
LikeLike
Frits 9:08 am on 19 April 2026 Permalink |
Also a minor issue is that “mg = list(gg)” could/should have been done at a higher level.
LikeLike
GeoffR 6:34 pm on 12 April 2026 Permalink |
It depends on the prompt – I asked Claude AI to make the code short and fast, and it chose to leave the comments out.
LikeLike
Brian Gladman 3:23 pm on 13 April 2026 Permalink |
Perhaps you shouldn’t encourage its bad habits!
LikeLike
Frits 7:01 pm on 12 April 2026 Permalink |
Not considering reflections/rotations.
from itertools import permutations # 3-digit primes with odd digits P = [3, 5, 7] P += [x for x in range(11, 33, 2) if all(x % p for p in P)] P = {s for x in range(101, 1000, 2) if all(x % p for p in P) and set("13579").issuperset(s := str(x))} # reversable primes for George G = {p for p in P if p[::-1] in P} # return sequence of 3 rows, 3 columns and 2 diagonals def nums8(rs): seq = set(''.join(r) for r in rs) # add columns seq.update(list(''.join(c) for c in zip(*[list(r) for r in rs]))) # add diagonals seq.update((rs[0][0] + rs[1][1] + rs[2][2], rs[0][2] + rs[1][1] + rs[2][0])) return seq sols = set() # select reversable primes for George for rs in permutations(G, 3): rowsG = [list(r) for r in rs] # check the two diagonals for George d1, d2 = rs[0][0] + rs[1][1] + rs[2][2], rs[0][2] + rs[1][1] + rs[2][0] if any(x not in G for x in (d1, d2)): continue # check the columns for George colsG = list(''.join(c) for c in zip(*rowsG)) if any(c not in G for c in colsG): continue # check for 8 different numbers for George if len(nums8(rowsG)) != 8: continue # change one digit in George's grid in cell [r][c] for r in range(3): for c in range(3): rowsM = list(row.copy() for row in rowsG) # choose new digit value for v in "13579": if v == rowsG[r][c]: continue rowsM[r][c] = v # check for 8 different numbers for Martha if len(numsM := nums8(rowsM)) != 8: continue # all Martha's 8 numbers must also be prime if any(n not in P for n in numsM): continue # count number of reversed numbers not being prime np = [x for x in numsM if x[::-1] not in P] if len(np) != 1: continue # seven were prime sols.add(np[0]) print(f"answer: {' or '.join(sols)}")LikeLike