Files
eolrb/solver.py
2024-08-24 13:48:36 +03:00

105 lines
3.1 KiB
Python

from collections import defaultdict
import itertools
import copy
from dataclasses import dataclass
from cube import LSECube, condense_algorithm, reverse_algorithm
from typing import Dict, List, Tuple
@dataclass
class EOLRBSolution:
alg: List[str]
pre_auf: str
post_auf: str
post_ams: str
def lse_brute_force_generator(max_length: int):
list1 = ["M", "M'", "M2"]
list2 = ["U", "U'", "U2"]
def valid_combination(comb):
# Ensure no adjacent elements are from the same list
if any(
(comb[i] in list1 and comb[i + 1] in list1)
or (comb[i] in list2 and comb[i + 1] in list2)
for i in range(len(comb) - 1)
):
return False
# # Ensure the combination does not end with a U move
# if comb and comb[-1] in list2:
# return False
return True
def generate_combinations():
# Generate combinations of increasing lengths
for length in range(1, max_length + 1):
for comb in itertools.product(list1 + list2, repeat=length):
if valid_combination(comb):
yield list(comb)
return generate_combinations()
#
# prune table
#
def create_eolrb_prune_table(prune_depth: int):
prune_table = defaultdict(list)
cube = LSECube()
prune_table[cube.eolrb_hash()] = [[]]
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:
cube.reset()
cube.alg(" ".join(alg))
prune_table[cube.eolrb_hash()].append(reverse_algorithm(alg))
return prune_table
def extract_pre_auf(alg: List[str]) -> Tuple[str, List[str]]:
if alg[0].startswith("U"):
pre_auf = alg.pop(0)
return pre_auf, alg
else:
return "", alg
def solve_eolrb(cube: LSECube, prune_table: Dict, solve: int):
for moves in lse_brute_force_generator(solve):
c = copy.deepcopy(cube)
c.alg(" ".join(moves))
if c.eolrb_hash() in prune_table:
for prune_solution in prune_table[c.eolrb_hash()]:
# TODO: split this function, very ugly copies and very long
prune_cube = copy.deepcopy(c)
prune_cube.alg(" ".join(prune_solution))
alg = condense_algorithm(moves + prune_solution)
# TODO: this is very weird
for _ in range(5):
alg = condense_algorithm(alg)
if len(alg) > 2:
pre_auf = ""
if alg[0].startswith("U"):
pre_auf = alg.pop(0)
post_auf = ""
if alg[-1].startswith("U"):
post_auf = alg.pop(-1)
post_ams = prune_cube.fix_m_slice()
yield EOLRBSolution(alg, pre_auf, post_auf, post_ams)
# for auf in ["U", "U2", "U'", ""]:
# c = copy.deepcopy(cube)
# auf_alg = f"{' '.join(alg)} {auf}"
# c.alg(auf_alg)
# if eolrb_solved(c):
# yield alg