diff --git a/__main__.py b/__main__.py index 032fb42..1309361 100644 --- a/__main__.py +++ b/__main__.py @@ -99,8 +99,8 @@ def main(): pretty_alg.extend(solution.alg) if solution.post_auf: pretty_alg.append(solution.post_auf) - if solution.mc: - pretty_alg.append("M") + if solution.post_ams: + pretty_alg.append(solution.post_ams) pretty_finger_tricks = build_pretty_string_from_finger_tricks_with_regrips( finger_tricks ) @@ -116,6 +116,7 @@ def main(): "raw_alg": " ".join(solution.alg), "pre_auf": solution.pre_auf, "post_auf": solution.post_auf, + "post_ams": solution.post_ams, "finger_tricks": pretty_finger_tricks, } ) diff --git a/cube.py b/cube.py index 7d098d2..079a8dd 100644 --- a/cube.py +++ b/cube.py @@ -119,6 +119,21 @@ class LSECube: return "U" return "" + def fix_m_slice(self) -> str: + match self.centers["U"]: + case "U": + return "" + case "B": + self.Mp() + return "M'" + case "D": + self.M2() + return "M2" + case "F": + self.M() + return "M" + return "" + def alg(self, alg: str): move_functions = { "U": self.U, diff --git a/move_score_approx.py b/move_score_approx.py new file mode 100644 index 0000000..e1ef325 --- /dev/null +++ b/move_score_approx.py @@ -0,0 +1,72 @@ +""" +use least squares to estimate the time it takes for each move. +to use this, you can start a cstimer session of M and U moves (3x3x3 substes -> roux generator) and time how much time it takes you to scramble each scramble. +you can then export the session and paste the times to this script. +this is experimenal and deosn't work very well +""" + +from typing import List +from dataclasses import dataclass +from collections import Counter +from typing import List, Dict +import numpy as np +from scipy.linalg import lstsq + +POSSIBLE_MOVES = {"M", "M2", "M'", "U", "U'", "U2"} + + +@dataclass +class Solve: + scramble: List[str] + time: float + + +def multiline_input() -> List[str]: + print("Enter/Paste your content. Ctrl-D or Ctrl-Z ( windows ) to save it.") + contents = [] + while True: + try: + line = input() + except EOFError: + break + contents.append(line) + return contents + + +def parse_cstimer_session_solves(lines: List[str]) -> List[Solve]: + solves = [] + for line in lines: + if line: + parts = line.split() + time = float(parts[1]) + scramble = parts[2:] + solves.append(Solve(time=time, scramble=scramble)) + return solves + + +def approximate_move_times(solves: List[Solve]) -> Dict[str, float]: + times = [] + move_counters = [] + for solve in solves: + times.append(solve.time) + move_counter = Counter(solve.scramble) + for move in POSSIBLE_MOVES: + move_counter[move] = move_counter.get(move, 0) + print(move_counter, solve.time) + move_counters.append(list(move_counter.values())) + + x, _, _, _ = lstsq(move_counters, times) + move_times = {} + for i, move in enumerate(POSSIBLE_MOVES): + move_times[move] = x[i] + return move_times + + +def main(): + session_times_raw = multiline_input() + solves = parse_cstimer_session_solves(session_times_raw) + print(approximate_move_times(solves)) + + +if __name__ == "__main__": + main() diff --git a/solver.py b/solver.py index acc07db..7f8937f 100644 --- a/solver.py +++ b/solver.py @@ -4,7 +4,6 @@ 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 @@ -13,7 +12,7 @@ class EOLRBSolution: alg: List[str] pre_auf: str post_auf: str - mc: bool + post_ams: str def lse_brute_force_generator(max_length: int): @@ -80,19 +79,23 @@ def solve_eolrb(cube: LSECube, prune_table: Dict, solve: int): 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: - # 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) + 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}"