Created
April 27, 2017 12:31
-
-
Save alecthegeek/c1de6fca467d9c4d1c308965cc0608a9 to your computer and use it in GitHub Desktop.
Solve sudoku puzzles in a very simple manner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Solve sudoku puzzles | |
package main | |
import ( | |
"fmt" | |
) | |
type SudokuBoard []int | |
func (b SudokuBoard) String() string { // For printing | |
var o string | |
for r := 0; r < 9; r += 1 { | |
if r % 3 == 0 { | |
o += fmt.Sprintf("=========================================\n") | |
} else { | |
o += fmt.Sprintf("-----------------------------------------\n") | |
} | |
for c := 0; c < 9 ; c += 1 { | |
if c % 3 == 0 { | |
o += fmt.Sprintf("|| %d ",abs(b[r*9+c])) | |
} else { | |
o += fmt.Sprintf("| %d ",abs(b[r*9+c])) | |
} | |
} | |
o += fmt.Sprintf("||\n") | |
} | |
return o + fmt.Sprintf("=========================================") | |
} | |
var theBoards = []SudokuBoard { | |
{ // Easy Problem | |
-3, -6, -8, -7, -9, -4, -2, -1, -5, | |
-9, -5, -7, -2, -1, 0, 0, -6, -8, | |
-4, -2, -1, -8, -6, -5, -3, -9, -7, | |
0, 0, 0, -3, -8, -6, -9, -7, -4, | |
0, 0, -3, -9, -5, 0, 0, -8, 0, | |
-7, -8, -9, -1, -4, 0, -6, 0, 0, | |
-2, -3, 0, 0, -7, -9, -8, -4, -1, | |
0, -7, -4, -6, -3, -1, -5, 0, -9, | |
-1, -9, 0, -4, -2, -8, 0, -3, 0, | |
}, | |
{ // Hard Problem | |
0, 0, 0, 0, 0, -2, 0, -3, 0, | |
0, 0, 0, -7, 0, -9, -4, 0, -2, | |
-9, 0, 0, 0, 0, 0, 0, 0, -7, | |
-3, 0, 0, -6, 0, 0, 0, -2, -1, | |
0, -5, 0, -2, 0, -4, 0, -9, 0, | |
-2, -9, 0, 0, 0, -7, 0, 0, -8, | |
-1, 0, 0, 0, 0, 0, 0, 0, -4, | |
-5, 0, -2, -1, 0, -6, 0, 0, 0, | |
0, -6, 0, -4, 0, 0, 0, 0, 0, | |
}, | |
{ // Another Hard problem | |
0, 0, 0, -8, 0, 0, 0, 0, -9, | |
-4, -9, 0, -3, 0, 0, 0, -1, 0, | |
0, 0, -6, 0, -9, 0, 0, 0, -4, | |
-8, 0, -1, 0, 0, -7, 0, 0, 0, | |
0, -4, 0, 0, 0, 0, 0, -2, 0, | |
0, 0, 0, -6, -1, 0, -9, 0, -8, | |
-9, 0, 0, 0, -8, 0, -7, 0, 0, | |
0, -8, 0, 0, 0, -9, 0, -6, -2, | |
-5, 0, 0, 0, 0, -6, 0, 0, 0, | |
}, | |
} | |
var count uint // Let's see how hard it is to solve these puzzles | |
func main() { | |
for _, b := range theBoards { | |
count = 0 | |
fmt.Printf("\n") | |
if !solveSudoku(b, 0) { | |
fmt.Println("solution not found. Invalid board\n%v\n",b) | |
} else { | |
fmt.Printf("Solution found in %v steps\n%v\n", count, b) | |
} | |
} | |
} | |
func abs(x int) int { | |
if x < 0 { | |
return x * -1 | |
} | |
return x | |
} | |
func solveSudoku(b SudokuBoard, cc uint) bool { | |
if cc == 9*9 { | |
return true // Solved! | |
} | |
if b[cc] < 0 { // cell already provided by puzzle. Solve next one | |
return solveSudoku(b, cc+1) | |
} | |
if b[cc] > 0 { // cell already filled in by us | |
fmt.Printf("Errror, attempt to solve cell %v which has alreadt been filled in\n", cc) | |
} | |
for v := 1; v < 10; v += 1 { | |
b[cc] = v | |
count += 1 | |
if checkCol(b, cc%9) && | |
checkRow(b, cc/9) && | |
checkSmallSquare(b, cc) && | |
solveSudoku(b, cc+1) { | |
return true | |
} | |
} | |
b[cc] = 0 // Set the cell back to blank | |
return false | |
} | |
func checkSet4duplicates(collection []int) bool { | |
var found [9]bool | |
for _, i := range collection { | |
if i == 0 { // Ignore -- not yet set | |
continue | |
} | |
i = abs(i) - 1 // found[] goes 0-8, not 1-9 | |
if found[i] == true { | |
return false | |
} | |
found[i] = true | |
} | |
return true | |
} | |
func checkRow(b SudokuBoard, row uint) bool { | |
return checkSet4duplicates(b[row*9:row*9+9]) | |
} | |
func checkCol(b SudokuBoard, col uint) bool { | |
var collection []int | |
for r := uint(0); r < 9; r += 1 { | |
collection = append(collection, b[r*9+col]) | |
} | |
return checkSet4duplicates(collection) | |
} | |
// Check the current 3x3 sqaure for uniqness | |
func checkSmallSquare(b SudokuBoard, cell uint) bool { | |
var collection []int | |
// find the 3x3 square for the current cell | |
row := (cell / 9) % 2 * 3 | |
col := (cell % 9) % 2 * 3 | |
for c := col; c < col+3; c += 1 { | |
for r := row; r < row+3; r += 1 { | |
collection = append(collection, b[r*9+c]) | |
} | |
} | |
return checkSet4duplicates(collection) | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment