Can Rubik's Cubes fit in Computer Science or Math?
I say YES! Read on to find out why.
This past summer, I learned how to solve several versions of the Rubik's Cube. It is almost always advisable to start with the standard 3x3 cube. Most of the other versions (4x4, 5x5, Windmill, Mirror, etc.) are based on moves in the basic 3x3 instructions.
So I started with the 3x3. As I watched YouTube videos and wrote detailed instructions to prepare myself to teach this to my High School students, I couldn't help but think in terms of:
- Loops
- Functions
- Functions within Functions
- Conditionals, and
- APIs
Function / API:
In the above video and steps, you'll see a very frequently used set of moves, which this video calls
"Right Hand":
JavaScript shown in block style
- Turn the right side clockwise
- Turn the top layer clockwise
- Turn the right side counter-clockwise
- Turn the top layer counter-clockwise
The exact opposite, slightly less frequently used, set of moves, is called
"Left Hand":
- Turn the left side counter-clockwise
- Turn the top layer counter-clockwise
- Turn the left side clockwise
- Turn the top layer clockwise
In the rest of the video/instructions, "Right Hand" and "Left Hand" are referred to over and over without having to list the 4 steps that make them up every time.
From a Computer Science perspective, we have just added a Function to the API.
API:
Before this, a "cube-student" needs to learn the basic "commands", like:
R = Turn the right side clockwise
R' = Turn the right side counter-clockwise
L = Turn the left side clockwise
L' = Turn the left side counter-clockwise
U and U' = The same pattern, with the top layer
F and F' = The same pattern, with the front face
D and D' = The same pattern, with the bottom layer
B and B' = The same pattern, with the back face
Conditionals:
As you go through the instructions, you'll get to a point where you need to do "Right Hand" UNTIL a certain condition is met (putting a corner that's on the top layer directly down to the bottom layer).
Loops:
At a later part of the instructions, you'll need to do "Right Hand" THREE TIMES, turn the entire cube, then "Left Hand" THREE TIMES.
When you get to the very last step/phase, you'll do
"Right Hand" ONCE"Left Hand" ONCE"Right Hand" 5x"Left Hand" 5x
I used Code.org's App Lap to write a JavaScript version of the instructions & video mentioned earlier.
- I made some Functions.
- I made some For Loops to repeat a set of steps.
- I needed to include more Comments where I had to stick with human-readable instructions. These were primarily for parts that were more intuitive, as opposed to an algorithm.
- Math: I assumed that something like the following would be sufficient to evaluate whether one side of a piece did NOT match the desired color: ((BottomOfCornerPiece != Yellow))
Parts of the "block" version of the code are shown above.
Here is the complete JavaScript project, shown in Text version:
//Define Basic Moves//Right is often refered to as Rfunction Right() {TurnRightSideCLOCKWISE}//RightInv is often refered to as R'function RightInv() {TurnRightSideCOUNTERCLOCKWISE}//Left is often refered to as Lfunction Left() {TurnLeftSideCLOCKWISE}//LeftInv is often refered to as L'function LeftInv() {TurnLeftSideCOUNTERCLOCKWISE}//Up is often refered to as Ufunction Up() {TurnTopLayerCLOCKWISE}//UpInv is often refered to as U'function UpInv() {TurnTopLayerCOUNTERCLOCKWISE}//Front is often refered to as Ffunction Front() {TurnFrontFaceCLOCKWISE}// FrontInv is often refered to as F'function FrontInv() {TurnFrontFaceCOUNTERCLOCKWISE}//Define "RightHand" and "LeftHand"function RightHand() {Right();Up();RightInv();UpInv();}function LeftHand() {LeftInv();UpInv();Left();Up();}function Bottom2Layers() {TurnBottomTwoLayersEitherDirection}function TurnCubeLeft() {TurnEntireCubeToTheLeft}function TurnCubeRight() {TurnEntireCubeToTheRight}function OrientCube(color) {OrientCubeSoThisColorIsOnTop}//WHITE CROSS//Make "Daisy"(yellow center w/ white edges); Then continue://This "for" loop repeats its contents 4xfor (var i = 0; i < 4; i++) {if (FrontFaceTopEdge_matches_FrontFaceCenter) {Right();Right();RotateCubeLeft} else {Bottom2Layers();}//Goal is to have all white edges' other color to match centers.}//WHITE CORNERS in placeOrientCube(yellow);while (LessThanFourWhiteCornersInPlace) {RotateTop: CornerWithWhite=AboveFinalPlacewhile (WhiteSquareNotInPlace) {RightHand();}//If a white square is on the bottom, but in the wrong place,//Do these steps to move it to the top, then//Repeat these steps to put it where it goes.}//COMPLETE MIDDLE LAYER (EDGES)while ((TopEdgePiecesWithYellow < 4)) {// Turn U so Top Edge piece WITHOUT yellow faces youwhile ((TopEdgePiece != FrontFaceCenter)) {Bottom2Layers();}//Top Edge piece should now match front face's centerif (TopEdgePieceTopColor == RightFaceCenter) {Up();RightHand();TurnCubeLeft();LeftHand();} else {//Top Edge Piece's top color should match LEFT face centerUpInv();LeftHand();TurnCubeRight();RightHand();}}//Orient Cube so Yellow is on bottomOrientCube(white);//YELLOW CROSSwhile (NoYellowCrossYet) {if (HorizontalYellowLine) {//Position yellows to the left and right//(NOT up and down)Front();RightHand();FrontInv();} else if (NineOClockPattern) {//Position yellows in top and leftFront();RightHand();FrontInv();} else {//Only yellow centerFront();RightHand();FrontInv();}}//POSITION Yellow Corners//These "for" loops repeats their contents 3xOrientCube(yellow);//Up until 2 adjacent corners are in proper position//Put these 2 correct corners to the left//These steps will swap the right two cornersfor (var i = 0; i < 3; i++) {RightHand();}RotateCubeLeft();for (var i = 0; i < 3; i++) {LeftHand();}//ORIENT Yellow CornersOrientCube(white);while ((NumberOfYellowCornersFacingDown < 4)) {while ((BottomOfCornerPiece != Yellow)) {//This should position the bottom-right piece so that//yellow is NOT on the bottom, but on one of the sidesBottom();}while ((BottomOfCornerPiece != Yellow)) {RightHand();}}//LAST STEP - position top edges//This will rotate top edge pieceswhile (CubeNotSolved) {RightHand();LeftHand();//These "for" loops repeat their contents 5xfor (var i = 0; i < 5; i++) {RightHand();}for (var i = 0; i < 5; i++) {LeftHand();}}