Family Riddle problem with Prolog

2024-01-12

My #prolog solution for “Family Riddle” proposed by dmcommunity.org challenge Jan 2024.

Let’s assume that Rene and Leo are both heads of household, and, what a coincidence, both families include three girls and three boys. The youngest child in Leo’s family is a girl, and in Rene’s family, a little girl has just arrived. In other words, there is a girl in Rene’s family whose age is less than one year. Neither family includes any twins, nor any children closer in age than a year. All the children are under age ten. In each family, the sum of the ages of the girls is equal to the sum of the ages of the boys; in fact, the sum of the squares of the ages of the girls is equal to the sum of the squares of the ages of the boys. The sum of the ages of all these children is 60.

My solution (without duplicates / permutations): the ages of children of the same sex are ordered.

?- findall([LeoBoys,LeoGirls,ReneBoys,ReneGirls], sol([LeoBoys,LeoGirls,ReneBoys,ReneGirls]), Solutions), length(Solutions, Tot).
Solutions = [[[4, 5, 9], [3, 7, 8], [1, 3, 8], [0, 5, 7]]],
Tot = 1.

Below the code


max_age(9).
sum_age(60).
count_same_sex(3).

constraints_family_same_sex(L):-
    max_age(MaxAge),
    count_same_sex(N),
    %% both families include three girls and three boys.
    length(L, N),
    %% All the children are under age ten
    L ins 0..MaxAge,
    %% ages in sorted order 
    ordered_list(L).

constraints_family(Boys, Girls):-
    sum_list(Boys, Sum),
    sum_list(Girls, Sum),
    sum_square_list(Boys, SumS),
    sum_square_list(Girls, SumS).

sum_list([E|L], Sum):-
    sum_list(L, SumL),
    Sum #= E + SumL.
sum_list([], 0).

sum_square_list([E|L], Sum):-
    sum_square_list(L, SumL),
    Sum #= E ^ 2 + SumL.
sum_square_list([], 0).

ordered_list([E1,E2|L]):-
    E1 #=< E2,
    ordered_list([E2|L]).
ordered_list([_E]).
ordered_list([]).

sol([LeoBoys, LeoGirls, ReneBoys, ReneGirls]):-    
    %% All the children are under age ten
    %% both families include three girls and three boys.
    constraints_family_same_sex(LeoBoys),
    constraints_family_same_sex(LeoGirls),
    constraints_family_same_sex(ReneBoys),
    constraints_family_same_sex(ReneGirls),

    %% in Rene’s family, a little girl has just arrived
    ReneGirls = [0|_],

    %% The youngest child in Leo’s family is a girl
    LeoBoys = [LB1|_RestLeoBoys],
    LeoGirls = [LG1|_RestLeoGirls],
    LG1 #< LB1,

    append(LeoBoys, LeoGirls, LeoList),
    append(ReneBoys, ReneGirls, ReneList),
    append(LeoList, ReneList, AllChildren),
    
    %% Neither family includes any twins, nor any children closer in age than a year
    all_distinct(LeoList),
    all_distinct(ReneList),
    
    %% The sum of the ages of all these children is 60.
    sum_age(SumAge),
    sum_list(AllChildren, SumAge),


    %% In each family, the sum of the ages of the girls is equal to the sum of the ages of the boys
    constraints_family(LeoBoys, LeoGirls),
    constraints_family(ReneBoys, ReneGirls),
    
    label(AllChildren).

Enter your instance's address


More posts like this

Stable Marriage Problem with Prolog

2024-06-07 | #programming #prolog

My #prolog solution for Stable Marriage Problem proposed by dmcommunity.org challenge Jun 2024. Given n men and n women, where each person has ranked all members of the opposite sex in order of preference, marry the men and women together such that there are no two people of opposite sex who would both rather have each other than their current partners.

Continue reading 