A deep‑learning model to score Rubik’s cube algorithms, trained on human preference data. GitHub: https://github.com/nbwzx/neural-algorithm-scorer
We present a neural algorithm scorer for Rubik’s cube algorithms that predicts algorithm quality without explicit move‑count metrics. Trained end‑to‑end on a differentiable approximation of a crowdsourced ranking objective, the model assigns lower scores to better algorithms. Evaluated against a comprehensive set of baselines—standard move counts (STM, QTM), a weighted move count metric (WMC), and the Movecount Coefficient (MCC, implemented as algSpeed)—our method substantially outperforms all, achieving significantly higher alignment with human‑rated solutions. The lightweight Transformer architecture (embedding dimension 64, 3 layers, 4 attention heads, feed‑forward hidden size 256) with RMSNorm, SwiGLU, Rotary Position Embeddings, and attention dropout ensures stable training and strong generalisation.
In blindfolded cubing (BLD), there are 1008 different 3‑style corner cases. For each case, dozens of candidate algorithms exist, but top BLD solvers develop strong preferences that go beyond mere move count. For example, algorithms favouring faces like R, U, D, and F are generally faster and more comfortable than those involving B, L, or wide moves. These preferences reflect subtle ergonomic qualities—fingertrick ease, regrip avoidance, and overall flow—that are difficult to capture with hand‑crafted metrics.
Existing ranking approaches rely on static rules such as move length (STM, QTM), weighted sums of per‑move difficulties (Weighted Move Count), or the Movecount Coefficient (MCC). The MCC, introduced by Trangium, models finger burden, wrist turns, push moves, and regrips; our algSpeed implementation is the Python version of the original code. While more sophisticated than plain move counting, these rule‑based metrics are fixed and cannot adapt to human preferences or to subtle patterns that emerge from large‑scale human ratings.
Neural networks have been applied to solve the cube (e.g., DeepCubeA), but ranking algorithms for a given state has received less attention. We bridge this gap by learning a scoring function directly from user‑provided rankings.
We use two complementary data sources:
cornerManmade.json– For each cube state, this file provides a list of candidate algorithms along with user vote counts. These votes reflect the collective preferences of experienced solvers.cornerRanking.json– For each state, this file supplies a list of 200 good algorithms, which we treat as a high‑quality reference set.
From these, we construct for each state
-
$\mathcal{E}_s$ – the set of candidate algorithms drawn fromcornerManmade.json. -
$\mathcal{R}_s$ – the reference set of$K = 200$ algorithms (fromcornerRanking.json). In practice we sample or take the top entries to ensure$K$ is fixed across states. -
$r(a)$ – a user preference weight for algorithm$a \in \mathcal{E}_s$ , derived by aggregating votes.
Algorithms are tokenised into atomic moves (e.g., R, U', F2). A tokeniser is built from all unique moves in the union of both datasets. Sequences are padded to a fixed length
With the dataset constructs (
We learn a scoring function
For a given state
where
To enable end‑to‑end training, we replace the non‑differentiable indicator with a sigmoid:
with temperature TEMPERATURE = 0.1). As
The training loss is the average of
Minimising
We use a lightweight Transformer encoder (AlgorithmScorer) with the following hyperparameters (all configurable at the top of main.py):
- Token Embedding:
vocab_size × 64(embedding dimensionDIM = 64). - Rotary Position Embeddings (RoPE) – encodes relative positions for better sequence extrapolation.
- 3 layers (
NUM_LAYERS = 3) with:- Multi‑head self‑attention with 4 heads (
NUM_HEADS = 4, head dimension 16) with causal masking and dropout 0.1. - RMSNorm before each sub‑layer.
- SwiGLU activation in the feed‑forward network (inner dimension 256,
FF_HIDDEN_DIM = 256). - Residual dropout 0.1.
- Multi‑head self‑attention with 4 heads (
- Pooling: mean over the sequence, followed by a linear projection to a scalar score.
The total number of parameters is approximately 0.2 million, allowing fast inference on CPU and GPU.
States are split into training, validation, and test sets (75%/15%/10%) using a fixed random seed (SEED = 42) to ensure reproducibility. The tokeniser is built from the union of all algorithms, and token caching persists across epochs (and is saved in checkpoints) to avoid recomputation.
We use AdamW with learning rate LR = 1e-3) and weight decay WEIGHT_DECAY = 0.01, applied to all parameters except biases and layer‑norm weights). Gradients are clipped to norm 1.0. A batch consists of 16 states (BATCH_SIZE = 16); all candidate and reference algorithms are concatenated and processed in a single forward pass (dynamic batching) to reduce overhead.
We apply ReduceLROnPlateau (factor 0.5, patience 3) on the validation objective, and stop early if no improvement occurs for 10 epochs (PATIENCE = 10, max 100 epochs). The full training state is checkpointed after every epoch (auto‑resume from checkpoint.pt), with the best model saved as best_model.pth. During evaluation, memory‑aware batching (chunk size 64) is used to avoid OOM when scoring many algorithms.
The training loss drops from 0.031924 to 0.005136 over the course of training, while the validation loss follows a similar downward path with only modest fluctuations—suggesting stable convergence without overfitting. Plateaus in the validation loss trigger automatic learning rate reductions, which help the optimizer escape flat regions and continue making progress, as reflected in the sustained decline of both curves.
The validation objective, our primary metric, improves steadily from an initial value of 0.015929 to a best of 0.005921.
Our neural algorithm scorer consistently outperforms all baselines on the held-out test set. The numbers below are from a representative run using the default configuration.
| Method | Test Objective |
|---|---|
| STM (slice turn metric) | 0.132985 |
| QTM (quarter turn metric) | 0.085444 |
| WMC (weighted move count) | 0.031352 |
| MCC (movecount coefficient) | 0.025986 |
| Our model (Neural Algorithm Scorer) | 0.005813 |
Smaller values are better. Our model captures non‑length‑based quality signals and generalises well, as evidenced by the larger gap on the validation set.
python main.pyLoads data, builds the tokenizer, trains the model, and logs progress to a timestamped run folder (e.g., 20260101_120000/). All hyperparameters are defined at the top of main.py and can be adjusted.
Example commands:
-
Sort a simple ranking JSON (state → list of algs)
python export.py ranking.json output.json [--top-k 18] -
Sort cornerManmade.json (nested entries) by model score
python export.py cornerManmade.json cornerManmadeSorted.json -
Sort a plain text file (one alg per line)
python export.py algs.txt algs_sorted.txt --txt [--with-scores] [--top-k 100] -
Sort all .txt files in a directory
python export.py --dir data/ [--output-dir sorted/] [--top-k 100]
By default loads the best model from best/; override with --run-dir to point to a specific training run folder.
The original cornerRanking.json contains unsorted algorithms per state. Our export.py sorts them by model score (best first, i.e. lowest score = highest quality) and outputs a fully sorted version cornerRankingSorted.json, ready for manual reference.
Usage:
python export.py cornerRanking.json cornerRankingSorted.jsonWe have presented a neural algorithm scorer that focuses on Rubik’s cube 3‑style corner algorithms, significantly outperforming move‑count and ergonomic metrics by learning directly from human preferences. While our evaluation centres on 3-style corner cases, the approach is general and can be applied to other domains within cubing—including parity algorithms, 3‑style edges, or speedsolving substeps like ZBLL—provided similar preference data is available.
GPLv3 License – see LICENSE.
Copyright (C) 2026 Zixing Wang
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

