-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsudoku_generator.py
116 lines (81 loc) · 3.22 KB
/
sudoku_generator.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
import math,random
class SudokuGenerator:
def __init__(self, row_length, removed_cells):
self.row_length = row_length
self.removed_cells = removed_cells
self.board = [[0 for i in range(9)] for j in range(9)]
self.box_length = int(row_length**0.5)
def get_board(self):
return self.board
def print_board(self):
for row in self.board:
print(row)
def valid_in_row(self, row, num):
for item in self.board[row]:
if item == num:
return False
return True
def valid_in_col(self, col, num):
for row in range(self.row_length):
if self.board[row][col] == num:
return False
return True
def valid_in_box(self, row_start, col_start, num):
for i in range(3):
for j in range(3):
if self.board[row_start + i][col_start + j] == num:
return False
return True
def is_valid(self, row, col, num):
return (self.valid_in_row(row, num) and self.valid_in_col(col, num) and self.valid_in_box(row - row % self.box_length, col - col % self.box_length, num))
def fill_box(self, row_start, col_start):
numbers = list(range(1, 10))
random.shuffle(numbers)
for i in range(row_start, row_start + 3):
for j in range(col_start, col_start + 3):
self.board[i][j] = numbers.pop()
def fill_diagonal(self):
for i in range(0, self.row_length, self.box_length):
self.fill_box(i, i)
def fill_remaining(self, row, col):
if (col >= self.row_length and row < self.row_length - 1):
row += 1
col = 0
if row >= self.row_length and col >= self.row_length:
return True
if row < self.box_length:
if col < self.box_length:
col = self.box_length
elif row < self.row_length - self.box_length:
if col == int(row // self.box_length * self.box_length):
col += self.box_length
else:
if col == self.row_length - self.box_length:
row += 1
col = 0
if row >= self.row_length:
return True
for num in range(1, self.row_length + 1):
if self.is_valid(row, col, num):
self.board[row][col] = num
if self.fill_remaining(row, col + 1):
return True
self.board[row][col] = 0
return False
def fill_values(self):
self.fill_diagonal()
self.fill_remaining(0, self.box_length)
def remove_cells(self):
removed = 0
while removed < self.removed_cells:
row, col = random.randint(0, 8), random.randint(0, 8)
if self.board[row][col] != 0:
self.board[row][col] = 0
removed += 1
def generate_sudoku(size, removed):
sudoku = SudokuGenerator(size, removed)
sudoku.fill_values()
board = sudoku.get_board()
sudoku.remove_cells()
board = sudoku.get_board()
return board