/* Children's age problem in Picat. From https://javascript.plainenglish.io/youre-a-good-programmer-if-you-can-solve-this-problem-b3bfe66a962a """ If you can solve this problem and understand the dialogue between two programmers, you either work in a large IT company or should consider going there and surprising everyone. Once upon a time, two programmers who had not spoken for many years met. One asked the other: - They say you have children? - Yes, three sons. - And how old are they? - In total — 13. - What else can you say about them? - If you multiply their ages, you get the same number as the number of windows in that house over there. Having counted the windows of the house, the first one answers: - Great, but that’s not enough to answer. - I can add that the eldest son is red-haired. - Oh, well now everything is clear, that means, your sons (and then follows an answer in which the ages of each of the three children are named). How old were the children? And most importantly, how was the first one able to figure out their age from this seemingly illogical dialogue? """ The unique solution: The ages are 2, 2, and 9. Here's the output of the model: all = [11 = [1,1,11],20 = [1,2,10],27 = [1,3,9],32 = [1,4,8],35 = [1,5,7],36 = [1,6,6],36 = [2,2,9],48 = [2,3,8],56 = [2,4,7],60 = [2,5,6],63 = [3,3,7],72 = [3,4,6],75 = [3,5,5],80 = [4,4,5]] dups = [[36,[1,6,6]],[36,[2,2,9]]] all2 = [[2,2,9]] See below for some more comments on the thought/modeling process. Cf similar puzzles: - ages_of_three_children.pi - cheryls_birthday.pi - im_thinking_of_a_birthday.pi This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. % import sat. main => go. go ?=> % """ % - They say you have children? % - Yes, three sons. % """ N = 3, X = new_list(N), % """ % - And how old are they? % - In total — 13. % - What else can you say about them? % - If you multiply their ages, you get the same number as the number of windows in % that house over there. % """ X :: 1..13, sum(X) #= 13, % total is 13 M #= prod(X), % multiplication increasing(X), % Here are all possible solutions for the first part (before counting the number of windows) % [11 = [1,1,11],20 = [1,2,10],27 = [1,3,9],32 = [1,4,8],35 = [1,5,7],36 = [1,6,6],36 = [2,2,9],48 = [2,3,8],56 = [2,4,7],60 = [2,5,6],63 = [3,3,7],72 = [3,4,6],75 = [3,5,5],80 = [4,4,5]] All=solve_all(M=X), println(all=All.sort), nl, % """ % Having counted the windows of the house, the first one answers: % % - Great, but that’s not enough to answer. % """ % hakank: Since the addition (13) and product (M) did not give a unique answer, we % search for the answers that has the same product: 36. % % dups = [[36,[1,6,6]],[36,[2,2,9]]] Dups = [[Prod,Ages] : Prod=Ages in All, [1 : P=_A in All, P == Prod].len > 1], println(dups=Dups), % Restrict M to be 36 M #= Dups[1,1], % """ % - I can add that the eldest son is red-haired. % - Oh, well now everything is clear, that means, your sons (and then follows an % answer in which the ages of each of the three children are named). % """ % Ensure that the oldest is not a twin/triplet nl, X[2] #< X[3], % all2 = [[2,2,9]] All2 = solve_all(X), println(all2=All2), nl, fail, % Ensure a unique solution nl. go => true. /* Variant with list comprehension all = [11 = [1,1,11],20 = [1,2,10],27 = [1,3,9],32 = [1,4,8],35 = [1,5,7],36 = [1,6,6],36 = [2,2,9],48 = [2,3,8],56 = [2,4,7],60 = [2,5,6],63 = [3,3,7],72 = [3,4,6],75 = [3,5,5],80 = [4,4,5]] dups = [[36,[1,6,6]],[36,[2,2,9]]] sol = [[2,2,9]] */ go2 ?=> All = [A*B*C=[A,B,C] : C in 1..13, B in 1..C, A in 1..B, A+B+C == 13], println(all=All.sort), Dups = [[Prod,Ages] : Prod=Ages in All, [1 : P=_A in All, P == Prod].len > 1], println(dups=Dups), Sol = [Ages : [_,Ages] in Dups, Ages[2] < Ages[3]], println(sol=Sol), fail, nl. /* Generating similar problems. For reasonable children's ages there is only one solution: all = [11 = [1,1,11],20 = [1,2,10],27 = [1,3,9],32 = [1,4,8],35 = [1,5,7],36 = [1,6,6],36 = [2,2,9],48 = [2,3,8],56 = [2,4,7],60 = [2,5,6],63 = [3,3,7],72 = [3,4,6],75 = [3,5,5],80 = [4,4,5]] dups = [[36,[1,6,6]],[36,[2,2,9]]] all2 = [[2,2,9,13,36]] s = 13 m = 36 I.e. the children's ages are 2, 2, and 9. However, for older people there is one other solution, namely when the total is 294 all = [777600 = [54,120,120],785400 = [55,119,120],792960 = [56,118,120],793016 = [56,119,119], ... ,940896 = [96,99,99],940900 = [97,97,100],941094 = [97,98,99],941192 = [98,98,98]] dups = [[909792,[78,108,108]],[909792,[81,96,117]]] all2 = [[81,96,117,294,909792]] s = 294 m = 909792 I.e. the persons ages are 81, 96, and 117. (Though I think that the scenario of the problem should be changed a little...) * For 4 children there are some variants all = [9 = [1,1,1,9],16 = [1,1,2,8],21 = [1,1,3,7],24 = [1,1,4,6],25 = [1,1,5,5],28 = [1,2,2,7],36 = [1,2,3,6],40 = [1,2,4,5],45 = [1,3,3,5],48 = [1,3,4,4],48 = [2,2,2,6],60 = [2,2,3,5],64 = [2,2,4,4],72 = [2,3,3,4],81 = [3,3,3,3]] dups = [[48,[1,3,4,4]],[48,[2,2,2,6]]] all2 = [[1,3,4,4,12,48]] s = 12 m = 48 all = [11 = [1,1,1,11],20 = [1,1,2,10],27 = [1,1,3,9],32 = [1,1,4,8],35 = [1,1,5,7],36 = [1,1,6,6],36 = [1,2,2,9],48 = [1,2,3,8],56 = [1,2,4,7],60 = [1,2,5,6],63 = [1,3,3,7],64 = [2,2,2,8],72 = [1,3,4,6],75 = [1,3,5,5],80 = [1,4,4,5],84 = [2,2,3,7],96 = [2,2,4,6],100 = [2,2,5,5],108 = [2,3,3,6],120 = [2,3,4,5],128 = [2,4,4,4],135 = [3,3,3,5],144 = [3,3,4,4]] dups = [[36,[1,1,6,6]],[36,[1,2,2,9]]] all2 = [[1,1,6,6,14,36]] s = 14 m = 36 * 5 children all = [9 = [1,1,1,1,9],16 = [1,1,1,2,8],21 = [1,1,1,3,7],24 = [1,1,1,4,6],25 = [1,1,1,5,5],28 = [1,1,2,2,7],36 = [1,1,2,3,6],40 = [1,1,2,4,5],45 = [1,1,3,3,5],48 = [1,1,3,4,4],48 = [1,2,2,2,6],60 = [1,2,2,3,5],64 = [1,2,2,4,4],72 = [1,2,3,3,4],80 = [2,2,2,2,5],81 = [1,3,3,3,3],96 = [2,2,2,3,4],108 = [2,2,3,3,3]] dups = [[48,[1,1,3,4,4]],[48,[1,2,2,2,6]]] all2 = [[1,1,3,4,4,13,48]] s = 13 m = 48 all = [10 = [1,1,1,1,10],18 = [1,1,1,2,9],24 = [1,1,1,3,8],28 = [1,1,1,4,7],30 = [1,1,1,5,6],32 = [1,1,2,2,8],42 = [1,1,2,3,7],48 = [1,1,2,4,6],50 = [1,1,2,5,5],54 = [1,1,3,3,6],56 = [1,2,2,2,7],60 = [1,1,3,4,5],64 = [1,1,4,4,4],72 = [1,2,2,3,6],80 = [1,2,2,4,5],90 = [1,2,3,3,5],96 = [1,2,3,4,4],96 = [2,2,2,2,6],108 = [1,3,3,3,4],120 = [2,2,2,3,5],128 = [2,2,2,4,4],144 = [2,2,3,3,4],162 = [2,3,3,3,3]] dups = [[96,[1,2,3,4,4]],[96,[2,2,2,2,6]]] all2 = [[1,2,3,4,4,14,96]] s = 14 m = 96 * 6 children all = [9 = [1,1,1,1,1,9],16 = [1,1,1,1,2,8],21 = [1,1,1,1,3,7],24 = [1,1,1,1,4,6],25 = [1,1,1,1,5,5],28 = [1,1,1,2,2,7],36 = [1,1,1,2,3,6],40 = [1,1,1,2,4,5],45 = [1,1,1,3,3,5],48 = [1,1,1,3,4,4],48 = [1,1,2,2,2,6],60 = [1,1,2,2,3,5],64 = [1,1,2,2,4,4],72 = [1,1,2,3,3,4],80 = [1,2,2,2,2,5],81 = [1,1,3,3,3,3],96 = [1,2,2,2,3,4],108 = [1,2,2,3,3,3],128 = [2,2,2,2,2,4],144 = [2,2,2,2,3,3]] dups = [[48,[1,1,1,3,4,4]],[48,[1,1,2,2,2,6]]] all2 = [[1,1,2,2,2,6,14,48]] s = 14 m = 48 all = [10 = [1,1,1,1,1,10],18 = [1,1,1,1,2,9],24 = [1,1,1,1,3,8],28 = [1,1,1,1,4,7],30 = [1,1,1,1,5,6],32 = [1,1,1,2,2,8],42 = [1,1,1,2,3,7],48 = [1,1,1,2,4,6],50 = [1,1,1,2,5,5],54 = [1,1,1,3,3,6],56 = [1,1,2,2,2,7],60 = [1,1,1,3,4,5],64 = [1,1,1,4,4,4],72 = [1,1,2,2,3,6],80 = [1,1,2,2,4,5],90 = [1,1,2,3,3,5],96 = [1,1,2,3,4,4],96 = [1,2,2,2,2,6],108 = [1,1,3,3,3,4],120 = [1,2,2,2,3,5],128 = [1,2,2,2,4,4],144 = [1,2,2,3,3,4],160 = [2,2,2,2,2,5],162 = [1,2,3,3,3,3],192 = [2,2,2,2,3,4],216 = [2,2,2,3,3,3]] dups = [[96,[1,1,2,3,4,4]],[96,[1,2,2,2,2,6]]] all2 = [[1,1,2,3,4,4,15,96]] s = 15 m = 96 */ go3 ?=> nolog, member(N,2..6), nl, println(n=N), member(S,1..100), X = new_list(N), X :: 1..100, S #= sum(X), M #= prod(X), increasing(X), All=solve_all($[ff,split],M=X), Dups = [[Prod,Ages] : Prod=Ages in All, [1 : P=_A in All, P == Prod].len > 1], % There's a single duplicated multiplier Dups.len > 1, [D[1] : D in Dups].remove_dups.len == 1, M #= Dups[1,1], X[2] #< X[3], % There is a unique solution All2 = solve_all(X ++ [S,M]), All2.len == 1, println(all=All.sort), nl, println(dups=Dups), nl, println(all2=All2), println(s=S), println(m=M), nl, fail, % Ensure a unique solution nl. go3 => true.