Brain-Teaser 6: [Family products]
From The Sunday Times, 2nd April 1961 [link]
Living next door to each other are two families each having three children. The product of the three ages in one family is equal to the product of those in the other family. Next month three of the six children, including the eldest, have birthdays, and at the end of the month the two products will again be equal.
None of the children has the same age either now or at the end of next month, and no child is older than twelve.
What are the ages in each family now?
This puzzle was originally published with no title.
[teaser6]
Jim Randell 11:19 am on 23 August 2020 Permalink |
This Python program runs in 55ms.
from enigma import (group, subsets, irange, multiply, printf) # collect triples of ages from 1 to 12, by their product ts = group(subsets(irange(1, 12), size=3), by=multiply) # we are only interested in products with multiple values ts = dict((k, v) for (k, v) in ts.items() if len(v) > 1) # choose the first product for (k1, vs1) in ts.items(): # choose the initial sets for (a1, b1) in subsets(vs1, size=2): # the ages are all different s1 = a1 + b1 if len(set(s1)) < 6: continue # choose the second product for (k2, vs2) in ts.items(): if not (k1 < k2): continue # choose the final sets for (a2, b2) in subsets(vs2, size=2, select="P"): # ages are still all different s2 = a2 + b2 if len(set(s2)) < 6: continue # and three of them differ by 1 ds = tuple(y - x for (x, y) in zip(s1, s2)) if not (ds.count(1) == 3 and ds.count(0) == 3): continue # including the max if not (max(s1) + 1 == max(s2)): continue # output solution printf("{k1} -> {a1} {b1}; {k2} -> {a2} {b2}")Solution: The current ages are: (1, 8, 9) and (3, 4, 6).
And 1×8×9 = 3×4×6 = 72.
At the end of next month the ages will be: (1, 9, 10) and (3, 5, 6), both giving products of 90.
LikeLike
Jim Randell 12:13 pm on 24 August 2020 Permalink |
A slightly shorter version:
from enigma import (irange, subsets, multiply, is_square, partitions, printf) # find 6 ages with a product that is square for s1 in subsets(irange(1, 12), size=6): p = is_square(multiply(s1)) if p is None: continue # split the ages into 2 sets for (a1, b1) in partitions(s1, 3): if multiply(a1) != p: continue # now increment 3 of the values for js in subsets(irange(0, 5), size=3): s2 = list(a1 + b1) for j in js: s2[j] += 1 # check the ages are still all different if len(set(s2)) < 6: continue # check the eldest is incremented if not (max(s2) == max(s1) + 1): continue # split the ages (a2, b2) = (s2[:3], s2[3:]) # check the products are still the same if not (multiply(a2) == multiply(b2)): continue # output solution printf("{p} -> {a1}, {b1}; {q} -> {a2}, {b2}", q=multiply(a2))LikeLike
GeoffR 5:27 pm on 23 August 2020 Permalink |
A part programmatic / part manual solution:
from itertools import permutations from collections import defaultdict D = defaultdict(list) # Family 1 ages are a,b,c and Family 2 ages are d,e,f # Allow for no child older than 12 after a 1 year increase for Q in permutations(range(1,12), 6): a, b, c, d, e, f = Q # make c the eldest child (is either c or f) if a < b and b < c and c > f and d < e and e < f: if a * b * c == d * e * f: # add result to dictionary, with product as key D[a * b * c] += [(a, b, c, d, e, f)] for k,v in D.items(): print(k,v) # Manual Assessment # A print-out of Dictionary D gives # the product first and the group of 6 family ages # 36 [(1, 4, 9, 2, 3, 6)] # 60 [(1, 6, 10, 3, 4, 5)] # 72 [(1, 8, 9, 3, 4, 6)] # 90 [(1, 9, 10, 3, 5, 6)] # 120 [(2, 6, 10, 3, 5, 8)] # 180 [(3, 6, 10, 4, 5, 9)] # The only group of three ages which can all be # increased by 1 are (8,9,4) in product 72 # to give (9,10,5) in product 90 with # eldest child's age increased by i year # # This gives (1,9,10) and (3,5,6) as the ages # of the two families now # # Note; # It appears that 120/180 products could have three 1 year # age increments ie (2,3,8) to become (3,4,9), # but there is no increase in the eldest # child's age, which is a condition, so invalidLikeLike
Frits 7:29 pm on 23 August 2020 Permalink |
from enigma import SubstitutedExpression, irange, seq_all_different p = SubstitutedExpression([ "A < D", # avoid reporting same solution twice "A < B", "B < C", "D < E", "E < F", "A*B*C == D*E*F", "b + c + d + e + f + g = 3", # addition bits "max(b,c,d,e,f,g) == 1", # bits are 0 or 1 "max(C, F) + 1 == max(C+d, F+g)", # eldest birthday "v([A+b,B+c,C+d,D+e,E+f,F+g])", # all different "(A+b)*(B+c)*(C+d) == (D+e)*(E+f)*(F+g)", ], verbose=0, digits=irange(0, 11), symbols="ABCDEFbcdefg", code="v = lambda x: seq_all_different(x)", distinct="ABCDEF", answer="(A,B,C,D,E,F,A+b,B+c,C+d,D+e,E+f,F+g,A*B*C,D*E*F, \ (A+b)*(B+c)*(C+d),(D+e)*(E+f)*(F+g))" ) # Print answers for (_, ans) in p.solve(verbose=0): print(f"Current:\nAges \ ({ans[0]},{ans[1]},{ans[2]}) product {ans[12]}, \ ({ans[3]},{ans[4]},{ans[5]}) product {ans[13]} \ \nEnd of the month: \nAges \ ({ans[6]},{ans[7]},{ans[8]}) product {ans[14]}, \ ({ans[9]},{ans[10]},{ans[11]}) product {ans[15]}") # Current: # Ages (1,8,9) product 72, (3,4,6) product 72 # End of the month: # Ages (1,9,10) product 90, (3,5,6) product 90LikeLike
GeoffR 10:05 am on 24 August 2020 Permalink |
Frits’ solution has given me an idea for a solution in MiniZinc.
i.e limiting the six addition digits to (0..1) range and the sum of the six additions to three
LikeLike