開発環境
- macOS Catalina - Apple (OS)
- Emacs (Text Editor)
- Windows 10 Pro (OS)
- Visual Studio Code (Text Editor)
- Go (プログラミング言語)
入門Goプログラミング (Nathan Youngman(著)、Roger Peppé(著)、吉川 邦夫(監修, 翻訳)、翔泳社)のUNIT 6(ネズミの穴を下って)、LESSON 29(チャレンジ:数独ルール)の解答を求めてみる。
コード
package main
import (
"errors"
"fmt"
"math/rand"
"os"
"time"
)
const (
rows = 9
cols = 9
)
var (
errBound = errors.New("ます目外")
errDigit = errors.New("1から9の数値ではない")
errRow = errors.New("行に既に存在する数")
errCol = errors.New("列に既に存在する数")
errGrid = errors.New("グリッドに既に存在する数")
)
func inBound(i int) bool {
return i >= 0 && i < rows
}
func validDigit(n int8) bool {
return n >= 1 && n <= 9
}
type sudoku [rows][cols]int8
func (s *sudoku) validRow(row int, n int8) bool {
for _, m := range s[row] {
if n == m {
return false
}
}
return true
}
func (s *sudoku) validCol(col int, n int8) bool {
for row := 0; row < rows; row++ {
if s[row][col] == n {
return false
}
}
return true
}
func (s *sudoku) validGrid(row, col int, n int8) bool {
k := row / 3 * 3
l := col / 3 * 3
for i := k; i < k+3; i++ {
for j := l; j < l+3; j++ {
if i != row && j != col && s[i][j] == n {
return false
}
}
}
return true
}
func (s *sudoku) set(row, col int, n int8) error {
if !inBound(row) || !inBound(col) {
return errBound
}
if !validDigit(n) {
return errDigit
}
if !s.validRow(row, n) {
return errRow
}
if !s.validCol(col, n) {
return errCol
}
if !s.validGrid(row, col, n) {
return errGrid
}
s[row][col] = n
return nil
}
func (s *sudoku) clear(row, col int) error {
if !inBound(row) || !inBound(col) {
return errBound
}
s[row][col] = 0
return nil
}
func (s sudoku) String() string {
a := ""
for _, row := range s {
for _, col := range row {
a += fmt.Sprintf("%v ", col)
}
a += "\n"
}
return a
}
func main() {
rand.Seed(time.Now().UnixNano())
s := sudoku([rows][cols]int8{
{5, 3, 0, 0, 7, 0, 0, 0, 0},
{6, 0, 0, 1, 9, 5, 0, 0, 0},
{0, 9, 8, 0, 0, 0, 0, 6, 0},
{8, 0, 0, 0, 6, 0, 0, 0, 3},
{4, 0, 0, 8, 0, 3, 0, 0, 1},
{7, 0, 0, 0, 2, 0, 0, 0, 6},
{0, 6, 0, 0, 0, 0, 2, 8, 0},
{0, 0, 0, 4, 1, 9, 0, 0, 5},
{0, 0, 0, 0, 8, 0, 0, 7, 9},
})
for i := 0; i < 50; i++ {
row := rand.Intn(10)
col := rand.Intn(10)
n := int8(rand.Intn(11))
err := s.set(row, col, n)
if err != nil {
fmt.Fprintln(os.Stderr, err)
} else {
fmt.Println(row+1, col+1, n)
fmt.Print(s)
}
}
for i := 0; i < 10; i++ {
row := rand.Intn(10)
col := rand.Intn(10)
err := s.clear(row, col)
if err != nil {
fmt.Fprintln(os.Stderr, err)
} else {
fmt.Println(row+1, col+1)
fmt.Print(s)
}
}
}
入出力結果(Zsh、PowerShell、Terminal)
% go build sudoku.go
% ./sudoku
3 9 2
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 6 2
8 0 0 0 6 0 0 0 3
4 0 0 8 0 3 0 0 1
7 0 0 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
4 6 7
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 0 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
列に既に存在する数
行に既に存在する数
列に既に存在する数
ます目外
行に既に存在する数
1から9の数値ではない
1から9の数値ではない
ます目外
列に既に存在する数
行に既に存在する数
1から9の数値ではない
ます目外
1から9の数値ではない
ます目外
行に既に存在する数
列に既に存在する数
行に既に存在する数
行に既に存在する数
ます目外
6 3 5
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
列に既に存在する数
行に既に存在する数
行に既に存在する数
1から9の数値ではない
2 7 8
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 8 0 0
0 9 8 0 0 0 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
ます目外
列に既に存在する数
ます目外
ます目外
行に既に存在する数
9 3 4
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 8 0 0
0 9 8 0 0 0 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 4 0 8 0 0 7 9
行に既に存在する数
行に既に存在する数
列に既に存在する数
7 8 4
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 8 0 0
0 9 8 0 0 0 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 4 0
0 0 0 4 1 9 0 0 5
0 0 4 0 8 0 0 7 9
列に既に存在する数
ます目外
列に既に存在する数
1から9の数値ではない
ます目外
1から9の数値ではない
1から9の数値ではない
行に既に存在する数
1から9の数値ではない
3 6 4
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 8 0 0
0 9 8 0 0 4 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 4 0
0 0 0 4 1 9 0 0 5
0 0 4 0 8 0 0 7 9
行に既に存在する数
列に既に存在する数
行に既に存在する数
3 4
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 8 0 0
0 9 8 0 0 4 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 4 0
0 0 0 4 1 9 0 0 5
0 0 4 0 8 0 0 7 9
9 9
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 8 0 0
0 9 8 0 0 4 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 4 0
0 0 0 4 1 9 0 0 5
0 0 4 0 8 0 0 7 0
4 8
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 8 0 0
0 9 8 0 0 4 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 4 0
0 0 0 4 1 9 0 0 5
0 0 4 0 8 0 0 7 0
ます目外
3 6
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 8 0 0
0 9 8 0 0 0 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 4 0
0 0 0 4 1 9 0 0 5
0 0 4 0 8 0 0 7 0
3 4
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 8 0 0
0 9 8 0 0 0 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 4 0
0 0 0 4 1 9 0 0 5
0 0 4 0 8 0 0 7 0
7 9
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 8 0 0
0 9 8 0 0 0 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 4 0
0 0 0 4 1 9 0 0 5
0 0 4 0 8 0 0 7 0
2 2
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 8 0 0
0 9 8 0 0 0 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 4 0
0 0 0 4 1 9 0 0 5
0 0 4 0 8 0 0 7 0
5 5
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 8 0 0
0 9 8 0 0 0 0 6 2
8 0 0 0 6 7 0 0 3
4 0 0 8 0 3 0 0 1
7 0 5 0 2 0 0 0 6
0 6 0 0 0 0 2 4 0
0 0 0 4 1 9 0 0 5
0 0 4 0 8 0 0 7 0
ます目外
% ./sudoku
1から9の数値ではない
行に既に存在する数
1から9の数値ではない
6 3 1
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 6 0
8 0 0 0 6 0 0 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
列に既に存在する数
4 7 9
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 6 0
8 0 0 0 6 0 9 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
列に既に存在する数
3 8 3
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 9 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
1から9の数値ではない
1から9の数値ではない
行に既に存在する数
7 4 3
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 9 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
0 6 0 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
列に既に存在する数
行に既に存在する数
1 4 2
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 9 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
0 6 0 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
1から9の数値ではない
列に既に存在する数
1から9の数値ではない
行に既に存在する数
ます目外
7 1 1
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 9 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 6 0 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
行に既に存在する数
2 8 4
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 4 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 9 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 6 0 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
行に既に存在する数
行に既に存在する数
ます目外
1から9の数値ではない
ます目外
行に既に存在する数
7 3 7
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 4 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 9 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 6 7 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
行に既に存在する数
列に既に存在する数
行に既に存在する数
7 2 5
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 4 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 9 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 5 7 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
行に既に存在する数
ます目外
列に既に存在する数
ます目外
グリッドに既に存在する数
4 7 5
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 4 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 5 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 5 7 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
1から9の数値ではない
グリッドに既に存在する数
1から9の数値ではない
ます目外
ます目外
行に既に存在する数
行に既に存在する数
9 8 6
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 4 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 5 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 5 7 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 6 9
1から9の数値ではない
列に既に存在する数
4 6
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 4 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 5 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 5 7 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 6 9
ます目外
8 7
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 4 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 5 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 5 7 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 6 9
ます目外
4 6
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 4 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 5 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 5 7 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 6 9
4 3
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 4 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 5 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 5 7 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 6 9
ます目外
4 4
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 4 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 5 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 5 7 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 6 9
6 8
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 4 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 5 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 5 7 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 6 9
9 2
5 3 0 2 7 0 0 0 0
6 0 0 1 9 5 0 4 0
0 9 8 0 0 0 0 3 0
8 0 0 0 6 0 5 0 3
4 0 0 8 0 3 0 0 1
7 0 1 0 2 0 0 0 6
1 5 7 3 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 6 9
%
0 コメント:
コメントを投稿