-
Notifications
You must be signed in to change notification settings - Fork 0
/
helper_functions.py
109 lines (83 loc) · 3.15 KB
/
helper_functions.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
import csv
from constraint import Problem, AllDifferentConstraint
from classes import Board
from datetime import datetime
def read_standard_puzzles(input_file):
"""
Reads puzzles from 3x3 csv format.
:param input_file: name of input file to be read
:return: an array of 2D array boards
"""
puzzles = []
with open(input_file) as f:
for line in f:
to_add = [[None for i in range(9)] for j in range(9)]
for i in range(len(line)-2):
to_add[i // 9][i % 9] = int(line[i]) if line[i] != '.' else 0
puzzles.append(to_add)
return puzzles
def read_jumbo_puzzles(input_file):
"""
Reads multiple 4x4 sudoku puzzle in csv format.
:param input_file: name of input file to be read
:return: an array of 2D array boards
"""
read_puzzles = []
with open(input_file, 'r') as f:
reader = csv.reader(f, delimiter=',')
for row in reader:
to_add = []
for i in range(16):
add_row = []
for j in range(16):
add_row.append(int(row[16*i+j]))
to_add.append(add_row)
read_puzzles.append(to_add)
return read_puzzles
def read_big_puzzle(input_file):
"""
Reads one 4x4 sudoku puzzle in csv format.
:param input_file: name of input file to be read
:return: an array of 2D array boards
NOTE: did not make it into the final version of the project :(
"""
puzzle = []
infile = csv.reader(open(input_file), delimiter=',')
for row in infile:
puzzle.append([int(entry) for entry in row])
return puzzle
def solve_puzzles(puzzles, solver):
"""
Solves an array of sudoku puzzles, recording runtime.
:param puzzles: an array of 2D array boards
:param solver: the CSP solver to be used
:return: none
"""
fail_count = 0
start_time = datetime.now() # start timer (for runtime)
for puzzle in puzzles:
# initialize Board
b = Board(puzzle)
sudoku = Problem(solver) # initialize CSP with custom solver
# add variables for each square, indexed 1...size^2
for index in range(b.board_size ** 2):
value = b.get_value(index)
if value == 0:
sudoku.addVariable(index, range(1, b.board_size + 1))
else:
sudoku.addVariable(index, [value])
# add uniqueness constraints to each row, column, and subsquare
for i in range(b.board_size):
sudoku.addConstraint(AllDifferentConstraint(), [el[0] for el in b.row(i)])
sudoku.addConstraint(AllDifferentConstraint(), [el[0] for el in b.col(i)])
sudoku.addConstraint(AllDifferentConstraint(), [el[0] for el in b.subsquare(i)])
sln = sudoku.getSolution() # solve CSP
if sln:
# assign solved values
for index, value in sln.items():
b.set_value(index, value)
else:
fail_count += 1
# perform/display runtime calculation
runtime = datetime.now() - start_time
print("Runtime: {} seconds ({} failed)".format(runtime.total_seconds(), fail_count))