Starting from:
$30

$24

Lab #3: Rubik's Cube Solution

Problem Description

The Rubik's cube is a three-dimensional combination puzzle that is considered the world's best-selling toy.



The 3 × 3 rubik's cube above can be fattened so that all six faces are shown.



Your task is to write a program that reads the cube faces as input, followed by the turns. It then manipulates the cube by turning the faces clockwise (F/R/U/L/B/D), anti-clockwise (F'/R'/U'/L'/B'/D') or halfway around (F2/R2/U2/L2/B2/D2). The fnal cube is then output. As an example, the input

1
2
3
4
5 6 7
8
9
16
17
18
10

11
12
13 14 15



19

20
21
22 23 24
25
26
27
28

29
30
31 32 33
34
35
36
37

38
39
40 41 42
43
44
45
46

47
48
49 50 51
52
53
54
F









R'









U2











will give the output


......541518......

......510504......

......480201......

303336455352101137

131438262306293235

161739272412070809

......343119......

......404120......

......434421......

......464728......

......495042......

......032225......

Take note of the following assumptions:

Input always begins with a set of 54 values specifying the face values of the 3 × 3 cube in order (top, left, front, right, down, back),

The numbers of the cube faces are positive (> 0) integers less than 100 Input turns are always valid


https://codecrunch.comp.nus.edu.sg/task_view.php?tid=5079
2/11
26/11/2021, 03:17    CodeCrunch

This task is divided into several levels. Read through all the levels to see how the different levels are related. You need to complete all levels.


Level 1

Since a cube comprises six faces, let's begin by developing the Face class. The cube face's nine values can be represented using a 3 × 3 array of integers. Each face can also be rotated right or left.

Develop the following methods for the Face class:

Face(int[][] grid): the constructor that takes in the 3 × 3 array of integers


Face right(): performs a quarter rotation to the right and returns a new Face

Face left(): performs a quarter rotation to the left and returns a new Face

Face half(): performs a half rotation and returns a new Face

int[][] toIntArray(): returns the 3 × 3 integer grid of the Face object

String toString(): returns a String representing the Face object


In addition, a Face object should be cloneable. That is, there is a clone() method that creates an immutable copy. Note that Face newFace.grid = this.grid is not enough, as both will reference the same grid. Write a Cloneable interface that enforces the defnition of the clone method. This will be useful in a later level.

It is also worth noting that the Object class defnes a similar clone() method with a protected access modifer. While we can override this with another clone() method in the Face class, the accessibility cannot be less restrictive than protected. Only by implementing the Cloneable interface, would the overriding clone() method be public accessible.

In addition, use String.format("%02d", ...) to output the cube face's values.


$ javac *.java

    • jshell -q your_java_files_in_bottom-up_dependency_order < test1.jsh jshell> Face f = new Face(new int[][]{{1,2,3},{4,5,6},{7,8,9}}) jshell> Face g = f.clone()
jshell> Cloneable c = g jshell> c.clone()
$.. ==> 010203 040506 070809

jshell> f.right()

$.. ==>

070401

080502

090603

jshell> f.left()

$.. ==>

030609

020508

010407

jshell> f.half()

$.. ==>

090807

060504

030201

jshell> g

    • ==>

010203

040506

070809

jshell> f.toIntArray()

$.. ==> int[3][] { int[3] { 1, 2, 3 }, int[3] { 4, 5, 6 }, int[3] { 7, 8, 9 } } jshell> /exit

Level 2

With the Face class ready, we can proceed to develop Rubik. We defne Rubik as a rubik's cube with one face that can be turned using the following methods:

right(): turns the face clockwise


left(): turns the face anti-clockwise


https://codecrunch.comp.nus.edu.sg/task_view.php?tid=5079
3/11
26/11/2021, 03:17    CodeCrunch

half(): turns the face half a revolution


RubikFront is a Rubik where the turns are applied to the front face. Defne the RubikFront constructor that takes in a three-dimensional (6 × 3 × 3) integer array of the six face's values.

Since all turn methods return an immutable object, it should be cloneable too.


$ javac *.java

    • jshell -q your_java_files_in_bottom-up_dependency_order < test2.jsh jshell> int[][][] grid = new int[6][3][3]
jshell> int d = 1

jshell> for (int k = 0; k < 6; k++)

...>for (int i = 0; i < 3; i++)

...> for (int j = 0; j < 3; j++) grid[k][i][j] = d++; jshell> Rubik r = new Rubik(grid)
|  Error:

| Rubik is abstract; cannot be instantiated | Rubik r = new Rubik(grid);
|
^-------------
^

jshell> Rubik r = new RubikFront(grid)

jshell> Rubik s = r.clone();

jshell> Cloneable c = s


jshell> c.clone()


$..
==>


......
010203......


......
040506......


......
070809......


101112192021282930


131415222324313233


161718252627343536


......
373839......


......
404142......


......
434445......


......
464748......


......
495051......


......
525354......


jshell> r.left()


$..
==>


......
010203......


......
040506......


......
283134......


101109212427392930


131408202326383233


161707192225373536


......
121518......


......
404142......


......
434445......


......
464748......


......
495051......


......
525354......


jshell> r.right()


$..
==>


......
010203......


......
040506......


......
181512......


101137252219072930


131438262320083233


161739272421093536


......
343128......


......
404142......


......
434445......


......
464748......


......
495051......


......
525354......


jshell> r.half()


$..
==>


......
010203......


......
040506......


......
393837......


101134272625182930


131431242322153233


https://codecrunch.comp.nus.edu.sg/task_view.php?tid=5079
4/11
26/11/2021, 03:17
CodeCrunch



161728212019123536









......090807......




......404142......




......434445......




......464748......




......495051......




......525354......




jshell> s




s ==>




......010203......




......040506......




......070809......




101112192021282930




131415222324313233




161718252627343536




......373839......




......404142......




......434445......




......464748......




......495051......




......525354......




jshell> /exit









Level 3

A Rubik can also be oriented to any one of the six sides using the following methods:



rightView(): orientates the cube so that the right-side faces front



leftView(): orientates the cube so that the left-side faces front



upView(): orientates the cube so that the top-side faces front



downView(): orientates the cube so that the bottom-side faces front



backView(): orientates the cube so that the back-side faces front. Although you can view the back of the cube



by either orientating right/left or up/down, for ease of correctness checking, we stipulate that you can only



orientate right/left



frontView(): no orientation needed






$ javac *.java



$ jshell -q your_java_files_in_bottom-up_dependency_order < test3.jsh



jshell> int[][][] grid = new int[6][3][3]



jshell> int d = 1



jshell> for (int k = 0; k < 6; k++)




...>
for (int i = 0; i < 3; i++)




...>
for (int j = 0; j < 3; j++) grid[k][i][j] = d++;



jshell> Rubik r = new RubikFront(grid)



jshell> r.upView()



$..
==>




......
464748
......



......
495051
......



......
525354
......



161310010203303336



171411040506293235



181512070809283134



......
192021
......



......
222324
......



......
252627
......



......
373839
......



......
404142
......



......
434445
......



jshell> r.rightView()



$..
==>




......
070401
......



......
080502
......



......
090603
......



192021282930545352



222324313233515049



252627343536484746



......
394245
......



......
384144
......



......
374043
......



......
181716
......



......
151413
......


https://codecrunch.comp.nus.edu.sg/task_view.php?tid=5079

5/11

26/11/2021, 03:17
CodeCrunch


121110


............


jshell> r.downView()


$..
==>


......
192021......


......
222324......


......
252627......


121518373839343128


111417404142353229


101316434445363330


......
464748......


......
495051......


......
525354......


......
010203......


......
040506......


......
070809......


jshell> r.leftView()


$..
==>


......
030609......


......
020508......


......
010407......


545352101112192021


515049131415222324


484746161718252627


......
434037......


......
444138......


......
454239......


......
363534......


......
333231......


......
302928......


jshell> r.backView()


$..
==>


......
090807......


......
060504......


......
030201......


282930545352101112


313233515049131415


343536484746161718


......
454443......


......
424140......


......
393837......


......
272625......


......
242322......


......
212019......


jshell> r.frontView()


$..
==>


......
010203......


......
040506......


......
070809......


101112192021282930


131415222324313233


161718252627343536


......
373839......


......
404142......


......
434445......


......
464748......


......
495051......


......
525354......


jshell> /exit







Level 4

We are now really ready to turn the other faces. Just like RubikFront, we need to implement fve other classes:

RubikLeft to turn the left face


RubikRight to turn the right face

RubikBack to turn the back face

RubikUp to turn the top face

RubikDown to turn the bottom face


https://codecrunch.comp.nus.edu.sg/task_view.php?tid=5079
6/11
26/11/2021, 03:17    CodeCrunch

You might think that you need to implement right, left and half turns separately for each of the above classes. However, there is no need to. With only front-face turns implemented in RubikFront, all you have to do is to orientate the turning side so that it is facing the front, make the front-face turn, and then orientate it back.


If the design has been done correctly, we can simply extend our implementation with left/right/half turns for each of the remaining classes.


$ javac *.java


$ jshell -q your_java_files_in_bottom-up_dependency_order < test4.jsh


jshell> int[][][] grid = new int[6][3][3]


jshell> int d = 1


jshell> for (int k = 0; k < 6; k++)



...>
for (int i = 0; i < 3; i++)



...>
for (int j = 0; j < 3; j++) grid[k][i][j] = d++;


jshell> Rubik rubik = new RubikFront(grid);


jshell> ((Rubik) new RubikUp(rubik)).left()


$..
==>



......
030609
......


......
020508
......


......
010407
......


545352101112192021


131415222324313233


161718252627343536


......
373839
......


......
404142
......


......
434445
......


......
464748
......


......
495051
......


......
302928
......


jshell> ((Rubik) new RubikUp(rubik)).right()


$..
==>



......
070401
......


......
080502
......


......
090603
......


192021282930545352


131415222324313233


161718252627343536


......
373839
......


......
404142
......


......
434445
......


......
464748
......


......
495051
......


......
121110
......


jshell> ((Rubik) new RubikUp(rubik)).half()


$..
==>



......
090807
......


......
060504
......


......
030201
......


282930545352101112


131415222324313233


161718252627343536


......
373839
......


......
404142
......


......
434445
......


......
464748
......


......
495051
......


......
212019
......


jshell> ((Rubik) new RubikRight(rubik)).left()


$..
==>



......
010248
......


......
040551
......


......
070854
......


101112192003303336


131415222306293235


161718252609283134


......
373821
......


......
404124
......


......
434427
......


......
464739
......


......
495042
......


......
525345
......



7/11
https://codecrunch.comp.nus.edu.sg/task_view.php?tid=5079


26/11/2021, 03:17
CodeCrunch



jshell> ((Rubik) new RubikRight(rubik)).right()









$..
==>




......
010221......




......
040524......




......
070827......




101112192039343128




131415222342353229




161718252645363330




......
373848......




......
404151......




......
434454......




......
464703......




......
495006......




......
525309......




jshell> ((Rubik) new RubikRight(rubik)).half()




$..
==>




......
010239......




......
040542......




......
070845......




101112192048363534




131415222351333231




161718252654302928




......
373803......




......
404106......




......
434409......




......
464721......




......
495024......




......
525327......




jshell> ((Rubik) new RubikDown(rubik)).left()




$..
==>




......
010203......




......
040506......




......
070809......




101112192021282930




131415222324313233




252627343536484746




......
394245......




......
384144......




......
374043......




......
181716......




......
495051......




......
525354......




jshell> ((Rubik) new RubikDown(rubik)).right()




$..
==>




......
010203......




......
040506......




......
070809......




101112192021282930




131415222324313233




484746161718252627




......
434037......




......
444138......




......
454239......




......
363534......




......
495051......




......
525354......




jshell> ((Rubik) new RubikDown(rubik)).half()




$..
==>




......
010203......




......
040506......




......
070809......




101112192021282930




131415222324313233




343536484746161718




......
454443......




......
424140......




......
393837......




......
272625......




......
495051......






8/11

https://codecrunch.comp.nus.edu.sg/task_view.php?tid=5079



26/11/2021, 03:17

CodeCrunch



525354





............





jshell> ((Rubik) new RubikLeft(rubik)).left()





$..
==>





......
190203......





......
220506......





......
250809......





121518372021282930





111417402324313233





101316432627343536





......
463839......





......
494142......





......
524445......





......
014748......





......
045051......





......
075354......





jshell> ((Rubik) new RubikLeft(rubik)).right()





$..
==>





......
460203......





......
490506......





......
520809......





161310012021282930





171411042324313233





181512072627343536





......
193839......





......
224142......





......
254445......





......
374748......





......
405051......





......
435354......





jshell> ((Rubik) new RubikLeft(rubik)).half()





$..
==>





......
370203......





......
400506......





......
430809......





181716462021282930





151413492324313233





121110522627343536





......
013839......





......
044142......





......
074445......





......
194748......





......
225051......





......
255354......





jshell> ((Rubik) new RubikBack(rubik)).left()





$..
==>





......
161310......





......
040506......





......
070809......





431112192021282901





441415222324313202





451718252627343503





......
373839......





......
404142......





......
363330......





......
485154......





......
475053......





......
464952......





jshell> ((Rubik) new RubikBack(rubik)).right()





$..
==>





......
303336......





......
040506......





......
070809......





031112192021282945





021415222324313244





011718252627343543





......
373839......





......
404142......





......
101316......





......
524946......








9/11

https://codecrunch.comp.nus.edu.sg/task_view.php?tid=5079




26/11/2021, 03:17
CodeCrunch


535047


............


......
545148......


jshell> ((Rubik) new RubikBack(rubik)).half()


$..
==>


......
454443......


......
040506......


......
070809......


361112192021282916


331415222324313213


301718252627343510


......
373839......


......
404142......


......
030201......


......
545352......


......
515049......


......
484746......


jshell> /exit







Level 5

Finally, read the Rubik's cube as input, followed by the turns and output the fnal Rubik's cube after all the turns have been made.

A skeleton Main class has been provided for you that parses the input and creates the frst RubikFront object. You will only need to modify the oneMove method to construct the appropriate Rubik object based on the frst character, and then invoke the correct turn.


import java.util.Scanner;

class Main {

static final int NFACES = 6;

static final int NROWS = 3;

static final int NCOLS = 3;

static Rubik oneMove(Rubik rubik, String move) {

System.out.print("Face " + move.charAt(0));

if (move.length() == 1) {

System.out.println(" right turn");

} else {

if (move.charAt(1) == '\'') {

System.out.println(" left turn");

} else {

System.out.println(" half turn");

}

}

return rubik;

}

public static void main(String[] args) {

int[][][] grid = new int[NFACES][NROWS][NCOLS];

Scanner sc = new Scanner(System.in);

for (int k = 0; k < NFACES; k++) {

for (int i = 0; i < NROWS; i++) {

for (int j = 0; j < NCOLS; j++) {

grid[k][i][j] = sc.nextInt();

}

}

}

Rubik rubik = new RubikFront(grid);

while (sc.hasNext()) {

rubik = oneMove(rubik, sc.next());

}

System.out.println(rubik);

}

}

The following is a sample run of the program. User input is underlined.


https://codecrunch.comp.nus.edu.sg/task_view.php?tid=5079    10/11
26/11/2021, 03:17











CodeCrunch




































1

2
3
4 5
6

7
8 9

16 17
18






10 11
12
13

14 15









19 20
21
22

23 24 25 26
27






28 29
30
31

32 33 34 35
36






37 38
39
40

41 42 43 44
45






46 47
48
49

50 51 52 53
54






F


































R'
















U2
















......


541518
......









......


510504
......









......


480201
......







303336455352101137






131438262306293235






161739272412070809








......


343119
......









......


404120
......









......


434421
......









......


464728
......









......


495042
......









......


032225
......























1

2
3
4 5
6

7
8 9

16 17
18






10 11
12
13

14 15









19 20
21
22

23 24 25 26
27






28 29
30
31

32 33 34 35
36






37 38
39
40

41 42 43 44
45






46 47
48
49

50 51 52 53
54






FRULBD











F' R' U' L'
B' D'







F2 R2
U2
L2
B2 D2








......


281118
......









......


220508
......









......


270648
......







211539342936452037






401451332344473253






014207192603543143








......


123830
......









......


354124
......









......


104916
......









......


521346
......









......


175002
......









......


090425
......


























Check the format correctness of the output by typing the following Unix command

$ java Main < test5.in




© Copyright 2009-2021 National University of Singapore. All    MySoC | Computing Facilities | Search | Campus Map

Rights Reserved.    School of Computing, National University of Singapore

Terms of Use | Privacy | Non-discrimination



















https://codecrunch.comp.nus.edu.sg/task_view.php?tid=5079    11/11

More products