73 lines
2.0 KiB
Python
73 lines
2.0 KiB
Python
"""
|
|
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()
|