text: /*
  
    Strimko puzzle in Picat.
  
    From 
    360: A New Twist on Latin Squares
    http://threesixty360.wordpress.com/2009/08/04/a-new-twist-on-latin-squares/
    """
    The idea is simple: each row and column of an nxn grid must contain 
    the number 1, 2, ... n exactly once (that is, the grid must form a 
    Latin square), and each "stream" (connected path in the grid) must 
    also contain the numbers 1, 2, ..., n exactly once.
    """
   
    For more information, see:
    * http://www.strimko.com/
    * http://www.strimko.com/rules.htm
    * http://www.strimko.com/about.htm
    * http://www.puzzlersparadise.com/Strimko.htm
  
    Model created by Hakan Kjellerstrand, hakank@gmail.com
    See also my Picat page: http://www.hakank.org/picat/
  
  */
  
  import util.
  import cp.
  
  main => go.
  
  go =>
          strimko(2).
  
  go2 =>
          Problems = [2,67,68,69,70],
          foreach(P in Problems) 
             strimko(P)
          end.
  
  latin_square(Board) =>
     foreach(Row in Board) all_different(Row) end,
     foreach(Column in transpose(Board)) all_different(Column) end.
  
  
  strimko(P) =>
          writef("\nProblem %w\n",P),
          problem(P,Streams,Placed),
  
          N = length(Streams),
          X = new_array(N,N),
          X :: 1..N,
  
          % is a latin square
          latin_square(X),
  
          % streams
          foreach(S in 1..N)
              Positions = [X[I,J] : I in 1..N, J in 1..N, S == Streams[I,J]],
              all_different(Positions)
          end,
          
  
          % placed
          foreach(I in 1..Placed.length)
             X[ Placed[I,1], Placed[I,2] ] #= Placed[I,3]
          end,
  
          solve(X),
          pretty_print(X),
          nl.
  
  
  pretty_print(X) =>
          N = X.length,
          foreach(I in 1..N)
              foreach(J in 1..N) writef(" %d ", X[I,J]) end,
              writef("\n")
          end,
          writef("\n").
  
  
  
  %
  % Strimko Monthly #02
  % Via http://www.hakank.org/minizinc/strimko2_002.dzn
  %
  problem(2,Streams, Placed) =>
      Streams = [[1,1,2,2,2,2,2],
                 [1,1,2,3,3,3,2],
                 [1,4,1,3,3,5,5],
                 [4,4,3,1,3,5,5],
                 [4,6,6,6,7,7,5],
                 [6,4,6,4,5,5,7],
                 [6,6,4,7,7,7,7]],
      Placed =  [[2,1,1],
                 [2,3,7],
                 [2,5,6],
                 [2,7,4],
                 [3,2,7],
                 [3,6,1],
                 [4,1,4],
                 [4,7,5],
                 [5,2,2],
                 [5,6,6]].
  
  % 
  % Strimko Weekly Set 067
  % Via http://www.hakank.org/minizinc/strimko2_067.dzn
  problem(67,Streams, Placed) =>
   Streams =  [[1,1,1,2,3],
               [1,2,2,2,3],
               [1,2,4,5,3],
               [5,4,5,4,3],
               [4,5,5,4,3
               ]],
   Placed =  [[1,3,4],
              [1,4,1],
              [3,3,2],
              [3,5,3],
              [5,4,5]].
  
  %
  % Strimko Weekly Set 068
  % Via http://www.hakank.org/minizinc/strimko2_068.dzn
  problem(68,Streams,Placed) =>
  
  Streams = [[1,2,2,4],
             [2,1,4,2],
             [3,4,1,3],
             [4,3,3,1]],
  Placed =  [[2,2,3],
             [2,3,2],
             [3,3,1]].
  
  
  % Strimko Weekly Set 069
  % Via http://www.hakank.org/minizinc/strimko2_069.dzn
  problem(69,Streams,Placed) =>
     Streams = [[1,2,3,3,3,4],
                [2,1,3,5,4,3],
                [2,1,3,5,5,4],
                [2,6,1,6,5,4],
                [2,6,1,6,4,5],
                [6,2,6,1,5,4]],
     Placed =  [[2,2,4],
                [2,3,1],
                [2,4,3],
                [2,5,2],
                [3,2,1],
                [3,5,6],
                [4,3,5],
                [4,4,2]].
  
  % Strimko Weekly Set 070
  % Via http://www.hakank.org/minizinc/strimko2_070.dzn
  problem(70,Streams,Placed) =>
     Streams =  [[1,2,3,3,3],
                 [2,1,1,3,1],
                 [2,2,3,1,4],
                 [5,2,5,4,4],
                 [5,5,5,4,4]],
     Placed =   [[1,1,1],
                 [2,5,4],
                 [4,1,2],
                 [5,4,5]].
  