anchor.diff:  
   let public foldi fold first source  =
           source 
  -        |> Array.fold(fun (prev,i) c -> (fold i prev c,i + 1)) (first,0)
  +        |> List.fold(fun (prev,i) c -> (fold i prev c,i + 1)) (first,0)
           |> fst
  +
  +let rotate (arr: 'T[,]) =
  +  Array2D.init (Array2D.length2 arr) (Array2D.length1 arr) (fun x y -> arr.[y,x]) 
   
   let convertPatternToResult grid :CellResult[,] =
     Array2D.map (fun v ->
  
positive.code: module gchq
  
  open System
  
  type group = int list
  type groupsIntermediate = { FinishedGroups : group list; CurrentGroup : group}
  type CellResult = Unknown | Black | White
  type TestResult = Indeterminate | Pass | Fail
  
  let row i (arr: 'T[,]) = arr.[i..i, *] |> Seq.cast<'T> |> Seq.toArray
  let column i (arr: 'T[,]) = arr.[*, i..i] |> Seq.cast<'T> |> Seq.toArray
  
  let rows (arr: 'T[,]) = 
    [ 0.. Array2D.length1 arr - 1 ] |> List.map (fun i -> row i arr)
  
negative.code:   let y = rnd.Next(0, 25)
    let z = if rnd.Next(0, 2) = 0 then Black else White
    Array2D.mapi (fun i j v -> if i = x && j = y then z else v) grid
  
  let trySolveAxis axis (testGroups: int list) =
    let axisGroups = getGroups axis
    let axisGroupCount = List.length axisGroups
    let testCount = List.length testGroups
    
    let result = 
      match testGroups with
      | [] -> List.map (fun r -> CellResult.White) axis
      | _ -> 
        let minimumSolutionWidth = List.sum testGroups + testCount - 1
        match axis.Length - minimumSolutionWidth with
        | overlap when overlap = 0 ->
            testGroups
            |> List.collect (fun groupLength -> CellResult.White :: List.init groupLength (fun _ -> CellResult.Black))
            |> List.tail
        | overlap when List.max testGroups > overlap ->
            List.init (overlap - 1) (fun _ -> CellResult.Unknown)
            @ List.collect (fun groupLength -> 
                match groupLength with
                | groupLength when groupLength > overlap ->
                  List.init (groupLength - overlap) (fun _ -> CellResult.Black)
                  @ CellResult.White :: List.init overlap (fun _ -> CellResult.Unknown)
                | _ ->
                  List.init (groupLength + 1) (fun _ -> CellResult.Unknown)
                ) testGroups
              
        | _ -> axis
        
    result
  
  // let dsadsa = fun () ->
  //   let axis = [
  //     CellResult.Black;
  //     CellResult.White;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.White;
  //     CellResult.Black;
  //     CellResult.White;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.White;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.Black;
  //     CellResult.White;
  //     CellResult.Black;
  //     CellResult.Black;
  //     ]
  //   
  //   let test = [1;3;1;3;10;2]
  //   
  //   let result = testAxis axis test
  //   
  //   match result with
  //   | Pass -> printf "Y  "
  //   | Fail -> printf "N  "
  //   | Indeterminate -> printf "?  "
  
  // let printListGrid = fun (arr:CellResult list list) ->
  //   use output = new StringWriter()
  //   for x in arr do
  //     printRow output x
  //     fprintfn output ""
  //   
  //   Console.WriteLine(output) |> ignore
  //   arr
  
  [<EntryPoint>]
  let main argv =
    
    let origPosition = (Console.CursorLeft, Console.CursorTop)
    
    let start = convertPatternToResult Puzzle.initialGrid
      
    let mutable guess = start
    for i in 1..100 do
      Thread.Sleep(100)
      guess <- 
        rows guess
        |> List.map2 trySolveAxis <| Puzzle.rowTests
        |> array2D
      
      guess <-
        columns guess
        |> List.map2 trySolveAxis <| Puzzle.colTests
        |> array2D
        |> rotate
      
      Console.SetCursorPosition origPosition
      printResultGrid guess Puzzle.rowTests Puzzle.colTests |> Console.WriteLine
      
    0 // return an integer exit code
  