-
Notifications
You must be signed in to change notification settings - Fork 0
/
generate.py
113 lines (78 loc) · 2.6 KB
/
generate.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
from argparse import ArgumentParser
from os import path
from re import fullmatch
from math import sqrt
from random import randint
import numpy as np
from detail.load import load
from detail.dump import dump
def transpose(matrix):
return list(map(list, [*zip(*matrix)]))
def relabel(matrix):
replacements = {
original: replacement
for original, replacement in zip(
range(1, len(matrix) + 1),
np.random.permutation(range(1, len(matrix) + 1))
)
}
for i in range(len(matrix)):
for j in range(len(matrix)):
if matrix[i][j] is not None:
matrix[i][j] = replacements[matrix[i][j]]
return matrix
def reorder(matrix):
def swap_rows(matrix):
m = int(sqrt(len(matrix)))
for p in range(m):
for q in range(m):
for r in range(m):
i1 = randint(m * p, m * (p + 1) - 1)
i2 = randint(m * p, m * (p + 1) - 1)
matrix[i1], matrix[i2] = matrix[i2], matrix[i1]
return matrix
return transpose(swap_rows(transpose(swap_rows(matrix))))
if __name__ == "__main__":
methods = {
"transpose": transpose,
"relabel": relabel,
"reorder": reorder
}
argparser = ArgumentParser(
description="Creating Variations on Sudoku Puzzles"
)
argparser.add_argument(
"-l", "--load",
help="a file representing an unsolved sudoku puzzle",
required=True
)
argparser.add_argument(
"-s", "--save",
help="the name of the new sudoku puzzle",
required=True
)
argparser.add_argument(
"-m", "--method",
help="the method used to create the new sudoku puzzle",
required=True
)
argparser.add_argument(
"-f", "--force",
help="do not prompt before overwriting",
action="store_true"
)
args = argparser.parse_args()
if args.load and not path.exists(args.load):
raise ValueError(f"'{args.load}' does not exist")
if args.save:
if path.exists(args.save) and not args.force:
answer = input(f"Would you like to overwrite '{args.save}': ")
if not fullmatch(r"y|Y|yes|YES|", answer):
raise ValueError(
f"Failed to save the linear programming formulation as '{args.save}'")
if args.method not in methods:
raise ValueError(
f"'{args.method}' is not a supported sudoku generation method")
matrix = load(args.load)
matrix = methods[args.method](matrix)
dump(matrix, args.save)