Compare commits
2 Commits
67e8c7a639
...
f012c0536f
| Author | SHA1 | Date | |
|---|---|---|---|
| f012c0536f | |||
| 50ceb636de |
@ -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,
|
||||
}
|
||||
)
|
||||
|
||||
15
cube.py
15
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,
|
||||
|
||||
72
move_score_approx.py
Normal file
72
move_score_approx.py
Normal file
@ -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()
|
||||
42
moves.yaml
42
moves.yaml
@ -95,11 +95,11 @@ regrips:
|
||||
- finger: index
|
||||
pre: B
|
||||
post: FL
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: index
|
||||
pre: B
|
||||
post: F
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: index
|
||||
pre: BL
|
||||
post: B
|
||||
@ -111,11 +111,11 @@ regrips:
|
||||
- finger: index
|
||||
pre: BL
|
||||
post: F
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: index
|
||||
pre: FL
|
||||
post: B
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: index
|
||||
pre: FL
|
||||
post: BL
|
||||
@ -127,11 +127,11 @@ regrips:
|
||||
- finger: index
|
||||
pre: F
|
||||
post: B
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: index
|
||||
pre: F
|
||||
post: BL
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: index
|
||||
pre: F
|
||||
post: FL
|
||||
@ -143,11 +143,11 @@ regrips:
|
||||
- finger: ring
|
||||
pre: B
|
||||
post: DF
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: ring
|
||||
pre: DB
|
||||
post: B
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: ring
|
||||
pre: DB
|
||||
post: DF
|
||||
@ -155,7 +155,7 @@ regrips:
|
||||
- finger: ring
|
||||
pre: DF
|
||||
post: B
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: ring
|
||||
pre: DF
|
||||
post: DB
|
||||
@ -167,15 +167,15 @@ regrips:
|
||||
- finger: pinky
|
||||
pre: B
|
||||
post: DF
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: pinky
|
||||
pre: B
|
||||
post: F
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: pinky
|
||||
pre: B
|
||||
post: F floating
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: pinky
|
||||
pre: DB
|
||||
post: B
|
||||
@ -187,15 +187,15 @@ regrips:
|
||||
- finger: pinky
|
||||
pre: DB
|
||||
post: F
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: pinky
|
||||
pre: DB
|
||||
post: F floating
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: pinky
|
||||
pre: DF
|
||||
post: B
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: pinky
|
||||
pre: DF
|
||||
post: DB
|
||||
@ -211,11 +211,11 @@ regrips:
|
||||
- finger: pinky
|
||||
pre: F
|
||||
post: B
|
||||
score: 1
|
||||
score: 3
|
||||
- finger: pinky
|
||||
pre: F
|
||||
post: DB
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: pinky
|
||||
pre: F
|
||||
post: DF
|
||||
@ -227,16 +227,16 @@ regrips:
|
||||
- finger: pinky
|
||||
pre: F floating
|
||||
post: B
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: pinky
|
||||
pre: F floating
|
||||
post: DB
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: pinky
|
||||
pre: F floating
|
||||
post: DF
|
||||
score: 1
|
||||
score: 2
|
||||
- finger: pinky
|
||||
pre: F floating
|
||||
post: F
|
||||
score: 1
|
||||
score: 2
|
||||
|
||||
11
solver.py
11
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}"
|
||||
|
||||
Reference in New Issue
Block a user