From The Sunday Times, 5th October 1980 [link]
Joe decided to utilise the garden see-saw to demonstrate the principles of balance, and of moments to, his family. Alf, Bert, Charlie, Doreen, Elsie and Fiona weighed 100, 80, 70, 60, 50 and 20 kilos respectively. The seesaw had three seats each side, positioned 1, 2 and 3 metres from the centre.
They discovered many ways of balancing using some or all of the family.
In one particular combination, with at most one person on each seat, one of the family not on the seesaw observed that the sum of the moments of all of the people on the seesaw was a perfect square.
“That’s right”, said Joe, “but, as you can see, it doesn’t balance — and what’s more, there’s nowhere you can sit to make it balance”.
“Wrong”, was the reply. “I could sit on someone’s lap”.
“True,” said Joe, “but only if you sit at the end”.
Which two would then be sitting together, and who else, if anyone, would be on the same side of the see-saw?
[To find the moment due to each person, multiply their distance from the centre by their weight. The sum of the moments on one side should equal the sum of those on the other if balance is to be achieved].
This puzzle is included in the book The Sunday Times Book of Brainteasers (1994).
[teaser950]
Jim Randell 5:21 pm on 6 June 2024 Permalink |
Very straightforward constructive solution.
This Python program runs in 57ms. (Internal runtime is 877µs).
from enigma import (primes, is_npalindrome, subsets, div, printf) # 3-digit palindromic primes scores = list(n for n in primes.between(100, 999) if is_npalindrome(n)) # choose 11 different scores for ss in subsets(scores, size=11): # calculate the mean avg = div(sum(ss), 11) # which is also in scores if avg and avg in scores: # output solution printf("{avg} -> {ss}")Solution: The two highest individual totals are 787 and 919.
The full list of totals is:
LikeLike
Ruud 6:41 pm on 6 June 2024 Permalink |
Very similar to @Jim Randell’s solution, but without enigma:
import sympy from itertools import combinations palindromic_primes_with_length_3 = [] for i in range(1, 1000): prime = sympy.prime(i) prime_as_str = str(prime) if len(prime_as_str) > 3: break if len(prime_as_str) == 3 and str(prime_as_str) == str(prime_as_str)[::-1]: palindromic_primes_with_length_3.append(prime) solutions = set() for scores in combinations(palindromic_primes_with_length_3, 11): average_score = sum(scores) / 11 if average_score in palindromic_primes_with_length_3: solutions.add((scores, int(average_score))) print(solutions)LikeLike
Frits 11:28 am on 7 June 2024 Permalink |
Sympy also has a primerange() method.
LikeLike
GeoffR 8:16 pm on 6 June 2024 Permalink |
% A Solution in MiniZinc include "globals.mzn"; var 100..999:A; var 100..999:B; var 100..999:C; var 100..999:D; var 100..999:E; var 100..999:F; var 100..999:G; var 100..999:H; var 100..999:I; var 100..999:J; var 100..999:K; constraint all_different([A,B,C,D,E,F,G,H,I,J,K]); predicate is_prime(var int: x) = x > 1 /\ forall(i in 2..1 + ceil(sqrt(int2float(ub(x))))) ((i < x) -> (x mod i > 0)); constraint A div 100 == A mod 10 /\ is_prime(A); constraint B div 100 == B mod 10 /\ is_prime(B); constraint C div 100 == C mod 10 /\ is_prime(C); constraint D div 100 == D mod 10 /\ is_prime(D); constraint E div 100 == E mod 10 /\ is_prime(E); constraint F div 100 == F mod 10 /\ is_prime(F); constraint G div 100 == G mod 10 /\ is_prime(G); constraint H div 100 == H mod 10 /\ is_prime(H); constraint I div 100 == I mod 10 /\ is_prime(I); constraint J div 100 == J mod 10 /\ is_prime(J); constraint K div 100 == K mod 10 /\ is_prime(K); var 1000..9999:asum; var 100..999:average; constraint asum == A+B+C+D+E+F+G+H+I+J+K; constraint average == asum div 11 /\ asum mod 11 == 0; constraint is_prime(average); constraint card( {average} intersect {A,B,C,D,E,F,G,H,I,J,K}) == 1; constraint increasing( [A,B,C,D,E,F,G,H,I,J,K]); solve satisfy; output["Scores are " ++ show([A,B,C,D,E,F,G,H,I,J,K]) ++ "\n" ++ "Average = " ++ show(average) ]; % Scores are [101, 131, 151, 181, 191, 313, 353, 373, 383, 787, 919] % Average = 353 % ---------- % ==========LikeLike
GeoffR 9:39 am on 7 June 2024 Permalink |
Shorter code, but still slow.
% A Solution in MiniZinc include "globals.mzn"; % Eleven cricket scores var 100..999:A; var 100..999:B; var 100..999:C; var 100..999:D; var 100..999:E; var 100..999:F; var 100..999:G; var 100..999:H; var 100..999:I; var 100..999:J; var 100..999:K; constraint all_different([A,B,C,D,E,F,G,H,I,J,K]); var 100..999:average; predicate is_pr_pal(var int: x) = x > 1 /\ forall(i in 2..1 + ceil(sqrt(int2float(ub(x))))) ((i < x) -> (x mod i > 0)) /\ x div 100 == x mod 10; constraint sum([is_pr_pal(A), is_pr_pal(B),is_pr_pal(C), is_pr_pal(D), is_pr_pal(E), is_pr_pal(F), is_pr_pal(G), is_pr_pal(H), is_pr_pal(I), is_pr_pal(J), is_pr_pal(K)]) == 11; constraint average == (A+B+C+D+E+F+G+H+I+J+K) div 11 /\ (A+B+C+D+E+F+G+H+I+J+K) mod 11 == 0; constraint is_pr_pal(average); constraint card( {average} intersect {A,B,C,D,E,F,G,H,I,J,K}) == 1; constraint increasing( [A,B,C,D,E,F,G,H,I,J,K]); solve satisfy; output["Scores are " ++ show([A,B,C,D,E,F,G,H,I,J,K]) ++ "\n" ++ "Average = " ++ show(average) ];LikeLike
GeoffR 9:57 pm on 6 June 2024 Permalink |
from enigma import is_prime from itertools import combinations scores = [x for x in range(100,999) if is_prime(x) \ if x // 100 == x % 10 ] for s in combinations(scores, 11): av, r = divmod(sum(s), 11) if r != 0: continue if av in scores and av //100 == av % 10: print(f"Average = {av}") print(f"Scores = {s}")LikeLike
Ruud 10:20 am on 7 June 2024 Permalink |
You can leave out the av // 100 == av % 10 test in the final if condition, as that’d guaranteed by the membership of scores.
LikeLike
Frits 10:17 am on 7 June 2024 Permalink |
Same number of iteratons. It also works if scores would have had exactly 11 items.
from itertools import combinations # prime numbers from 101-999 P = [3, 5, 7] P += [x for x in range(11, 100, 2) if all(x % p for p in P)] P = [x for x in range(101, 1000, 2) if all(x % p for p in P)] # 3-digit palindromic primes scores = {p for p in P if p // 100 == p % 10} assert (ln := len(scores)) >= 11 t = sum(scores) # choose scores outside the 11 for ss in combinations(scores, ln - 11): # calculate the average avg, r = divmod(t - sum(ss), 11) # which is also in scores if r or avg not in scores: continue print("answer", sorted(scores.difference(ss))[-2:])LikeLike