-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdemo_util.py
221 lines (209 loc) · 7.67 KB
/
demo_util.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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
from prevedbe import *
from util import *
from chaff import chaff
from re import sub
from os import path
from time import clock
from bf_dpll import bfSAT, DPLL
from resitelj import resitelj
#a = sudoku([["Bla",None,None,None],["Kor",None,None,None],["AS",None,None,None],["MA",None,None,None]])
def resi_sudoku(tabela=[], input_file="", izpisi=False, output_file="", solver = "chaff", izpis_output_file="", cas = False):
""" v datoteki pričakuje sudoku v formatu (primer 2x2):
# a,b \n
# c,d \n
, kjer so lahko a,b,c in d poljubni neprazni nizi oz. števila, razen 0.
0, \prazno in None so rezervirani za prazno polje.
V podani datoteki naj bo samo en sudoku in naj ne bo praznih vrstic."""
if type(tabela)!= list:
raise UsageError("Podan \"sudoku\" ni tabela.")
if solver not in ["DPLL","resitelj","bfSAT", "chaff"]:
raise UsageError("Podali ste solver, ki ni implementiran! (ali pa ste se zatipkali)")
if not tabela:
if not input_file:
raise UsageError("Nisete podali sudokuja!")
## try:
if not path.isfile(input_file):
raise UsageError("Podana datoteka z vhodnimi podatki ne obstaja!")
f = open(input_file,"r",encoding="utf-8")
file = f.read()
vrstice = file.split("\n")
k=1
for i in vrstice:
if i:
k+=1
vrstice=vrstice[:k]
n = k-1
#print(n)
if "," in file:
locilo = ","
elif ";" in file:
locilo = ";"
elif n == 1:
locilo = " " #imamo 1x1 sudoku, ničesar ne rabimo ločiti.
else:
raise UsageError("Ločilo med polji je napačno!")
if not vrstice:
raise UsageError("Podana datoteka je prazna!.")
tabela = [None]*n
for i in range(n):
k = vrstice[i].split(locilo)
if len(k)!=n:
raise UsageError("{0}. vrstica v datoteki ima premalo/preveč elementov.".format(i+1))
tabela[i] = k
#print(tabela)
f.close()
## except:
## raise InternalError("Nekaj je šlo narobe pri branju datoteke,"+
## "prosim pošljite nam email s podatki o vhodu,"+
## "pri katerem je prišlo do te napake.")
n = len(tabela)
k = int(n**0.5)
if k*k !=n:
raise UsageError("Podana tabela ne predstavlja sudokuja, saj dolžina stranice ni popoln kvadrat!")
#print(sudoku(tabela))
for i in range(n):
if len(tabela[i])!=n:
raise UsageError("{0}. vrstica v \"sudokuju\" ima premalo/preveč elementov.".format(i+1))
elif type(tabela[i])!=list:
raise UsageError("{0}. \"vrstica\" v \"sudokuju\" ni tabela.".format(i+1))
if izpisi: print("\nNaloga:\n");prikazi(tabela);print("\ndelam... \n")
cas1=clock()
res = eval(solver+"(sudoku(tabela))")
cas2=clock()
if cas: print("Porabljen čas: {0}".format(cas2-cas1))
#za to si rabimo nekje zapomnit imena
#res = eval(sub(r"([^\(]+?)([0-9]+)([^\)]+?)",r"\1imena[\2-1]\3",str(res))
if res == "Formula ni izpolnljiva":
print("Rešitev problema ne obstaja!")
return None
resitev = resit(res,n)
if izpisi:
print("\nRešeni sudoku: \n")
prikazi(resitev)
if output_file:
if not path.isfile(output_file):
raise UsageError("Datoteka, kamor naj bi zapisal rezultat ne obstaja!")
f = open(output_file,"w",encoding="utf-8")
file = ""
for i in resitev:
s = ""
for j in i:
s+= str(j)+","
s = s[:-1]+"\n"
file+=s
f.write(file[:-1])
f.close()
if izpis_output_file:
if not path.isfile(izpis_output_file):
raise UsageError("Datoteka, kamor naj bi izpisal rezultat ne obstaja!")
f = open(izpis_output_file,"w",encoding="utf-8")
f.write(prikazi(resitev,file = True))
f.close()
return None
def resit1(rezultat,n):
resitev = [[None]*n for j in range(n)]
barve = [None]*n
rezultat = eval(sub(r"(\")+",r"\"",str(rezultat)))
for i in rezultat.keys():
j = eval(i)
if rezultat[i] and j[0][0] != "(":
barve[j[1]] = j[0]
for i in rezultat.keys():
j = eval(i)
if rezultat[i] and j[0][0] == "(":
j = eval(j[0]),j[1]
resitev[j[0][0]][j[0][1]] = barve[j[1]]
return resitev
def resit(rezultat,n):
resitev = [[None]*n for j in range(n)]
barve = [None]*n
rezultat = eval(sub(r"(\")+",r"\"",str(rezultat)))
for i in rezultat.keys():
j = eval(sub(r"([a-zA-Z]+)",r"'\1'",i))
if rezultat[i]:
resitev[j[0]][j[1]]=j[2]
return resitev
def prikazi(resitev,file=False):
#pravilno deluje samo za sudokuje (dolžina tabele mora biti pravilen kvadrat)
if type(resitev)!= list:
raise UsageError("Podan \"sudoku\" ni tabela.")
n = len(resitev)
k = int(n**0.5)
file1=""
for i in range(n):
if len(resitev[i])!=n:
raise UsageError("{0}. vrstica v \"sudokuju\" ima premalo/preveč elementov.".format(i+1))
elif type(resitev[i])!=list:
raise UsageError("{0}. \"vrstica\" v \"sudokuju\" ni tabela.".format(i+1))
for i in range(n):
for j in range(n):
if resitev[i][j] in ["0","None",0]:
resitev[i][j] = 0
resitev = eval(sub(r"[\"\']{2,}",r"'",str(resitev)))
naj = ""
for i in resitev:
for j in i:
if len(str(j))>len(naj):
naj = str(j)
m = len(naj)
## if m%2==0:
## m+=1
pomo1="#"+(("─"*(2+m)+" ")*(k-1)+"─"*(2+m)+"║")*(k-1)+("─"*(2+m)+" ")*(k-1)+"─"*(2+m)+"#"
#pomo1="#"+("─"*(2+m)+" ")*(n-1)+"─"*(2+m)+"#"
pomo2="#"+"="*((2+m)*n+n-1)+"#"
pomo3="#"*((2+m)*n+n-1+2)
file1+=pomo3+"\n"
for i in range(n):
s = "#"
for j in range(n):
l = (2+m-len(str(resitev[i][j])))//2
if 2*l + len(str(resitev[i][j])) == 2+m:
d = l
else:
d = l + 1
if j%k == k-1 and j != n-1:
s+=" "*l+str(resitev[i][j])+" "*d+"║"
elif j == n-1:
s+=" "*l+str(resitev[i][j])+" "*d+"#"
else:
s+=" "*l+str(resitev[i][j])+" "*d+"│"
file1+=s+"\n"
if i%k==k-1 and i != n-1:
file1+=pomo2+"\n"
elif i == n-1:
file1+=pomo3
else:
file1+=pomo1+"\n"
if not file:
#print("\nRešeni sudoku: \n")
print(file1)
return None
return file1
def izp():
izpisi = input("Ali naj sudoku lepo izpišem? (da/ne) ")
if izpisi and izpisi in "DAdaDaJAjaJaYESYesyes":
izpisi = True
elif izpisi and izpisi in "NEneNeNOnoNo":
izpisi = False
else:
print("Žal te nisem razumel, prosim poizkusi ponovno!")
return izp()
return izpisi
def sol():
solver = input("S katerim algoritmom zelite reševati problem? ")
if not solver:
solver = "resitelj"
elif solver not in ["DPLL","resitelj","bfSAT"]:
print("Algoritma \"{0}\" žal (še) nismo implementirali. Prosim, vnesite drug algoritem.".format(solver))
return sol()
return solver
def de():
dem = input("Ali želite demonstracijo? (da/ne) ")
if dem and dem in "DAdaDaJAjaJaYESYesyesSevedaseveda": dem = True
elif dem and dem in "NEneNeNOnoNoNikakornikakornikdarNikdarNikolinikoli": dem = False
else: print("Žal te nisem razumel, prosim poizkusi ponovno!");return de()
return dem
#Rezultati testiranja:
#chaff je porabil 0.42 časa DPLL na velikosti 70, pri 100 ponovitvah
#0.59, 100, 10
#0.34, 100, 50