|
|
|
|
@ -1,6 +1,5 @@
|
|
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
|
|
import itertools
|
|
|
|
|
import functools
|
|
|
|
|
import json
|
|
|
|
|
import os.path
|
|
|
|
|
@ -88,24 +87,22 @@ class Explore:
|
|
|
|
|
|
|
|
|
|
return path
|
|
|
|
|
|
|
|
|
|
def explore(self, paths, probes=None, mark=Path()):
|
|
|
|
|
def explore(self, path=Path(), probes=None, mark=Path()):
|
|
|
|
|
probes = probes or self.probes
|
|
|
|
|
num_marks = mark.path.count("[")
|
|
|
|
|
|
|
|
|
|
expaths = []
|
|
|
|
|
for path in paths:
|
|
|
|
|
path = self._path(path)
|
|
|
|
|
expaths.extend(mark + path + probe for probe in probes)
|
|
|
|
|
path = self._path(path)
|
|
|
|
|
paths = [mark + path + probe for probe in probes]
|
|
|
|
|
|
|
|
|
|
num_marks = mark.path.count("[")
|
|
|
|
|
prefix_len = len(mark) - 2 * num_marks + len(path)
|
|
|
|
|
|
|
|
|
|
print("explore", paths)
|
|
|
|
|
response = api.explore([p.path for p in expaths])
|
|
|
|
|
response = api.explore([p.path for p in paths])
|
|
|
|
|
results = response["results"]
|
|
|
|
|
self.score = response["queryCount"]
|
|
|
|
|
|
|
|
|
|
for path, presults in zip(paths, itertools.batched(results, len(probes))):
|
|
|
|
|
prefix_len = len(mark) - 2 * num_marks + len(path)
|
|
|
|
|
print("id", path, results)
|
|
|
|
|
self.update(path, [res[prefix_len:] for res in presults])
|
|
|
|
|
print("id", path, results)
|
|
|
|
|
return [res[prefix_len:] for res in results]
|
|
|
|
|
|
|
|
|
|
def _add_room(self, path, results):
|
|
|
|
|
label = results[0][0]
|
|
|
|
|
@ -244,13 +241,10 @@ class Explore:
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
def unexplored(self):
|
|
|
|
|
unexplored = []
|
|
|
|
|
for path, ns in self.neighbors.items():
|
|
|
|
|
for d, (p, rid) in enumerate(ns):
|
|
|
|
|
if not rid:
|
|
|
|
|
unexplored.append((d, path))
|
|
|
|
|
if unexplored:
|
|
|
|
|
yield unexplored
|
|
|
|
|
yield d, path
|
|
|
|
|
|
|
|
|
|
def is_explored(self):
|
|
|
|
|
return next(self.unexplored(), None) is None and all(len(p) == 1 for p in self.room_ids.values())
|
|
|
|
|
@ -373,19 +367,19 @@ def mark_solve(problem, nrooms):
|
|
|
|
|
ex = Explore(problem, probes)
|
|
|
|
|
exs.append(ex)
|
|
|
|
|
|
|
|
|
|
ex.explore([Path()], mark=mark_loop)
|
|
|
|
|
res = ex.explore(Path(), mark=mark_loop)
|
|
|
|
|
ex.update(Path(), res)
|
|
|
|
|
ex.dump()
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
unexplored = next(ex.unexplored(), None)
|
|
|
|
|
door, unexplored = next(ex.unexplored(), (None, None))
|
|
|
|
|
if unexplored is None:
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
paths = []
|
|
|
|
|
for door, path in unexplored:
|
|
|
|
|
paths.append(path + Path([door]))
|
|
|
|
|
print("explore", unexplored)
|
|
|
|
|
ex.explore(paths, mark=mark_loop)
|
|
|
|
|
print("explore", door, unexplored)
|
|
|
|
|
path = unexplored + Path([door])
|
|
|
|
|
res = ex.explore(path, mark=mark_loop)
|
|
|
|
|
ex.update(path, res)
|
|
|
|
|
ex.unify_all()
|
|
|
|
|
ex.dump()
|
|
|
|
|
|
|
|
|
|
@ -430,7 +424,7 @@ def mark_solve(problem, nrooms):
|
|
|
|
|
if t == Path():
|
|
|
|
|
start = s
|
|
|
|
|
print("use as start", start)
|
|
|
|
|
assert start is not None
|
|
|
|
|
assert start
|
|
|
|
|
|
|
|
|
|
layout = ex.layout(orig=orig, start=starts[0])
|
|
|
|
|
guess_ok = api.guess(layout)
|
|
|
|
|
@ -439,6 +433,60 @@ def mark_solve(problem, nrooms):
|
|
|
|
|
return guess_ok
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def path_solve(problem, nrooms, plen):
|
|
|
|
|
maxlen = 18 * nrooms
|
|
|
|
|
probe = Path([random.randrange(6) for _ in range(plen)])
|
|
|
|
|
print("probe path", probe)
|
|
|
|
|
|
|
|
|
|
ex = Explore(problem, probe)
|
|
|
|
|
api.select(ex.problem)
|
|
|
|
|
|
|
|
|
|
def extendpath(path, maxlen):
|
|
|
|
|
while len(path) < maxlen - plen - 1:
|
|
|
|
|
path = path + Path([random.randrange(6)]) + probe
|
|
|
|
|
return path
|
|
|
|
|
|
|
|
|
|
def target(door, path):
|
|
|
|
|
print("target", door, path)
|
|
|
|
|
probe0 = extendpath(probe, maxlen - len(path))
|
|
|
|
|
probe1 = extendpath(Path([door]) + probe, maxlen - len(path))
|
|
|
|
|
|
|
|
|
|
res0, res1 = ex.explore(path, [probe0, probe1])
|
|
|
|
|
ex.update_path(path, door, res0[: plen + 1], res1[: plen + 2])
|
|
|
|
|
ex.dump()
|
|
|
|
|
ex.unify_all()
|
|
|
|
|
ex.dump()
|
|
|
|
|
|
|
|
|
|
i = plen + 1
|
|
|
|
|
while i + plen < len(res0):
|
|
|
|
|
ex.update(path + probe0[:i], [res0[i : i + 1], res0[i : i + plen + 1]])
|
|
|
|
|
ex.unify_all()
|
|
|
|
|
i += plen + 1
|
|
|
|
|
|
|
|
|
|
i = plen + 2
|
|
|
|
|
while i + plen < len(res1):
|
|
|
|
|
ex.update(path + probe1[:i], [res1[i : i + 1], res1[i : i + plen + 1]])
|
|
|
|
|
ex.unify_all()
|
|
|
|
|
i += plen + 1
|
|
|
|
|
|
|
|
|
|
target(0, Path())
|
|
|
|
|
ex.dump()
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
door, unexplored = next(ex.unexplored(), (None, None))
|
|
|
|
|
print("unexplored", door, unexplored)
|
|
|
|
|
if unexplored is None:
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
target(door, unexplored)
|
|
|
|
|
ex.dump()
|
|
|
|
|
|
|
|
|
|
print("explored", ex.is_explored())
|
|
|
|
|
if ex.is_explored():
|
|
|
|
|
print("guess", ex.guess())
|
|
|
|
|
print("score", ex.score)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
problem = sys.argv[1]
|
|
|
|
|
|
|
|
|
|
@ -456,9 +504,9 @@ if __name__ == "__main__":
|
|
|
|
|
api.clean_explore_cache()
|
|
|
|
|
except ExploreError as exc:
|
|
|
|
|
api.clean_explore_cache()
|
|
|
|
|
raise exc
|
|
|
|
|
print(exc)
|
|
|
|
|
except Exception as exc:
|
|
|
|
|
api.write_explore_cache()
|
|
|
|
|
raise exc
|
|
|
|
|
print(exc)
|
|
|
|
|
|
|
|
|
|
sys.exit(0 if ok else 1)
|
|
|
|
|
|