Solving Rubik's Cubes
with F#
Stachu Korick | @stachudotnet | hello@stachu.net
Nov 17, 2018
Talk Inspiration
- Speed-Solving Rubik's Cubes
- And other pattern-related hobbies
- Writing F#
A bit about me
Stachu
site: stachu.net
.NET
email: hello@stachu.net
github: @stachudotnet
facebook: @stachudotnet
twitter: @stachudotnet
The Plan
- [10] (this) Intro
- [10] On-Ramp Domain Knowledge
- [15] Hands-on: How to represent and "turn" a cube?
- [15] Hands-on: How to scramble a Rubik's Cube?
- [15] Show off Inefficient Solvers
- (the Rubik's Cube is a "graph"!)
- [30] Discuss Efficient Solver Patterns
- (sure, but it's also a "group"!)
- [10] Show off SAFE usage (Fable+Elmish+Saturn)
- Hands-on opportunities!
- [10] Outro/Questions/Buffer
- (probably related to the Rubik's Cube speed-solving world)
A bit about the Rubik's Cube
My Cubing Background
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215161/pasted-from-clipboard.png)
My Cubing Background
The Physical Structure, Pt. 1
The core structure of the Rubik's Cube does not move relative to each
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5218895/pasted-from-clipboard.png)
The Physical Structure, Pt. 2
12 Edges surround the core and the centers.
Each of these 12 pieces has two orientations; "correct" and "flipped."
An edge cannot have opposite-side colors.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5218898/pasted-from-clipboard.png)
The Physical Structure, Pt. 3
8 "corner" pieces surround the core and edges.
Each of them has 3 orientations: "correct," "twisted clockwise" and "twisted counter-clockwise."
These also cannot have two "opposite" colors.
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5218901/pasted-from-clipboard.png)
Basic 6 Moves
- R(
ight ) - L(
eft ) - U(p)
- D(own)
- F(
ront ) - B(ack)
12 Derived Moves
- R is clockwise 90 degrees
- R' is counter-clockwise 90 degrees.
- R2 is the R face turned 180 degrees.
- ...
An Example Algorithm
Referring to
Certain Pieces
Creating a Simple Solver
-
Modeling the cube's state
-
Writing a scrambler
-
Transcribing the basic 18 'moves'
-
Getting *some* solver running
Challenge!
How can you store the state of a Rubik's Cube?
Representing the Cube
Facelet
Facelet Array
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5218903/pasted-from-clipboard.png)
Representing the Cube
Cubie
Piece Arrays
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5218904/pasted-from-clipboard.png)
Representing the Cube
CO+CP+EO+EP
CO + CP + EO + EP
CO: 0 <= x1 < 3^7
EO: 0 <= x2< 2^11
CP: 0 <= x3< 8!
EP: 0 <= x4< 12!
Representing the Cube
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215188/2018-08-30_09h24_19.png)
Representing the Cube
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5414102/pasted-from-clipboard.png)
Turning the Cube
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215203/pasted-from-clipboard.png)
Turning the Cube
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215197/pasted-from-clipboard.png)
Turning the Cube
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215208/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215210/pasted-from-clipboard.png)
Turning the Cube
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215209/pasted-from-clipboard.png)
Turning the Cube
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215212/pasted-from-clipboard.png)
Turning the Cube
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215213/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215214/pasted-from-clipboard.png)
Turning the Cube
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215215/pasted-from-clipboard.png)
Challenge!
Scramble a Rubik's Cube
Scrambling the Cube
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215217/pasted-from-clipboard.png)
Scrambling the Cube
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215218/pasted-from-clipboard.png)
The Cube is a Graph
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215233/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215234/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215237/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215238/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215240/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215243/pasted-from-clipboard.png)
R2 U2
R2
U2
U2 R2
U2 R2 U2 R2 U2 R2
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215252/pasted-from-clipboard.png)
U2 R2 U2
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215253/pasted-from-clipboard.png)
U2 R2 U2 R2
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215257/pasted-from-clipboard.png)
U2 R2 U2 R2 U2
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215270/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215272/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215273/pasted-from-clipboard.png)
R2 U2 R2
R2 U2 R2 U2
R2 U2 R2 U2 R2
Depth-First Tree Searching
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215223/pasted-from-clipboard.png)
Depth-First Tree Searching
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215228/pasted-from-clipboard.png)
IDA Tree Searching
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5215250/pasted-from-clipboard.png)
Why is this so slow?
- 43 quintillion is a big number. (really big)
- 18^20 is a big number. (even bigger)
- `Execute` takes a while to change cube state
Creating a Better Solver
Some Trade-offs for Consideration
- Human-Learnable
- Turning Ergonomics
- Support partially-defined cubes?
- Move Count
- Resource Requirements
- CPU, RAM, Disk Storage
- Speed
Program Human Algorithms?
The "CFOP" Method
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5300771/oll.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5300772/pll.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5300769/cross.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5300770/f2l.png)
Cross
F2L
(First 2 Layers)
OLL
(Orientation of the Last Layer)
PLL
(Permutation of the Last Layer)
Creating a Complex Solver
focus: run in a reasonable amount of time
The Kociemba Algorithm
Phase 1
Phase 2
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5218957/pasted-from-clipboard.png)
Solved:
- Edge Orientation
- Corner Orientation
- U/D Edges in U/D Layer
Solve the rest, using only <U,D,R2,L2,F2,B2>
Additional "tricks"
to Implement
- representing each of these components into simple 16-bit integers
(16bits is a lot less than an int array!) - move depth-caching caching
(how many moves deep various positions are away from a 'solved' state) - caching position-transitions
- storing the transitions between the 16bit numbers rather than computing them on the fly
- taking advantage of symmetries
- using sub-optimal phase 1 solutions
Storing Cube State Cheaply
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5218979/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5218980/pasted-from-clipboard.png)
Corner Orientation
Storing Cube State Cheaply
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5218982/pasted-from-clipboard.png)
Corner Permutation
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5218999/pasted-from-clipboard.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5219006/pasted-from-clipboard.png)
Move Tables
Symmetry Reductions
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5219019/pasted-from-clipboard.png)
Pruning Tables
function Treesearch(position p, depth d) if d = 0 then if p is solved then Hooray! else if d > 0 then if prune1[p] <= d and prune2[p] <= d then for each available move m Treesearch(result of m applied to p, d-1)
Pruning Tables
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5219108/pasted-from-clipboard.png)
Using Sub-Optimal Phase 1 Solutions
Let's See It in Action!
Running it all with SAFE
![](https://s3.amazonaws.com/media-p.slid.es/uploads/767151/images/5414019/pasted-from-clipboard.png)
Thanks! Questions?
@stachudotnet on twitter and
(hello@)stachu.net
Topic suggestions:
- What other puzzles are featured at competitions?
- Can you tell us a cubing story or two?
- How do people solve them blindfolded?
- Are you ever going to record another WTF# episode?
Solving Rubik's Cubes with F#
By Stachu Korick
Solving Rubik's Cubes with F#
- 1,732