equal
deleted
inserted
replaced
1 package takuzu |
1 package takuzu |
2 |
2 |
3 import ( |
3 // This file contains the takuzu validation functions and methods. |
4 "fmt" |
|
5 |
|
6 "github.com/pkg/errors" |
|
7 ) |
|
8 |
4 |
9 // checkRange returns true if the range is completely defined, and an error |
5 // checkRange returns true if the range is completely defined, and an error |
10 // if it doesn't follow the rules for a takuzu line or column |
6 // if it doesn't follow the rules for a takuzu line or column |
11 // Note that the boolean might be invalid if the error is not nil. |
7 // Note that the boolean might be invalid if the error is not nil. |
12 func checkRange(cells []Cell) (bool, error) { |
8 func checkRange(cells []Cell) (bool, error) { |
29 prevCellCount = 1 |
25 prevCellCount = 1 |
30 } else { |
26 } else { |
31 if c.Value == prevCell.Value { |
27 if c.Value == prevCell.Value { |
32 prevCellCount++ |
28 prevCellCount++ |
33 if prevCellCount > 2 { |
29 if prevCellCount > 2 { |
34 return full, errors.Errorf("3+ same values %d", c.Value) |
30 v := c.Value |
|
31 return full, validationError{ |
|
32 ErrorType: ErrorTooManyAdjacentValues, |
|
33 CellValue: &v, |
|
34 } |
35 } |
35 } |
36 } else { |
36 } else { |
37 prevCellCount = 1 |
37 prevCellCount = 1 |
38 } |
38 } |
39 |
39 |
40 } |
40 } |
41 prevCell = c |
41 prevCell = c |
42 } |
42 } |
43 if counters[0] > size/2 { |
43 if counters[0] > size/2 { |
44 return full, errors.Errorf("too many zeroes") |
44 v := 0 |
|
45 return full, validationError{ |
|
46 ErrorType: ErrorTooManyValues, |
|
47 CellValue: &v, |
|
48 } |
45 } |
49 } |
46 if counters[1] > size/2 { |
50 if counters[1] > size/2 { |
47 return full, errors.Errorf("too many ones") |
51 v := 1 |
|
52 return full, validationError{ |
|
53 ErrorType: ErrorTooManyValues, |
|
54 CellValue: &v, |
|
55 } |
48 } |
56 } |
49 return full, nil |
57 return full, nil |
50 } |
58 } |
51 |
59 |
52 // CheckRangeCounts returns true if all cells of the provided range are defined, |
60 // CheckRangeCounts returns true if all cells of the provided range are defined, |
99 |
107 |
100 // Let's check line i |
108 // Let's check line i |
101 d = b.GetLine(i) |
109 d = b.GetLine(i) |
102 full, err = checkRange(d) |
110 full, err = checkRange(d) |
103 if err != nil { |
111 if err != nil { |
104 return false, errors.Wrapf(err, "line %d", i) |
112 err := err.(validationError) |
|
113 err.LineNumber = &i |
|
114 return false, err |
105 } |
115 } |
106 if full { |
116 if full { |
107 hv := computeVal(d) |
117 hv := computeVal(d) |
108 if lineVals[hv] { |
118 if lineVals[hv] { |
109 return false, fmt.Errorf("duplicate lines (%d)", i) |
119 err := validationError{ |
|
120 ErrorType: ErrorDuplicate, |
|
121 LineNumber: &i, |
|
122 } |
|
123 return false, err |
110 } |
124 } |
111 lineVals[hv] = true |
125 lineVals[hv] = true |
112 } else { |
126 } else { |
113 finished = false |
127 finished = false |
114 } |
128 } |
115 |
129 |
116 // Let's check column i |
130 // Let's check column i |
117 d = b.GetColumn(i) |
131 d = b.GetColumn(i) |
118 full, err = checkRange(d) |
132 full, err = checkRange(d) |
119 if err != nil { |
133 if err != nil { |
120 return false, errors.Wrapf(err, "column %d", i) |
134 err := err.(validationError) |
|
135 err.ColumnNumber = &i |
|
136 return false, err |
121 } |
137 } |
122 if full { |
138 if full { |
123 hv := computeVal(d) |
139 hv := computeVal(d) |
124 if colVals[hv] { |
140 if colVals[hv] { |
125 return false, fmt.Errorf("duplicate columns (%d)", i) |
141 err := validationError{ |
|
142 ErrorType: ErrorDuplicate, |
|
143 ColumnNumber: &i, |
|
144 } |
|
145 return false, err |
126 } |
146 } |
127 colVals[hv] = true |
147 colVals[hv] = true |
128 } else { |
148 } else { |
129 finished = false |
149 finished = false |
130 } |
150 } |