/* Create the nonogram states in Picat. 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. /* State transition for [1,1,2,3]: zeroPositions=[2,4,7,11] 0 1 [1,2] % 1 (start state) 0: loop 1: goto 2 [3,0] % 2 zero after first "1" <- zero pos [3,4] % 3 [5,0] % 4 second "1" <- zero pos [5,6] % 5 [0,7] % 6 [8,0] % 7 <- zero pos [8,9] % 8 [0,10] % 9 [0,11] % 10 [11,0] % 11 (finish state) <- zero pos col2: 1) start with assigning all with 1+I 2) for all zero pos: assign 0 */ go => Pattern = [1,1,2,3], make_automatonX(Pattern), println("TEST:"), nl. make_automaton2(X,Pattern) => N = Pattern.length, Len = max(length([Pattern[I] : I in 1..N, Pattern[I] > 0]) + sum(Pattern),1), println(len=Len), Tmp = [0], NumStates = N+sum(Pattern), println(numStates=NumStates), C = 0, foreach(P in Pattern) foreach(I in 1..P) Tmp := Tmp ++ [1], C:= C+1 end, if C < NumStates - 2 then Tmp := Tmp ++ [0] end end, States = new_array(NumStates,2), States[NumStates,1] := NumStates, States[NumStates,2] := 0, foreach(I in 1..NumStates) if Tmp[I] == 0 then States[I,1] := I, States[I,2] := I+1 else if I < NumStates then if Tmp[I+1] = 1 then States[I,1] := 0, States[I,2] := I+1 else States[I,1] := I+1, States[I,2] := 0 end end end end, foreach(State in States) println(State) end. make_automatonX(Pattern) => N = length(Pattern), % fix for "zero clues" Len = max(length([Pattern[I] : I in 1..N, Pattern[I] > 0]) + sum(Pattern),1), LeadingZeros = sum([1 : I in 1..N, Pattern[I] = 0]), ZeroPositions = [sum([Pattern[J]+1 : J in 1..I]) -LeadingZeros : I in 1..N, Pattern[I] > 0], println(zeroPositions=ZeroPositions), States = [], if (length([Pattern[I] : I in 1..N, Pattern[I] > 0]) + sum(Pattern)) = 0 then States := [1,1] % fix for "zero clues" else States := [1, 2], % Yes, it's a mess... foreach(I in 3..2*(Len-1)) if member(I div 2, ZeroPositions) then if I mod 2 = 0 then States := States ++ [0] else States := States ++ [(I div 2) + 1] end elseif member((I-1) div 2, ZeroPositions) then if I mod 2 = 0 then States := States ++ [(I div 2)+1] else States := States ++ [(I div 2)+2] end else if not(member((((I-1) div 2) - 1),ZeroPositions)) then if I mod 2 = 0 then States := States ++ [(I div 2) + 1] else if member((I div 2) + 1,ZeroPositions) then States := States ++ [(I div 2) + 2] else States := States ++ [0] end end else if I mod 2 = 0 then States := States ++ [(I div 2) + 1] else if not(member((I div 2) + 1, ZeroPositions)) then States := States ++ [0] else States := States ++ [(I div 2) + 2 ] end end end end end, States := States ++ [Len,0] end, States2 = [], % convert to 2D matrix foreach(I in 1..States.length div 2) States2 := States2 ++ [[States[I*2-1],States[I*2]]] end, foreach(State in States2) println(State) end, % % regular(X,Len,2,States2,1,[Len]), nl.