105 lines
3.0 KiB
Python
105 lines
3.0 KiB
Python
from collections import defaultdict
|
|
import itertools
|
|
import copy
|
|
|
|
from dataclasses import dataclass
|
|
from cube import LSECube, condense_algorithm, reverse_algorithm
|
|
from eolr import eolrb_solved
|
|
from typing import Dict, List, Tuple
|
|
|
|
|
|
@dataclass
|
|
class EOLRBSolution:
|
|
alg: List[str]
|
|
pre_auf: str
|
|
post_auf: str
|
|
mc: bool
|
|
|
|
|
|
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_prune_table(prune_depth: int):
|
|
prune_table = defaultdict(list)
|
|
cube = LSECube()
|
|
prune_table[hash(cube)] = [[]]
|
|
|
|
generator = lse_brute_force_generator(prune_depth)
|
|
|
|
for alg in generator:
|
|
# TODO: turn the prune table into a dict of list values to store multiple solutions
|
|
cube.reset()
|
|
cube.alg(" ".join(alg))
|
|
setup = reverse_algorithm(alg)
|
|
prune_table[hash(cube)].append(setup)
|
|
|
|
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 hash(c) in prune_table:
|
|
for alg_start in prune_table[hash(c)]:
|
|
alg = condense_algorithm(alg_start + moves)
|
|
# TODO: this is very weird
|
|
for _ in range(10):
|
|
alg = condense_algorithm(alg)
|
|
if len(alg) == 0:
|
|
yield EOLRBSolution(alg, "", "", False)
|
|
else:
|
|
# TODO: check if this is mc
|
|
pre_auf = ""
|
|
if alg[0].startswith("U"):
|
|
pre_auf = alg.pop(0)
|
|
post_auf = ""
|
|
if alg[-1].startswith("U"):
|
|
post_auf = alg.pop(-1)
|
|
yield EOLRBSolution(alg, pre_auf, post_auf, False)
|
|
# 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
|