-
Notifications
You must be signed in to change notification settings - Fork 0
/
constraint.py
154 lines (122 loc) · 4.49 KB
/
constraint.py
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import numpy as np
def knight_constraint(arr, x, y, val):
"""Checks for the knight constraint on a Sudoku board.
The knight constraint checks if a given cell has any surrounding cell of same values.
The surrounding cells in this scenario is a knight-step away referring to chess.
Args:
arr: The Sudoku board as a two-dimensional list of integers.
x: The x-position of the cell.
y: The y-position of the cell.
val: The value which will be tested at the given position.
Returns:
True if the value does not break the knight constraint on the given position in the board.
False otherwise.
"""
if x != 0:
if y > 1:
if val == arr[y - 2][x - 1]:
return False
if y < 7:
if val == arr[y + 2][x - 1]:
return False
if x != 8:
if y > 1:
if val == arr[y - 2][x + 1]:
return False
if y < 7:
if val == arr[y + 2][x + 1]:
return False
if y != 0:
if x > 1:
if val == arr[y - 1][x - 2]:
return False
if x < 7:
if val == arr[y - 1][x + 2]:
return False
if y != 8:
if x > 1:
if val == arr[y + 1][x - 2]:
return False
if x < 7:
if val == arr[y + 1][x + 2]:
return False
return True
def king_constraint(arr, x, y, val):
"""Checks for the king constraint on a Sudoku board.
The king constraint checks if any surrounding cells of a given cell has the same value.
Args:
arr: The Sudoku board as a two-dimensional list of integers.
x: The x-position of the cell.
y: The y-position of the cell.
val: The value which will be tested at the given position.
Returns:
True if the value does not break the king constraint on the given position in the board.
False otherwise.
"""
# Pad 0-values around the matrix to avoid checking if the cell is on the edge of the board.
pad_arr = np.pad(arr, [(1, 1), (1, 1)], mode="constant", constant_values=0)
# To compensate for the padding.
x += 1
y += 1
for i in range(-1, 2):
if pad_arr[y - 1][x + i] == val:
return False
if pad_arr[y + 1][x + i] == val:
return False
if pad_arr[y][x + 1] == val:
return False
if pad_arr[y][x - 1] == val:
return False
return True
def constraint_pass_inv(arr, x, y, val):
"""Checks the common constraints on a Sudoku board.
Checks if a given value fits on the row, column, and block of the board.
Args:
arr: The Sudoku board as a two-dimensional list of integers.
x: The x-position of the cell.
y: The y-position of the cell.
val: The value which will be tested at the given position.
Returns:
True if the value at the given position does not break any constraints.
False otherwise.
"""
for i in range(9):
if i != x:
row_cell = arr[y][i]
if row_cell == val:
return False
if i != y:
column_cell = arr[i][x]
if column_cell == val:
return False
# Finds the correct block arithmetically.
i = int(x / 3)
j = int(y / 3)
for n in range(3 * j, 3 * j + 3):
for k in range(3 * i, 3 * i + 3):
if n != y and k != x and arr[n][k] == val:
return False
return True
def check_board(arr, king, knight):
"""Checks the entire board if any constraints are broken.
Args:
arr: The Sudoku board as a two-dimensional list of integers.
king: If the king constraint is enabled.
knight: If the knight constraint is enabled.
Returns:
True if no constraint is broken broken, false otherwise.
"""
for i in range(9):
for j in range(9):
if arr[i][j] == 0:
continue
if not constraint_pass_inv(arr, j, i, arr[i][j]):
print("regular constraint at x: " + str(j) + ", y: " + str(i))
return False
if king and not king_constraint(arr, j, i, arr[i][j]):
print("king constraint at x: " + str(j) + ", y: " + str(i))
return False
if knight and not knight_constraint(arr, j, i, arr[i][j]):
print("knight constraint at x: " + str(j) + ", y: " + str(i))
return False
return True