New Scientist Enigma 544b – Little Puzzlers
by Keith Austin
From Issue #1696, 23rd December 1989
Amy, Beth, Jo and Meg decided to give each other pots of marmeelade for Christmas. Each girl made a number of pots and then divided her pots into three piles, which were not necessarily equal; then she wrapped up each pile, labelled each parcel, and put them under the Christmas tree. The total number of pots involved was between 50 and 100.
We will let the letters A, B, C, …, I stand for the digits 1, 2, 3 , …, 9 in some order. Amy gave D/F of her pots to Jo, and C/B to Meg. Beth gave H/G of her pots to Amy, H/A to Jo, and D/G to Meg. Jo gave F/G of her pots to Amy. Meg gave A/B of her pots to Beth, and D/H to Jo.
On Christmas day, each girl opened the three parcels she had received. Amy received H/E of her pots from Beth, and F/E from Jo. Jo received D/I of her pots from Amy, D/H from Beth and D/A from Meg
Note that all the fractions were in reduced form before letters were substituted (1/2 and 2/3 are in reduced form, whereas 4/8 and 6/9 are not).
What was the total number of pots that were given?

Brian Gladman permalink123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118from itertools import combinations, permutationsfrom math import gcd# check that a fraction x / y is proper and in lowest termsis_prf = lambda x, y: x < y and gcd(x, y) == 1# sum two fractions input and returned as pairs# where (t, b) represents the fraction t/bdef sum_frac(x, y):tr, br = x[0] * y[1] + y[0] * x[1], x[1] * y[1]g = gcd(tr, br)return tr // g, br // g# check that <n> multipled by a set of fractions (fs) gives# only integers and, if so, return them (otherwise None)def check_int(n, fs):if any((n * t) % b for t, b in fs):return Nonereturn tuple(n * t // b for t, b in fs)# use combinations for these since D < H < A < Bfor c in combinations(range(1, 10), 4):D, H, A, B = c# check the fractionsif not (is_prf(D, H) and is_prf(H, A) and is_prf(A, B)):continue# use permutations for the remainderfor p in permutations(set(range(1, 10)).difference(c)):C, E, F, G, I = p# check the remaining fractionsif not (is_prf(D, A) and is_prf(D, F) and is_prf(D, G) andis_prf(D, I) and is_prf(H, E) and is_prf(H, G) andis_prf(F, G) and is_prf(F, E) and is_prf(C, B)):continue# Beth: H/G to Amy, H/A to Joe, D/G to Megbt_ajm = ((H, G), (H, A), (D, G))if sum_frac(bt_ajm[0], sum_frac(bt_ajm[1], bt_ajm[2])) != (1, 1):continue# Joe : D/I from Amy, D/H from Beth, D/A from Megjf_abm = ((D, I), (D, H), (D, A))if sum_frac(jf_abm[0], sum_frac(jf_abm[1], jf_abm[2])) != (1, 1):continue# Beth: H/G to Amy, H/A to Joe, D/G to Meg# try Beth's number of potsfor bp in range(1, 101):bt = check_int(bp, bt_ajm)if bt is None:continue# Amy: D/F to Jo, C/B to Megu, v = (D, F), (C, B)t, b = sum_frac(u, v)# check that Beth gets someif not (t and t < b):continueat_bjm = ((b  t, b), u, v)# try Amy's number of potsfor ap in range(1, 101  bp):at = check_int(ap, at_bjm)if at is None:continue# Meg: A/B to Beth, D/H to Joeu, v = (A, B), (D, H)t, b = sum_frac(u, v)# check that Amy gets someif not (t and t < b):continuemt_abj = ((b  t, b), u, v)# try Meg's number of potsfor mp in range(1, 101  bp  ap):# all pots given must be integersmt = check_int(mp, mt_abj)if mt is None:continue# Joe: F/G to Amy# consider the pots Joe gives to Bethfor x in range(1, G  F):jt_abm = (F, G), (x, G), (G  x, G)# try Joe's number of potsfor jp in range(1, 101  ap  bp  mp):# all pots given must be integersjt = check_int(jp, jt_abm)if jt is None:continue# the total pots is at least 50if sum((at + bt + jt + mt)) < 50:continue# the number of pots received by Amy and Joeag = (bt[0], jt[0], mt[0])jg = (at[1], bt[1], mt[2])sa, sj = sum(ag), sum(jg)# Amy : H/E from Beth, F/E from Joeif not (ag[0] * E == sa * H and ag[1] * E == sa * F):continue# Joe : D/I from Amy, D/H from Beth, D/A from Megif not (jg[0] * I == jg[1] * H == jg[2] * A == sj * D):continuesm = sum((ap, bp, jp, mp))print(f"pots total {sm} (a={at}, b={bt}, j={jt}, m={mt})")print(f"A={A} B={B} C={C} D={D} E={E} F={F} G={G} H={H} I={I}\n")