-
Notifications
You must be signed in to change notification settings - Fork 15
/
sudoku_test.go
100 lines (93 loc) · 1.72 KB
/
sudoku_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package main
import (
"bufio"
"errors"
"fmt"
"os"
"regexp"
"testing"
)
type Used [9]bool
func (u *Used) Add(n int) error {
n-- //change from 1 to 9 in sudoku to 0 to 8 for indexing
if u[n] {
return errors.New("number is used")
}
u[n] = true
return nil
}
func TestSudoku(t *testing.T) {
f, err := os.Open("README.md")
if err != nil {
t.Fatal(err)
}
defer f.Close()
r := bufio.NewReader(f)
skipLines(r, 10)
var rs, cs, bs [9]Used
var count int
for i := 0; i < 9; i++ {
for j := 0; j < 9; j++ {
t.Run(fmt.Sprintf("line %v%v", i+1, j+1), func(t *testing.T) {
n, err := nextNumber(r)
if err != nil {
t.Fatal(err)
}
if n == 0 {
return
}
count++
err = rs[i].Add(n)
if err != nil {
t.Fatal(err)
}
err = cs[j].Add(n)
if err != nil {
t.Fatal(err)
}
k := i/3 + (j/3)*3
err = bs[k].Add(n)
if err != nil {
t.Fatal(err)
}
})
}
skipLines(r, 1)
}
t.Logf("%v out of 81 numbers filled", count)
}
var numberRegexp = regexp.MustCompile(`[1-9]`)
var spaceRegexp = regexp.MustCompile(` `)
func nextNumber(r *bufio.Reader) (int, error) {
line, pre, err := r.ReadLine()
if err != nil {
return 0, err
}
if pre {
return 0, errors.New("unhandled pre")
}
numbers := numberRegexp.FindAll(line, -1)
if len(numbers) > 1 {
return 0, errors.New("too many digits")
}
if len(numbers) == 1 {
return int(numbers[0][0] - '0'), nil
}
space := spaceRegexp.Find(line)
if space == nil {
return 0, errors.New("expected space filler for empty cells")
}
return 0, nil
}
func skipLines(r *bufio.Reader, n int) error {
for i := 0; i < n; i++ {
_, pre, err := r.ReadLine()
if err != nil {
return err
}
if pre {
i--
}
}
return nil
}