Skip to content

thomasjungblut/go-dancing-links

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go

go-dancing-links

go-dancing-links contains a golang implementation of the dancing links algorithm (DLX) as Donald Knuth devised it in his paper.

The algorithm solves the exact cover problem, which is a common constraint satisfaction algorithm that can be used to solve Sudokus or the n-queens problem.

Installation

go get -d github.com/thomasjungblut/go-dancing-links

Using go-dancing-links

It's fairly easy to use, as long as you can translate your problem into a binary matrix.

Let's say you're at a (somewhat nerdy) party and you want to have exactly one of each item: beer, nachos and sour cream. Now your friends can bring some of them in varying configurations and you want to tell them whether they should bring their items or not. Fret not, DLX has you covered and in no time you'll have the solution(s) to your problem!

Example

We need to tell the matrix what items you need (columns) and what friends you have and what they can bring to your party (rows).

mat := NewDancingLinkMatrix()

mat.AppendColumn("beer")
mat.AppendColumn("nachos")
mat.AppendColumn("sour cream")

mat.AppendRow("Jack", []bool{true, false, false}) // Jack can bring beer only
mat.AppendRow("Amanda", []bool{true, true, false}) // Amanda can bring beer and nachos
mat.AppendRow("Chris", []bool{false, false, true}) // Chris can only bring sour cream
mat.AppendRow("Jen", []bool{true, true, true}) // Jen can bring everything 

In this simple example, we have two solutions: either Jen brings everything or Amanda and Chris can bring their stuff individually. Let's see what DLX thinks about it:

result := mat.Solve()
fmt.Println(result)
// [[Amanda Chris] [Jen]]

Awesome! The result is a two dimensional slice of row names, because there can be multiple solutions for any given matrix.

Sudoku Solver

Sudokus can also be solved pretty fast from a string by using the Euler96 format:

board := NewSudokuBoard(9)
board.ReadEulerTextFormat(`Grid 01
    003020600
    900305001
    001806400
    008102900
    700000008
    006708200
    002609500
    800203009
    005010300`)
board, err := board.FindSingleSolution() // solve with DLX and return the filled board
err := board.VerifyCorrectness() // check if the solution is correct
err := board.Print(os.Stdout) // print it to stdout

// or if there are multiple solutions possible, you can find all boards
boards, err := board.FindAllSolutions() 
for _, board := range boards {
	err := board.VerifyCorrectness() // check if the solution is correct
	err := board.Print(os.Stdout) // print it to stdout
}

N-Queens Solver

The generalized N-Queens problem can also be solved fairly easy with DLX:

board := NewNQueensBoard(4)
result, err := board.FindAllSolutions()
for _, board := range result {
    assert.Nil(t, board.VerifyCorrectness())
    assert.Nil(t, board.Print(os.Stdout))
    println()
}

which outputs the results as a NxN block where 'x' denotes a queen:

o x o o 
o o o x 
x o o o 
o o x o 

o o x o 
x o o o 
o o o x 
o x o o 

About

GoLang AlgorithmX with Dancing Links implementation for solving Exact Cover problems like Sudoku and N-Queens

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published