/* Circular numbers in Picat. Inspired by Rodolfo Kurchan from the CelebrationOfMind Hangout 2013 About http://www.youtube.com/watch?v=naPBXFtdoJs&feature=share&t=12m42s [But, I realized later, this has nothing to do with Rodolfo's talk. :-)] Numbers in a circle 0..n where the two neighbours must give sums of 0..n. For N=1..100 the following N has a solution: sols=[3,4,7,8,11,12,15,16,19,20,23,24,27,28,31,32,35,36,39,40,43,44,47,48,51,52,55,56,59,60,63,64,67,68,71,72,75,76,79,80,83,84,87,88,91,92,95,96,99,100] These are the N that either 0 or 3 modulo 4. The basic patterns are: n=18 n=19 X =[0,1,1,2,2,3,3,4,4,5,6,6,7,7,8,8,9,9,10] Sums=[1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,10] n=20 X =[0,1,1,2,2,3,3,4,4,5,6,6,7,7,8,8,9,9,10,10] Sums=[1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,10] n=21 n=22 I.e. X: [0,1,1,2,2,...N div 2, N div 2] Sums: [1,2,3...,N-1,N,N div 2] Another property of these numbers is (from http://oeis.org/A154708) """ Numbers a such that b and c exist with b <= a < c and a*(a+1)+b^2=c^2. """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ % import util. import cp. main => go. go => N = 11, circular_numbers(N), nl. go2 => Sols = [], foreach(N in 1..100) println(n=N), (circular_numbers(N) -> Sols := Sols ++ [N] ; true ) end, println(sols=Sols), nl. circular_numbers(N) => X = new_list(N), X :: 0..N, Sums = new_list(N), Sums :: 1..N, %% all_different(X), all_distinct(Sums), % all_different(Sums), foreach(I in 1..N-1) Sums[I] #= X[I] + X[I+1] end, Sums[N] #= X[N] + X[1], % symmetry breaking X[1] #= min(X), increasing(X), %% increasing(Sums), Vars = X ++ Sums, solve([ff,split],Vars), println('X '=X), println('Sums'=Sums), nl. increasing(List) => foreach(I in 2..List.length) List[I-1] #=< List[I] end.