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

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()