-
Notifications
You must be signed in to change notification settings - Fork 3
/
solve_one_e50_subproblem.py
264 lines (240 loc) · 10.9 KB
/
solve_one_e50_subproblem.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
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
import datetime
import os
import re
import sys
# from reversi_misc import *
from reversi_solver_misc import read_empty50_tasklist_edax_knowledge
def drop_duplicate_knowledge(problem_obf):
# knowledgeファイルに完全一致する行が含まれている場合は除去する。
if os.path.isfile(f"knowledge_{problem_obf[:64]}.csv") is False:
return
with open(f"knowledge_{problem_obf[:64]}.csv", "r", encoding="utf-8") as f:
lines = [s.strip() for s in f.readlines()]
outputs = set()
with open(f"knowledge_{problem_obf[:64]}.csv", "w", encoding="utf-8") as f:
for i in range(len(lines)):
m = re.fullmatch(
r"([-OX]{64}\s[OX];,-?[0-9]+,-?[0-9]+,-?[0-9]+,-?[0-9]+),-?[0-9]+",
lines[i],
)
if m is None:
assert i == 0
f.write(lines[i] + "\n")
continue
if m.group(1) not in outputs:
f.write(lines[i] + "\n")
outputs.add(lines[i])
def read_all_obtained_knowledges():
# すべてのknowledgeを読み込む。
# 複数箇所にかかれている場合は、最も深く読まれているものだけを集める。
# 最も深く読まれているものが複数ある場合は、答えの範囲が狭いものを優先する。
print(
f"{datetime.datetime.now().strftime(r'%Y/%m/%d %H:%M:%S')} : start: read_all_obtained_knowledges"
)
obtained_knowledges = {}
knowledge_filenames = [
x
for x in os.listdir()
if "knowledge" in x and re.search(r"[-OX]{64}", x) is not None
]
for i in range(len(knowledge_filenames)):
filename = knowledge_filenames[i]
if os.path.isfile(filename) is not True:
continue
with open(filename, "r", encoding="utf-8") as f:
lines = [
x.strip()
for x in f.readlines()
if re.search(r"[-OX]{64}\s[OX];", x.strip()) is not None
]
for x in lines:
m = re.fullmatch(
r"([-OX]{64}\s[OX];),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+),-?[0-9]+",
x,
)
assert m is not None
obf = m.group(1)
if obf not in obtained_knowledges:
obtained_knowledges[obf] = x
else:
depth = int(m.group(2))
accuracy = int(m.group(3))
current_strength = depth * 100 + accuracy
mm = re.fullmatch(
r"([-OX]{64}\s[OX];),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+),-?[0-9]+",
obtained_knowledges[obf],
)
assert mm is not None
depth = int(mm.group(2))
accuracy = int(mm.group(3))
existing_strength = depth * 100 + accuracy
if current_strength > existing_strength:
obtained_knowledges[obf] = x
elif current_strength == existing_strength:
cur_lb = int(m.group(4))
cur_ub = int(m.group(5))
cur_range = cur_ub - cur_lb
exis_lb = int(mm.group(4))
exis_ub = int(mm.group(5))
exis_range = exis_ub - exis_lb
if (
cur_lb <= exis_lb
and exis_ub <= cur_ub
and exis_range < cur_range
):
obtained_knowledges[obf] = x
print(
f"{datetime.datetime.now().strftime(r'%Y/%m/%d %H:%M:%S')} : start: read_all_obtained_knowledges"
)
return obtained_knowledges
def solve_screening_tasklist(problem_obf, obtained_knowledges=None):
assert os.path.isfile("empty50_tasklist_edax_knowledge.csv")
tasklist = read_empty50_tasklist_edax_knowledge()
assert problem_obf in tasklist
assert os.path.isfile(f"{problem_obf[:64]}.csv")
# tasklistを読み込む
task_obfs = {}
with open(f"{problem_obf[:64]}.csv", "r", encoding="utf-8") as f:
task_lines = [x.strip() for x in f.readlines()]
lines = [x for x in task_lines if re.search(r"[-OX]{64}\s[OX];", x) is not None]
for x in lines:
m = re.fullmatch(
r"([-OX]{64}\s[OX];),(-?[0-9]{1,2}),(-?[0-9]{1,2}),(-?[0-9]{1,2})", x
)
assert m is not None
obf = m.group(1)
alpha = int(m.group(2))
beta = int(m.group(3))
estimated_score = int(m.group(4))
task_obfs[obf] = (alpha, beta, estimated_score)
if len(task_obfs) == 0:
return False
# すべてのknowledgeを読み込み、tasklist内の盤面に関するknowledgeを集める。
# 複数箇所にかかれている場合は、最も深く読まれているものだけを集める。
# 最も深く読まれているものが複数ある場合は、答えの範囲が狭いものを優先する。
obtained_knowledges = {}
knowledge_filenames = [
x
for x in os.listdir()
if "knowledge" in x and re.search(r"[-OX]{64}", x) is not None
]
for i in range(len(knowledge_filenames)):
filename = knowledge_filenames[i]
if os.path.isfile(filename) is not True:
continue
with open(filename, "r", encoding="utf-8") as f:
lines = [
x.strip()
for x in f.readlines()
if re.search(r"[-OX]{64}\s[OX];", x.strip()) is not None
]
for x in lines:
m = re.fullmatch(
r"([-OX]{64}\s[OX];),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+),-?[0-9]+",
x,
)
assert m is not None
obf = m.group(1)
if obf in task_obfs:
if obf not in obtained_knowledges:
obtained_knowledges[obf] = x
else:
depth = int(m.group(2))
accuracy = int(m.group(3))
current_strength = depth * 100 + accuracy
mm = re.fullmatch(
r"([-OX]{64}\s[OX];),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+),-?[0-9]+",
obtained_knowledges[obf],
)
assert mm is not None
depth = int(mm.group(2))
accuracy = int(mm.group(3))
existing_strength = depth * 100 + accuracy
if accuracy < 100:
continue # 100%未満のknowledgeは無視する。p006の前のcollect imperfect knowledgesでカバーされるので。
if current_strength > existing_strength:
obtained_knowledges[obf] = x
elif current_strength == existing_strength:
cur_lb = int(m.group(4))
cur_ub = int(m.group(5))
cur_range = cur_ub - cur_lb
exis_lb = int(mm.group(4))
exis_ub = int(mm.group(5))
exis_range = exis_ub - exis_lb
if (
cur_lb <= exis_lb
and exis_ub <= cur_ub
and exis_range < cur_range
):
obtained_knowledges[obf] = x
found_knowledges = {}
for obf, v in task_obfs.items():
if obf in obtained_knowledges:
found_knowledges[obf] = obtained_knowledges[obf]
flag_imparfect_knowledge_loaded = False
# knowledgeファイルに見つけた情報を追記する。knowledgeファイルに書かれたスコアの範囲と、taskのスコアの範囲が一致しない場合はフラグを立てる。
print(
f"{datetime.datetime.now().strftime(r'%Y/%m/%d %H:%M:%S')} : info: len(found_knowledges) = {len(found_knowledges)}"
)
with open(f"knowledge_{problem_obf[:64]}.csv", "a") as f:
for k, v in found_knowledges.items():
f.write(f"{obtained_knowledges[k].strip()}\n")
m = re.fullmatch(
r"([-OX]{64}\s[OX];),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+)",
v,
)
assert m is not None
knowledge_lb = int(m.group(4))
knowledge_ub = int(m.group(5))
task_alpha = task_obfs[k][0]
task_beta = task_obfs[k][1]
if task_beta < knowledge_lb or knowledge_ub < task_alpha:
flag_imparfect_knowledge_loaded = True
# tasklistのtaskのうち、完全読みのknowledgeが追記されたtaskを除去する。
os.remove(f"{problem_obf[:64]}.csv")
with open(f"{problem_obf[:64]}.csv", "w") as f:
for line in task_lines:
m = re.search(r"([-OX]{64})", line)
if m is not None:
obf = m.group(1) + " X;"
if obf in found_knowledges:
mm = re.fullmatch(
r"([-OX]{64}\s[OX];),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+),(-?[0-9]+)",
found_knowledges[obf],
)
assert mm is not None
depth = int(mm.group(2))
accuracy = int(mm.group(3))
if depth == 36 and accuracy == 100:
continue
f.write(f"{line}\n")
drop_duplicate_knowledge(problem_obf)
return flag_imparfect_knowledge_loaded
if __name__ == "__main__":
args = sys.argv
if len(args) != 2:
print("Error: len(args) == 2", file=sys.stderr)
sys.exit(1)
if re.fullmatch(r"[0-9]+", args[1]) is not None:
problem_number = int(args[1]) - 1 # 1-originで来るので
tasklist = read_empty50_tasklist_edax_knowledge()
if problem_number < 0 or len(tasklist) <= problem_number:
print("error: problem_number is invalid")
sys.exit(1)
problem_obf = tasklist[problem_number]
elif re.fullmatch(r"[-OX]{64}", args[1]) is not None:
assert args[1].count("-") == 50
problem_obf = args[1] + " X;"
else:
print("error: args[1] is invalid.")
sys.exit(1)
print(
f"{datetime.datetime.now().strftime(r'%Y/%m/%d %H:%M:%S')} : start: solve_screening_tasklist({problem_obf})"
)
flag = solve_screening_tasklist(problem_obf)
print(
f"{datetime.datetime.now().strftime(r'%Y/%m/%d %H:%M:%S')} : info: flag_imparfect_knowledge_loaded = {flag}"
)
print(
f"{datetime.datetime.now().strftime(r'%Y/%m/%d %H:%M:%S')} : finish: solve_screening_tasklist({problem_obf})"
)