Advertisement
saltycracker

Sudoku(9x9).ml

Nov 20th, 2020
2,014
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 2.81 KB | None | 0 0
  1.  
  2. let sudoArray =
  3.   [|
  4.     0;0;0; 0;0;8; 0;0;0;
  5.     2;0;0; 0;5;9; 0;0;0;
  6.     1;0;0; 0;0;0; 2;5;0;
  7.  
  8.     0;0;8; 0;0;1; 4;6;0;
  9.     3;0;0; 0;0;0; 1;0;0;
  10.     9;0;4; 0;8;3; 0;0;0;
  11.  
  12.     0;0;0; 5;0;0; 0;8;4;
  13.     0;0;0; 0;0;4; 9;0;0;
  14.     0;2;3; 0;0;0; 0;0;0
  15.   |]
  16.  
  17. let solution = ref 1
  18.  
  19. let sudokuRowSize = 9
  20. let sudokuBoxSize = 3
  21.  
  22. (*
  23. 1 => 1, 2
  24. 2 => -1, 1
  25. 0 => -2, -1
  26. *)
  27.  
  28. let buildEdgeBox r c acc =
  29.   let rm = r mod sudokuBoxSize in
  30.   let cm = c mod sudokuBoxSize in
  31.   let rl = if rm = 1 then [1; 2] else if rm = 2 then [-1; 1] else [-2; -1] in
  32.   let cl = if cm = 1 then [1; 2] else if cm = 2 then [-1; 1] else [-2; -1] in
  33.   List.fold_left (fun a d -> List.fold_left (fun ai di ->((r + d), (c + di)):: ai) a cl) acc rl
  34.  
  35. let rec buildEdgesRow r c cnt acc =
  36.   match cnt with
  37.   | 0 -> acc
  38.   | x when c = x -> buildEdgesRow r c (cnt - 1) acc
  39.   | x -> buildEdgesRow r c (cnt - 1) ((r, x)::acc)
  40.  
  41. let rec buildEdgesCol r c cnt acc =
  42.   match cnt with
  43.   | 0 -> acc
  44.   | x when r = x -> buildEdgesCol r c (cnt - 1) acc
  45.   | x -> buildEdgesCol r c (cnt - 1) ((x, c)::acc)
  46.  
  47. let lst =
  48.   List.fold_left
  49.     (
  50.       fun a d ->
  51.         let r = (d/sudokuRowSize + 1) in
  52.         let c = ((d mod sudokuRowSize) + 1) in
  53.         let v = Array.get sudoArray d in
  54.         let lst = if v != 0
  55.           then
  56.             []
  57.             else
  58.           (buildEdgeBox r c
  59.              (buildEdgesCol r c sudokuRowSize
  60.                 (buildEdgesRow r c sudokuRowSize []))) in
  61.         let slst = if v !=0
  62.           then
  63.             []
  64.             else
  65.           List.fold_left
  66.             (
  67.               fun a (r, c) ->
  68.                 let ans = (Array.get sudoArray (((r - 1) * sudokuRowSize) + (c - 1))) in
  69.                 if ans = 0
  70.                 then
  71.                   a
  72.                 else
  73.                 (List.filter (fun x -> ans != x) a)
  74.             )
  75.             [1;2;3;4;5;6;7;8;9;] lst in
  76.         (
  77.           d,
  78.           v,
  79.           (r, c),
  80.           lst,
  81.           slst
  82.         )::a
  83.     )
  84.     []
  85.     (List.init 81 (fun x -> x))
  86.  
  87. let rec solveIt lst =
  88.   match lst with
  89.   | [] ->
  90.     (
  91.       Printf.printf "Solution: %d\n" (!solution);
  92.       solution := (!solution) + 1;
  93.       Array.iter (fun x -> Printf.printf "%d\n" x) sudoArray
  94.     )
  95.   | (p, 0, (r, c), e, s)::tl ->
  96.     List.iter
  97.       (
  98.         fun x ->
  99.           if (List.exists
  100.                 (fun (r, c) ->
  101.                    (x = (Array.get sudoArray (((r - 1) * sudokuRowSize) + (c - 1))))) e
  102.              )
  103.           then
  104.             ()
  105.           else
  106.             (
  107.               (Array.set sudoArray p x);
  108.               solveIt tl;
  109.               (Array.set sudoArray p 0)
  110.             )
  111.       ) s
  112.   | (p, v, (r, c), e, s)::tl ->
  113.     (Array.set sudoArray p v);
  114.     solveIt tl;
  115.     (Array.set sudoArray p 0)
  116.  
  117. let () = solveIt lst  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement