/* Dinner problem (Martin Gardner) in Picat. Martin Gardner The Last Recreations, page 121 """ A woman plans to invite 15 friends to dinner. For 35 days she wants to have dinner with exactly three friends a day, and she wants to arrange the triplets so that each pair of friends will only come once. Is this arrangement possible? """ (This is of course a Steiner triplet problem.) This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go ?=> NumPersonsPerMeeting = 3, NumDays = 35, Persons = 15, Days = new_array(NumDays,NumPersonsPerMeeting), Days :: 1..Persons, % different triplets per day all_different($[Days[I,1]*100+Days[I,2]*10 + Days[I,3] : I in 1..NumDays]), % max 1 common person in each days foreach(I in 1..NumDays, J in 1..NumDays, I != J) % at most once sum([Days[I,K] #= Days[J,L] : K in 1..3, L in 1..3]) #<= 1 % exactly once % sum([Days[I,K] #= Days[J,L] : K in 1..3, L in 1..3]) #= 1 end, % symmetry breaking foreach(D in 1..NumDays) increasing_strict(Days[D]) end, lex2(Days), solve([ff,split],Days), println(days=Days), flush(stdout), fail, nl. go => true. % Port of MiniZinc's lex2.mzn % """ %-----------------------------------------------------------------------------% % Require adjacent rows and adjacent columns in the array 'x' to be % lexicographically ordered. Adjacent rows and adjacent columns may be equal. %-----------------------------------------------------------------------------% % """ % Note: This use lex_less/1. lex2(X) => Len = X[1].length, foreach(I in 2..X.length) lex_lt([X[I-1,J] : J in 1..Len], [X[I,J] : J in 1..Len]) end.