add masking

This commit is contained in:
2024-08-24 10:24:27 +03:00
parent 47f2989373
commit 7e247e8980
4 changed files with 31 additions and 26 deletions

View File

@ -11,7 +11,7 @@ from eolr import (
) )
import humanize import humanize
from dataclasses import dataclass from dataclasses import dataclass
from solver import EOLRBSolution, solve_eolrb, create_prune_table from solver import EOLRBSolution, solve_eolrb, create_eolrb_prune_table
from scorer import ( from scorer import (
FingerTrickWithRegrip, FingerTrickWithRegrip,
load_config, load_config,
@ -21,7 +21,7 @@ from scorer import (
import heapq import heapq
from typing import List, Any, Generator, Dict from typing import List, Any, Generator, Dict
SOLUTIONS_TO_EVAL = 40 SOLUTIONS_TO_EVAL = 1000
SOLUTIONS_TO_SHOW = 3 SOLUTIONS_TO_SHOW = 3
PRUNE = 10 PRUNE = 10
@ -52,7 +52,7 @@ def load_or_generate_prune_table(file_path: str, prune_size: int) -> Dict:
return pickle.load(file) return pickle.load(file)
else: else:
print("generating prune table...") print("generating prune table...")
prune_table = create_prune_table(prune_size) prune_table = create_eolrb_prune_table(prune_size)
print("saving prune table to", file_path) print("saving prune table to", file_path)
with open(file_path, "wb") as file: with open(file_path, "wb") as file:
pickle.dump(prune_table, file) pickle.dump(prune_table, file)
@ -61,7 +61,6 @@ def load_or_generate_prune_table(file_path: str, prune_size: int) -> Dict:
def main(): def main():
config = load_config("./moves.yaml") config = load_config("./moves.yaml")
prune_table = load_or_generate_prune_table("prune_table.pkl", PRUNE) prune_table = load_or_generate_prune_table("prune_table.pkl", PRUNE)
print("prune table size:", humanize.naturalsize(sys.getsizeof(prune_table))) print("prune table size:", humanize.naturalsize(sys.getsizeof(prune_table)))
@ -113,6 +112,7 @@ def main():
{ {
"alg": " ".join(pretty_alg), "alg": " ".join(pretty_alg),
"stm": len(solution.alg), "stm": len(solution.alg),
# "mc": solution.mc,
"score": score, "score": score,
"raw_alg": " ".join(solution.alg), "raw_alg": " ".join(solution.alg),
"pre_auf": solution.pre_auf, "pre_auf": solution.pre_auf,

28
cube.py
View File

@ -38,12 +38,12 @@ class LSECube:
# "DF": Edge("DF", True), # "DF": Edge("DF", True),
# } # }
self.edges = { self.edges = {
"UB": Edge("", True), "UB": Edge("UB", True),
"UR": Edge("UR", True), "UR": Edge("UR", True),
"UF": Edge("", True), "UF": Edge("UF", True),
"UL": Edge("UL", True), "UL": Edge("UL", True),
"DB": Edge("", True), "DB": Edge("DB", True),
"DF": Edge("", True), "DF": Edge("DF", True),
} }
self.centers = { self.centers = {
"U": "U", "U": "U",
@ -58,16 +58,22 @@ class LSECube:
"UBL": "UBL", "UBL": "UBL",
} }
def __hash__(self): def eolrb_hash(self):
# TODO: I fucking hate this language. why can't hashing be simpelr # TODO: I fucking hate this language. why can't hashing be simpelr
hash_dict = lambda d: hashlib.md5(str(sorted(d.items())).encode()).hexdigest() hash_dict = lambda d: hashlib.md5(str(sorted(d.items())).encode()).hexdigest()
edges_hash = hash_dict(self.edges) eolrb_state = {}
centers_hash = hash_dict(self.centers) # mask edges to only care about LR edges and orientation of everything else
corners_hash = hash_dict(self.corners) for location, edge in self.edges.items():
if edge.name in ["UR", "UL"]:
eolrb_state[location] = edge
else:
eolrb_state[location] = Edge("", edge.oriented)
eolrb_state["center_oriented"] = self.centers["U"] in ["U", "D"]
eolrb_state["UFR"] = self.corners["UFR"]
return int( return int(
hashlib.md5( hashlib.md5(hash_dict(eolrb_state).encode()).hexdigest(),
(edges_hash + centers_hash + corners_hash).encode()
).hexdigest(),
16, 16,
) )

View File

@ -1,3 +1,4 @@
# TODO: do a lot of random MU algs and find out which moves are statistically faster
finger_tricks: finger_tricks:
- name: "U push" - name: "U push"
move: "U" move: "U"

View File

@ -50,19 +50,19 @@ def lse_brute_force_generator(max_length: int):
# #
def create_prune_table(prune_depth: int): def create_eolrb_prune_table(prune_depth: int):
prune_table = defaultdict(list) prune_table = defaultdict(list)
cube = LSECube() cube = LSECube()
prune_table[hash(cube)] = [[]] prune_table[cube.eolrb_hash()] = [[]]
generator = lse_brute_force_generator(prune_depth) generator = lse_brute_force_generator(prune_depth)
# TODO: for every solved state (pre auf), we can apply the generator's moves and save to prune table?
for alg in generator: for alg in generator:
# TODO: turn the prune table into a dict of list values to store multiple solutions
cube.reset() cube.reset()
cube.alg(" ".join(alg)) cube.alg(" ".join(alg))
setup = reverse_algorithm(alg) solution = reverse_algorithm(alg)
prune_table[hash(cube)].append(setup) prune_table[cube.eolrb_hash()].append(solution)
return prune_table return prune_table
@ -79,15 +79,13 @@ def solve_eolrb(cube: LSECube, prune_table: Dict, solve: int):
for moves in lse_brute_force_generator(solve): for moves in lse_brute_force_generator(solve):
c = copy.deepcopy(cube) c = copy.deepcopy(cube)
c.alg(" ".join(moves)) c.alg(" ".join(moves))
if hash(c) in prune_table: if c.eolrb_hash() in prune_table:
for alg_start in prune_table[hash(c)]: for prune_solution in prune_table[c.eolrb_hash()]:
alg = condense_algorithm(alg_start + moves) alg = condense_algorithm(moves + prune_solution)
# TODO: this is very weird # TODO: this is very weird
for _ in range(10): for _ in range(10):
alg = condense_algorithm(alg) alg = condense_algorithm(alg)
if len(alg) == 0: if len(alg) > 2:
yield EOLRBSolution(alg, "", "", False)
else:
# TODO: check if this is mc # TODO: check if this is mc
pre_auf = "" pre_auf = ""
if alg[0].startswith("U"): if alg[0].startswith("U"):