/* Magic sequence with "double list" problem in Picat. Cf the traditional magic sequence: http://www.dcs.st-and.ac.uk/~ianm/CSPLib/prob/prob019/spec.html """ A magic sequence of length n is a sequence of integers x0 . . xn-1 between 0 and n-1, such that for all i in 0 to n-1, the number i occurs exactly xi times in the sequence. For instance, 6,2,1,0,0,0,1,0,0,0 is a magic sequence since 0 occurs 6 times in it, 1 occurs twice, ... """ (See http://hakank.org/picat/magic_sequence.pi .) Inspiration of this model is from https://enigmaticcode.wordpress.com/2015/07/28/enigma-298-suspended-sentences/ This variant has two differences: - the problem is to figure out the following sentence: "In this sentence, the number of occurrences of the number 1 is ?, of 2 is ?, of 3 is ?, ....", i.e. where the number itself should be counted. Hence the name "double list". - the sequence can start with either 0 or 1 (using the Start variables) Model created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp,util. main => go. go ?=> Start = 1, N = 9, magic_sequence(N,Start,StartCoeff,Numbers,Sequence), println(startCoeff=StartCoeff), print_sequence(N,Start,StartCoeff,Numbers,Sequence), % fail, nl. go => true. go2 => foreach(N in 1..100,Start in 0..1) if magic_sequence(N,Start,StartCoeff,Numbers,Sequence) then print_sequence(N,Start,StartCoeff,Numbers,Sequence) else printf("N=%d, Start=%d: No solution\n\n", N, Start) end end, nl. print_sequence(N,Start,StartCoeff,Numbers,Sequence) => println([n=N,start=Start]), println('numbers '=Numbers), println('sequence'=Sequence), println(startCoeff=StartCoeff), println(sumSequence=sum(Sequence)), println([to_fstring("%d of %ds", Sequence[I+StartCoeff], Numbers[I+StartCoeff]) : I in Start..N-StartCoeff].join(", ")), nl. magic_sequence(N,Start, StartCoeff,Numbers, Seq) => if Start == 1 then StartCoeff = 0 else StartCoeff = 1 end, Sequence = new_list(N*2), Sequence :: Start..N-StartCoeff, % sum([Sequence[I+N+StartCoeff] : I in Start..N-StartCoeff]) #= 2*N, foreach(I in Start..N-StartCoeff) Sequence[I+N+StartCoeff] #= sum([ Sequence[J] #= I : J in 1..N*2 ]), Sequence[I+StartCoeff] #= I end, solve([degree,split], Sequence), Numbers = [Sequence[I+StartCoeff] : I in Start..N-StartCoeff], Seq = [Sequence[I+N+StartCoeff] : I in Start..N-StartCoeff].