first explorer
parent
fe70efb1f3
commit
10a976fc70
@ -0,0 +1,3 @@
|
||||
**/venv
|
||||
**/*.pyc
|
||||
**/__pycache__
|
||||
@ -0,0 +1,37 @@
|
||||
import os.path
|
||||
from argparse import Namespace
|
||||
from typing import List
|
||||
|
||||
import requests
|
||||
|
||||
config = {}
|
||||
with open(os.path.join(os.path.dirname(__file__), "..", "config")) as h:
|
||||
for line in h.readlines():
|
||||
parts = line.strip().split("=")
|
||||
config[parts[0].lower()] = parts[1].replace('"', "")
|
||||
|
||||
config = Namespace(**config)
|
||||
|
||||
|
||||
class APIError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def select_problem(problem: str):
|
||||
response = requests.post(config.contest_url + "/select", json={"problemName": problem, "id": config.id})
|
||||
if not response.ok:
|
||||
raise APIError(response.text)
|
||||
|
||||
data = response.json()
|
||||
return data["problemName"]
|
||||
|
||||
|
||||
def explore(plans: List[str]):
|
||||
response = requests.post(
|
||||
config.contest_url + "/explore",
|
||||
json={"plans": plans, "id": config.id},
|
||||
)
|
||||
if not response.ok:
|
||||
raise APIError(response.text)
|
||||
|
||||
return response.json()
|
||||
@ -0,0 +1,157 @@
|
||||
import api
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
class ExploreError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Explore:
|
||||
def __init__(self, problem):
|
||||
self.problem = problem
|
||||
self.rooms = {}
|
||||
self.room_ids = defaultdict(lambda: set())
|
||||
self.neighbors = {}
|
||||
|
||||
self.unification_id = {}
|
||||
self.unifications = defaultdict(lambda: set())
|
||||
|
||||
def _path(self, path):
|
||||
return self.unification_id.get(path, path)
|
||||
|
||||
def id_room(self, path):
|
||||
path = self._path(path)
|
||||
if path in self.room_ids:
|
||||
return self.r
|
||||
|
||||
paths = [path + str(i) for i in range(6)]
|
||||
self.neighbors[path] = [(p, None) for p in paths]
|
||||
|
||||
results = api.explore(paths)["results"]
|
||||
|
||||
# print("id", path, results)
|
||||
label = results[0][-2]
|
||||
neighbors = [r[-1] for r in results]
|
||||
|
||||
room_id = str(label) + "".join(str(n) for n in neighbors)
|
||||
self.rooms[path] = room_id
|
||||
self.room_ids[room_id].add(path)
|
||||
|
||||
# update pen-ultimate room
|
||||
if path:
|
||||
p, rid = self.neighbors[path[:-1]][int(path[-1])]
|
||||
self.neighbors[path[:-1]][int(path[-1])] = (p, room_id)
|
||||
|
||||
return room_id
|
||||
|
||||
def dump(self):
|
||||
print(self.problem + " rooms:")
|
||||
for r, rid in self.rooms.items():
|
||||
print(f" {r:<10}: {rid} {self.neighbors[r]}")
|
||||
print()
|
||||
for rid, paths in self.room_ids.items():
|
||||
print(f" {rid}: {paths}")
|
||||
|
||||
print()
|
||||
|
||||
def unify(self, path1, path2):
|
||||
"""
|
||||
try to unify rooms at paths p1, p2
|
||||
return unified rooms
|
||||
"""
|
||||
|
||||
path1 = self._path(path1)
|
||||
path2 = self._path(path2)
|
||||
|
||||
if path1 == path2:
|
||||
return
|
||||
|
||||
if path1 not in self.rooms:
|
||||
raise ExploreError(f"room '{path1}' not explored")
|
||||
if path2 not in self.rooms:
|
||||
raise ExploreError(f"room '{path2}' not explored")
|
||||
|
||||
if self.rooms[path1] != self.rooms[path2]:
|
||||
raise ExploreError(f"ids of '{path1}'({self.rooms[path1]}) and '{path2}'({self.rooms[path2]}) do not match")
|
||||
|
||||
path = min(path1, path2)
|
||||
pmerge = max(path1, path2)
|
||||
room_id = self.rooms[path]
|
||||
|
||||
rooms = self.rooms.copy()
|
||||
room_ids = self.room_ids.copy()
|
||||
neighbors = self.neighbors.copy()
|
||||
unifications = self.unifications.copy()
|
||||
unification_id = self.unification_id.copy()
|
||||
|
||||
merged_neighbors = []
|
||||
for n, ((p, rid), (pm, rmid)) in enumerate(zip(neighbors[path], neighbors[pmerge])):
|
||||
if rid and rmid and rid != rmid:
|
||||
raise ExploreError(f"neighbor {n} of '{path}'({rid}) and '{pmerge}'({rmid}) do not match")
|
||||
merged_neighbors.append((p, rid or rmid))
|
||||
|
||||
# unify paths
|
||||
unification_id[pmerge] = path
|
||||
for p in unifications[pmerge]:
|
||||
unification_id[p] = path
|
||||
|
||||
unifications[path] = unifications[path1] | unifications[path2] | {pmerge}
|
||||
if pmerge in unifications:
|
||||
del unifications[pmerge]
|
||||
|
||||
# fix rooms
|
||||
del rooms[pmerge]
|
||||
|
||||
room_ids[room_id] = {p for p in room_ids[room_id] if p != pmerge}
|
||||
|
||||
neighbors[path] = merged_neighbors
|
||||
del neighbors[pmerge]
|
||||
|
||||
for p, ns in neighbors.items():
|
||||
new = []
|
||||
for np, rid in ns:
|
||||
if np.startswith(pmerge):
|
||||
new.append((path + np[len(pmerge) :], rid))
|
||||
else:
|
||||
new.append((np, rid))
|
||||
neighbors[p] = new
|
||||
|
||||
unified = self.__class__(self.problem)
|
||||
unified.rooms = rooms
|
||||
unified.room_ids = room_ids
|
||||
unified.neighbors = neighbors
|
||||
unified.unifications = unifications
|
||||
unified.unification_id = unification_id
|
||||
|
||||
return unified
|
||||
|
||||
|
||||
def test():
|
||||
ex = Explore("probatio")
|
||||
ex.rooms = {
|
||||
"": "0101112",
|
||||
"0": "1002001",
|
||||
"1": "0101112",
|
||||
"2": "1002001",
|
||||
"3": "1002001",
|
||||
"4": "1002001",
|
||||
"5": "2212022",
|
||||
}
|
||||
ex.room_ids = {"0101112": {"", "1"}, "1002001": {"0", "2", "3", "4"}, "2212022": {"5"}}
|
||||
ex.neighbors = {
|
||||
"": [
|
||||
("0", "1002001"),
|
||||
("1", "0101112"),
|
||||
("2", "1002001"),
|
||||
("3", "1002001"),
|
||||
("4", "1002001"),
|
||||
("5", "2212022"),
|
||||
],
|
||||
"0": [("00", None), ("01", None), ("02", None), ("03", None), ("04", None), ("05", None)],
|
||||
"1": [("10", None), ("11", None), ("12", None), ("13", None), ("14", None), ("15", None)],
|
||||
"2": [("20", None), ("21", None), ("22", None), ("23", None), ("24", None), ("25", None)],
|
||||
"3": [("30", None), ("31", None), ("32", None), ("33", None), ("34", None), ("35", None)],
|
||||
"4": [("40", None), ("41", None), ("42", None), ("43", None), ("44", None), ("45", None)],
|
||||
"5": [("50", None), ("51", None), ("52", None), ("53", None), ("54", None), ("55", None)],
|
||||
}
|
||||
return ex
|
||||
@ -0,0 +1 @@
|
||||
requests
|
||||
Loading…
Reference in New Issue