/* Rotating discs in Picat. From Jean-Luis Lauriere's ALICE paper "A Language and a Program for Stating and Solving Combinatorial Problems" (1978), page 84f: """ Banerji proposed a discs problem: four concentric discs are divided into eight valued zones; the question is to turn the discs round so that each octant counts up to the same value of 12. """ This program was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ import cp. main => go. go => N = 8, % 8 discs NumDiscs = 4, % Data, the discs V = [[2,1,3,4,2,5,1,3], [3,2,3,4,1,3,4,5], [3,4,5,3,3,2,2,1], [5,1,5,3,4,3,2,4]], % decision variables % the rotation of each disc Rot = new_list(NumDiscs), Rot :: 0..N-1, foreach(J in 1..N) sum( [T : I in 1..NumDiscs, R #= 1+((Rot[I]+J-1) mod N), matrix_element(V,I, R,T)]) #= 12 end, % symmetry breaking Rot[1] #= 0, solve(Rot), println(rot=Rot), foreach(J in 1..N) printf("zone %d: %w\n",J,[V[I,1+((Rot[I]+J-1) mod N)] : I in 1..NumDiscs]) end, nl, fail, nl.