go编程解数独

gs272 · 2013-04-26 05:01:04 · 5280 次点击

<p>//你看看是不是要这样的效果,可以求所有的解</p>

<p>package main</p>

<p>import "fmt"</p>

<p>const (</p> N = 9 <p>)</p>

<p>type point struct{</p>

<pre><code>x int

y int </code></pre>

<p>}</p>

<p>type line [N]int</p>

<p>type area [N]line</p>

<p>func (s *area) show(){</p>

<pre><code>fmt.Println("---------------")

for i:=0;i&lt;N;i++ { for j:=0;j&lt;N;j++ { fmt.Print(s[i][j]) } fmt.Print("\n") } </code></pre>

<p>}</p>

<p>func main(){</p>

<pre><code>fmt.Println("")

var ( i int j int start int step int total int current point ) var sudoku area = area{ / {0,0,7,0,0,0,0,0,1}, {9,0,0,0,0,0,6,2,8}, {6,0,2,0,0,0,5,9,0}, {0,0,0,0,8,1,0,0,5}, {0,7,0,5,0,3,0,0,0}, {0,9,0,0,6,0,0,7,0}, {0,0,0,0,0,5,0,0,0}, {2,0,0,0,4,0,0,8,6}, {0,4,0,0,3,0,0,0,0}, /// {0,0,0,0,0,0,0,0,1}, {9,0,0,0,0,0,6,2,8}, {6,0,2,0,0,0,5,9,0}, {0,0,0,0,8,1,0,0,5}, {0,7,0,5,0,3,0,0,0}, {0,9,0,0,6,0,0,7,0}, {0,0,0,0,0,5,0,0,0}, {2,0,0,0,4,0,0,8,6}, {0,4,0,0,3,0,0,0,0}, } var limit area = area{} var route [NN]point = [NN]point{}

sdk := sudoku[:] i = 0 j = 0 route[0].x, route[0].y = i, j

var cover func([]line,point) int = func(sudo []line,p point) int {

var (
    x   int
    y   int
    i   int
    j   int
    result  int
)
result = 0

for i,j = p.x,0; j<N; j++ {
    if p.y != j {
        result = result|(1<<uint(sudo[i][j]))
    }
}
for i,j = 0,p.y; i<N; i++ {
    if p.x != i {
        result = result|(1<<uint(sudo[i][j]))
    }
}
x,y = (p.x/3)*3,(p.y/3)*3
for i=0;i<3;i++ {
    for j=0;j<3;j++ {
        if p.x != i && p.y != j {
            result = result|(1<<uint(sudo[x+i][y+j]))
        }
    }
}

return result

}

// 确定填写路线 step,start = 0,0 for i=0; i&lt;N; i++ { for j=0; j&lt;N; j++{ if sudoku[i][j] &gt; 0 { route[step].x,route[step].y = i,j step++ } } } start = step for i=0; i&lt;N; i++ { for j=0; j&lt;N; j++{ if !(sudoku[i][j] &gt; 0) { route[step].x,route[step].y = i,j step++ } } }

//for _,a := range route { //fmt.Print(a) //}

// 初始化求解参数 current = route[start] limit[current.x][current.y] = cover(sdk,current) flag := '+' temp := sudoku[current.x][current.y] depth := start total = 0 for{ //fmt.Printf("%c,%d",flag,depth) switch flag {

    case '>':
        if depth >= N*N {
            sudoku.show()
            depth--
            flag = '<'
            total++
        }else{
            temp = 0
            current = route[depth]
            limit[current.x][current.y] = cover(sdk,current)
            flag = '+'
        }
        break
    case '<':
        if depth < start {
            break
        } else {
            current = route[depth]
            flag = '+'
            temp = sudoku[current.x][current.y]
        }
    default:
        temp++
        if temp > N {
            flag = '<'
            sudoku[current.x][current.y] = 0
            depth--
        }else if (1<<uint(temp)|limit[current.x][current.y]) != limit[current.x][current.y] {
            flag = '>'
            sudoku[current.x][current.y] = temp
            depth++
        }

}

if depth < start { // 查找完毕
    break
}

}

fmt.Println("------------------OVER--------------------") fmt.Println("total:",total) </code></pre>

<p>}</p>

#12
更多评论
polaris
社区,需要你我一同完善!

没玩过数独……

#1
不好意思,写错了,应该是下面的
007000001
900000628
602000590
000081005
070503000
090060070
000005000
200040086
040030000
#2