Types and helper functions to work with the Permutate Last Layer (PLL) algorithm set, the last step of the CFOP method. See https://www.speedsolving.com/wiki/index.php/PLL for further information
A non-empty list of all the PLLs. Can for example be used for randomly selecting a pll
import List.Nonempty
-- All the PLLs are there!
List.Nonempty.length all --> 21
-- We could for example select a random PLL case
-- via this
List.Nonempty.sample allGenerates a string of the identifying letters of the case.
This could be used either for serialization purposes, or for building a string to display the user in some instances.
-- Format is always first letter capitalized and
-- the second one lower case if applicable
getLetters Ua --> "Ua"
getLetters H --> "H"Check whether an algorithm solves a PLL case.
Note that actually solving the cube depends on it being in the correct execution angle as well and doing the last AUF. This function just checks if with those correctly aligned the algorithm can solve it. So different algorithms can pass this as seen in these examples:
import Algorithm
Algorithm.fromString "(x) R' U R' D2 R U' R' D2 R2 (x')"
|> Result.map (\alg -> solvedBy alg Aa)
--> Ok True
Algorithm.fromString "U (x) R' U R' D2 R U' R' D2 R2 (x')"
|> Result.map (\alg -> solvedBy alg Aa)
--> Ok True
Algorithm.fromString "(x) R' U R' D2 R U' R' D2 R2 (x') U"
|> Result.map (\alg -> solvedBy alg Aa)
--> Ok True
Algorithm.fromString "U"
|> Result.map (\alg -> solvedBy alg Aa)
--> Ok FalseCalculates and returns all pairs of AUFs that are equivalent to the given pair of AUFs for the given PLL
import AUF
import Expect
import Expect.Extra exposing (equalNonEmptyListMembers)
import List.Nonempty
getAllEquivalentAUFs ( AUF.None, H, AUF.None )
|> equalNonEmptyListMembers
(List.Nonempty.Nonempty
( AUF.None, AUF.None )
[ ( AUF.Clockwise, AUF.CounterClockwise )
, ( AUF.Halfway, AUF.Halfway )
, ( AUF.CounterClockwise, AUF.Clockwise )
]
)
--> Expect.passReturns a list of lists, where each sublist represents an equivalency class of AUF pairs for the given The equivalency classes are also exhaustive, so every possible AUF pair is represented in this list of lists
Describes a unique way to recognize the pll case from just the two sides given by the RecognitionAngle. It also describes one or more possibilities for how to recognize which way to do the final AUF.
Describes a unique way to recognize the pll case from just the two sides given by the RecognitionAngle
Describes one or more possibilities for how to recognize which way to do the final AUF
Either a type of pattern on the two sides or just a single sticker on the two sides.
All the possible patterns that we use to recognize the pll case.
The six visible stickers during two sided recognition.
Gets a two sided recognition specification that uniquely identifies the pll case and preAUF
The angle the cube is being looked at while doing two sided recognition
Describes looking at the cube so that the U F and L sides are visible
Describes looking at the cube so that the U F and R sides are visible
Occurs if the pll algorithm provided to getUniqueTwoSidedRecognitionSpecification for the case does not solve the case
A collection of algorithms that solves the respective case
Get the algorithm for the PLL case from an algorithm collection. This helps avoid any typos or need to write your own case statements in order to get the algorithm for a case passed to a function
getAlgorithm referenceAlgorithms Y
--> referenceAlgorithms.yPlls verified to be correct so they can be used to verify user selected plls or for displaying a pll case somewhere on the site.
They have been chosen to be the optimally lowest move count in HTM just for a small performance boost.
The example tests below are just meant for an easier to read version of all the algorithms that are verified to be correct. They are also tested via elm-verify-examples so the string versions are correct equivalents to the code below.
import Algorithm
-- Edges Only
Algorithm.fromString "R2 U2 R U2 R2 U2 R2 U2 R U2 R2"
--> Ok referenceAlgorithms.h
Algorithm.fromString "F2 U' (L R') F2 (L' R) U' F2"
--> Ok referenceAlgorithms.ua
Algorithm.fromString "F2 U (R' L) F2 (R L') U F2"
--> Ok referenceAlgorithms.ub
Algorithm.fromString "R B' R' B F R' F B' R' B R F2"
--> Ok referenceAlgorithms.z
-- Corners Only
Algorithm.fromString "R' F R' B2 R F' R' B2 R2"
--> Ok referenceAlgorithms.aa
Algorithm.fromString "R B' R F2 R' B R F2 R2"
--> Ok referenceAlgorithms.ab
Algorithm.fromString "D R' D2 F' D L D' F D2 R D' F' L' F"
--> Ok referenceAlgorithms.e
-- Corners And Edges
Algorithm.fromString "L F R' F' L' F' D2 B' L' B D2 F' R F2"
--> Ok referenceAlgorithms.f
Algorithm.fromString "F2' D (R' U R' U' R) D' F2 L' U L"
--> Ok referenceAlgorithms.ga
Algorithm.fromString "R' U' R B2 D (L' U L U' L) D' B2"
--> Ok referenceAlgorithms.gb
Algorithm.fromString "R2' D' F U' F U F' D R2 B U' B'"
--> Ok referenceAlgorithms.gc
Algorithm.fromString "R U R' F2 D' (L U' L' U L') D F2"
--> Ok referenceAlgorithms.gd
Algorithm.fromString "B2 R' U' R B2 L' D L' D' L2"
--> Ok referenceAlgorithms.ja
Algorithm.fromString "B2 (L U L') B2 (R D' R D) R2"
--> Ok referenceAlgorithms.jb
Algorithm.fromString "L U' R U2 L' U R' L U' R U2 L' U R'"
--> Ok referenceAlgorithms.na
Algorithm.fromString "R' U L' U2 R U' L R' U L' U2 R U' L"
--> Ok referenceAlgorithms.nb
Algorithm.fromString "F2 R' F' U' F' U F R F' U2 F U2 F'"
--> Ok referenceAlgorithms.ra
Algorithm.fromString "R2 F R U R U' R' F' R U2 R' U2 R"
--> Ok referenceAlgorithms.rb
Algorithm.fromString "F2 D R2 U' R2 F2 D' L2 U L2"
--> Ok referenceAlgorithms.t
Algorithm.fromString "R' U R' U' B' R' B2 U' B' U B' R B R"
--> Ok referenceAlgorithms.v
Algorithm.fromString "F2 D R2 U R2 D' R' U' R F2 R' U R"
--> Ok referenceAlgorithms.y
All the cases are represented here. Use the value constructors here or @all to specify a given case in your code, and pass these to any of the helper functions