Advertisement
Guest User

Untitled

a guest
Dec 3rd, 2016
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 4.19 KB | None | 0 0
  1. open System
  2. type Cell = {Number : Option<int>; PossibleNumbers : int list} with
  3.         static member Cell =
  4.             {Number = None; PossibleNumbers = [1..9]}
  5.         member this.SetNumber number =
  6.             {this with Number = Some(number); PossibleNumbers = List<int>.Empty}
  7.         member this.RemovePossible number =
  8.             {this with PossibleNumbers = this.PossibleNumbers |> List.filter (fun x -> x <> number)}  
  9. type Board = {Cells : Cell[,]} with
  10.     static member Board =
  11.          { Cells = Array2D.init<Cell> 9 9 (fun _ _ -> Cell.Cell) }            
  12.     static member private createIterByCell i j =
  13.         let rowIter = List.init 9 (fun index -> (i, index)) |> List.filter (fun tuple -> snd tuple <> j)
  14.         let colIter = List.init 9 (fun index -> (index, j)) |> List.filter (fun tuple -> fst tuple <> i)
  15.         let topLeft = (i-i%3, j-j%3)
  16.         let sqrIter = List.init 9 (fun index -> (fst topLeft + index/3, snd topLeft + index%3))|> List.filter (fun tuple -> fst tuple <> i || snd tuple <> j)
  17.         Seq.distinct(rowIter @ colIter @ sqrIter) |> Seq.toList
  18.     member this.SetCell i j value =
  19.         let cells = Board.createIterByCell i j
  20.         match value with        
  21.         | 0 -> this                
  22.         | v ->
  23.             (
  24.                 let newArray = this.Cells |> Array2D.mapi (fun row column cell ->
  25.                     match (row, column) with
  26.                     | a, b when a = i && b = j -> cell.SetNumber v
  27.                     | a, b when cells |> List.contains (a, b) -> cell.RemovePossible value
  28.                     | _ -> cell
  29.                 )
  30.                 {this with Cells = newArray}                
  31.             )
  32.     static member private SetBoardRec (board:Board) (values: (int*int*int) list) =
  33.         match values with        
  34.         | [] -> board
  35.         | (i, j, value)::tail -> Board.SetBoardRec (board.SetCell i j value) tail                          
  36.     member this.SetBoard (values: int[,]) =
  37.         let cells = values |> Array2D.mapi (fun i j value -> (i, j, value)) |> Seq.cast<int*int*int> |> Seq.toList
  38.         Board.SetBoardRec this cells        
  39.     member this.printBoard =
  40.         ignore([0..8] |> List.map (fun row ->
  41.             ignore ([0..8] |> List.map (fun col ->
  42.                 let cell = this.Cells.[row, col]      
  43.                 match cell.Number with
  44.                 | None -> Console.Write("0 ")
  45.                 | Some(x) -> Console.Write(x.ToString() + " ")                                        
  46.                 ))                                            
  47.             Console.WriteLine()            
  48.             ))            
  49. let rec solveSudoku (board:Board) =
  50.     let unknownCellsInd =
  51.         Array2D.init 9 9 (fun i j -> (i, j))
  52.         |> Seq.cast<int*int> |> Seq.toList
  53.         |> List.filter (fun tuple -> board.Cells.[fst tuple, snd tuple].Number = None)
  54.     match unknownCellsInd with
  55.     | [] -> (
  56.             printfn "You win"
  57.             board.printBoard
  58.         )
  59.     | _ -> (            
  60.             let firstGuess = board.Cells.[fst unknownCellsInd.Head, snd unknownCellsInd.Head]
  61.             let possibleNumbersEnum = (firstGuess.PossibleNumbers |> List.toSeq).GetEnumerator()            
  62.             while possibleNumbersEnum.MoveNext() do              
  63.                 let newBoard = board.SetCell (fst unknownCellsInd.Head) (snd unknownCellsInd.Head) possibleNumbersEnum.Current
  64.                 solveSudoku newBoard
  65.         )    
  66.     ()                    
  67. [<EntryPoint>]
  68. let main _ =
  69.     let start = array2D
  70.                     [
  71.                         [|0; 0; 7; 8; 6; 1; 0; 5; 0|];
  72.                         [|0; 1; 8; 4; 5; 3; 0; 0; 0|];
  73.                         [|5; 6; 0; 7; 9; 2; 8; 1; 0|];
  74.                         [|1; 0; 0; 0; 7; 6; 3; 8; 5|];
  75.                         [|0; 0; 0; 3; 4; 5; 0; 0; 1|];
  76.                         [|6; 3; 5; 0; 1; 8; 0; 0; 7|];
  77.                         [|0; 5; 0; 1; 2; 4; 0; 9; 8|];
  78.                         [|0; 0; 1; 6; 8; 9; 5; 0; 0|];
  79.                         [|0; 0; 0; 5; 3; 7; 1; 0; 0|]
  80.                     ]
  81.     let board = Board.Board.SetBoard start        
  82.     board.printBoard
  83.     solveSudoku board    
  84.     0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement