v / examples / sudoku.v
97 lines · 93 sloc · 2.15 KB · d06e11188b980439bb46dfdfe8548e8a536ad2a5
Raw
1fn main() {
2 mut grid := [
3 [0, 3, 0, 0, 7, 0, 0, 0, 0],
4 [0, 0, 0, 1, 3, 5, 0, 0, 0],
5 [0, 0, 1, 0, 0, 0, 0, 5, 0],
6 [1, 0, 0, 0, 6, 0, 0, 0, 3],
7 [4, 0, 0, 8, 0, 3, 0, 0, 1],
8 [7, 0, 0, 0, 2, 0, 0, 0, 6],
9 [0, 0, 0, 0, 0, 0, 2, 1, 0],
10 [0, 0, 0, 4, 1, 2, 0, 0, 5],
11 [0, 0, 0, 0, 0, 0, 0, 7, 4],
12 ]
13 print_grid('Sudoku Puzzle:', grid)
14 println('Solving...')
15 if solve_sudoku(mut grid) {
16 print_grid('Solution:', grid)
17 } else {
18 println('No solution exists.')
19 exit(1)
20 }
21}
22
23// is_valid checks if placing `num` at grid[row][col] is valid
24fn is_valid(grid [][]int, row int, col int, num int) bool {
25 // check the row, if the number has been placed already:
26 for x := 0; x < 9; x++ {
27 if grid[row][x] == num {
28 return false
29 }
30 }
31 // check column
32 for x := 0; x < 9; x++ {
33 if grid[x][col] == num {
34 return false
35 }
36 }
37 // check 3x3 subgrid
38 start_row := row - row % 3
39 start_col := col - col % 3
40 for i := 0; i < 3; i++ {
41 for j := 0; j < 3; j++ {
42 if grid[i + start_row][j + start_col] == num {
43 return false
44 }
45 }
46 }
47 return true
48}
49
50// find_empty finds an empty cell (0) in the grid:
51fn find_empty(grid [][]int) ?(int, int) {
52 for i := 0; i < 9; i++ {
53 for j := 0; j < 9; j++ {
54 if grid[i][j] == 0 {
55 return i, j
56 }
57 }
58 }
59 return none
60}
61
62// solve_sudoku solves the Sudoku puzzle using backtracking
63fn solve_sudoku(mut grid [][]int) bool {
64 // If there is no empty cell, the puzzle is solved:
65 row, col := find_empty(grid) or { return true }
66 // Try placing all the digits in turn in the empty cell:
67 for num := 1; num <= 9; num++ {
68 if is_valid(grid, row, col, num) {
69 grid[row][col] = num
70 // Recursively try to solve the rest
71 if solve_sudoku(mut grid) {
72 return true
73 }
74 // We could not find a solution using this number,
75 // so backtrack and try another number instead:
76 grid[row][col] = 0
77 }
78 }
79 return false
80}
81
82// print_grid prints a labeled Sudoku grid
83fn print_grid(label string, grid [][]int) {
84 println(label)
85 for i := 0; i < 9; i++ {
86 if i % 3 == 0 && i != 0 {
87 println('- - - - - - - - - - - -')
88 }
89 for j := 0; j < 9; j++ {
90 if j % 3 == 0 && j != 0 {
91 print(' | ')
92 }
93 print('${grid[i][j]} ')
94 }
95 println('')
96 }
97}
98