Skip to content

Instantly share code, notes, and snippets.

@alecthegeek
Created April 27, 2017 12:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alecthegeek/c1de6fca467d9c4d1c308965cc0608a9 to your computer and use it in GitHub Desktop.
Save alecthegeek/c1de6fca467d9c4d1c308965cc0608a9 to your computer and use it in GitHub Desktop.
Solve sudoku puzzles in a very simple manner
// 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