Orient the Rubik's Cube
JavaScript (ES6), 95 bytes
n=>'y2+X+Zyx+ZX+z+ZY+z2+x+Y+zx+zy+Zy2+z2X+x2+zX+y+zY+Z+z2x++Zx+z2Y+Zx2+Zy'.split`+`[n%10955%24]
This works similarly to @Arnauld's answer (credits to him for the idea), but inputs as a base-10 integer (with 123456
instead of WYROGB
), which skips the base decoding.
Hash function
Input | mod 10955 | mod 24 | Output
-------+-----------+--------+-------
136452 | 4992 | 0 | "y2"
145362 | 2947 | 19 | ""
153642 | 272 | 8 | "Y"
164532 | 207 | 15 | "y"
235461 | 5406 | 6 | "z2"
246351 | 5341 | 13 | "x2"
254631 | 2666 | 2 | "Zyx"
263541 | 621 | 21 | "z2Y"
315264 | 8524 | 4 | "z"
326154 | 8459 | 11 | "Zy2"
352614 | 2054 | 14 | "zX"
361524 | 9 | 9 | "zx"
416253 | 10918 | 22 | "Zx2"
425163 | 8873 | 17 | "Z"
451623 | 2468 | 20 | "Zx"
462513 | 2403 | 3 | "ZX"
514236 | 10306 | 10 | "zy"
523146 | 8261 | 5 | "ZY"
531426 | 5586 | 18 | "z2x"
542316 | 5521 | 1 | "X"
613245 | 10720 | 16 | "zY"
624135 | 10655 | 23 | "Zy"
632415 | 7980 | 12 | "z2X"
641325 | 5935 | 7 | "x"
Test Cases
f=n=>'y2+X+Zyx+ZX+z+ZY+z2+x+Y+zx+zy+Zy2+z2X+x2+zX+y+zY+Z+z2x++Zx+z2Y+Zx2+Zy'.split`+`[n%10955%24]
console.log(f(263541))
console.log(f(145362))
console.log(f(531426))
console.log(f(136452))
console.log(f(361524))
console.log(f(514236))
JavaScript (ES6), 114 bytes
Saved 15 bytes thanks to @ngn
Picking the results from a lookup table turns out to be significantly shorter than my best attempt so far at golfing a solver.
Outputs X, Y and Z instead of x', y', z'.
s=>'X//Zy//Zyx/z2/zX/Zx2//z2Y/x/Zy2//x2/Zx/z2X/zY/z2x/ZY/z/y//ZX/zy/y2//zx/Z/Y/'.split`/`[parseInt(s+0,35)%405%31]
Test cases
let f =
s=>'X//Zy//Zyx/z2/zX/Zx2//z2Y/x/Zy2//x2/Zx/z2X/zY/z2x/ZY/z/y//ZX/zy/y2//zx/Z/Y/'.split`/`[parseInt(s+0,35)%405%31]
console.log(f('YBRGOW')); // z2Y
console.log(f('WOGRBY')); // nothing
console.log(f('GRWOYB')); // z2x
console.log(f('WRBOGY')); // y2
console.log(f('RBWGYO')); // zx
console.log(f('GWOYRB')); // zy
Solver
Here is the solver used to generate the moves stored in the lookup table.
s => {
const rot = [ '215304', '023415', '152043' ];
const S = [];
// recursive function looking for all possible solutions of at most 6 clockwise moves
const g = (s, m, r = 0) => {
if(s == 'WOGRBY') {
// this is a solution; replace 3 consecutive identical clockwise moves with a
// single counterclockwise move; rewrite 2 consecutive identical moves as 'x2';
// store the result in S[]
S.push(m.replace(/(.)\1\1/g, s => s[0].toUpperCase()).replace(/(.)\1/g, '$12'));
}
else if(!m[5]) {
// try the next rotation on the current cube
if(r < 2) {
g(s, m, r + 1);
}
// apply the current rotation and restart from there
g([...rot[r]].reduce((r, i) => r + s[i], ''), m + 'xyz'[r]);
}
}
// find all solutions
g(s, '');
// find the length of the shortest solution(s)
const min = Math.min(...S.map(s => s.length));
// return the 1st solution matching this length
return S.find(s => s.length == min);
}
Hash function
Below is a summary of the results provided by the hash function for all 24 valid inputs, along with the corresponding solutions.
input | base 35->10 | * 35 | mod 405 | mod 31 | output
----------+-------------+-------------+---------+--------+--------
"WOGRBY" | 1717434494 | 60110207290 | 370 | 29 | ""
"WBOGRY" | 1698256454 | 59438975890 | 175 | 20 | "y"
"WRBOGY" | 1721718494 | 60260147290 | 55 | 24 | "y2"
"WGRBOY" | 1705881974 | 59705869090 | 400 | 28 | "Y"
"OGWBYR" | 1285921692 | 45007259220 | 45 | 14 | "Zx"
"OYGWBR" | 1312271862 | 45929515170 | 120 | 27 | "Z"
"OBYGWR" | 1278510372 | 44747863020 | 270 | 22 | "ZX"
"OWBYGR" | 1309058862 | 45817060170 | 255 | 7 | "Zx2"
"GRWOYB" | 882269476 | 30879431660 | 110 | 17 | "z2x"
"GYRWOB" | 892568926 | 31239912410 | 80 | 18 | "ZY"
"GOYRWB" | 877856956 | 30724993460 | 155 | 0 | "X"
"GWOYRB" | 889441606 | 31130456210 | 395 | 23 | "zy"
"RBWGYO" | 1435990314 | 50259660990 | 150 | 26 | "zx"
"RYBWGO" | 1469623284 | 51436814940 | 135 | 11 | "Zy2"
"RGYBWO" | 1443572994 | 50525054790 | 285 | 6 | "zX"
"RWGYBO" | 1466838684 | 51339353940 | 360 | 19 | "z"
"BYOWRG" | 629831036 | 22044086260 | 250 | 2 | "Zy"
"BRYOWG" | 619745786 | 21691102510 | 325 | 15 | "z2X"
"BWRYOG" | 626960756 | 21943626460 | 295 | 16 | "zY"
"BOWRYG" | 615161906 | 21530666710 | 10 | 10 | "x"
"YOBRGW" | 1822264042 | 63779241470 | 230 | 13 | "x2"
"YGOBRW" | 1810797202 | 63377902070 | 35 | 4 | "Zyx"
"YRGOBW" | 1826976442 | 63944175470 | 5 | 5 | "z2"
"YBRGOW" | 1803428722 | 63120005270 | 350 | 9 | "z2Y"
Ruby, 84 83 bytes
->a{k=a.index(0);%W{#{} z x Z X zz xx}[k+=k/5*a[2]/3]+%W{#{} Y yy y}[a[c=1+k%2]-c]}
Try it online!
Llambda function taking an array of 6 numbers 0..5 representing the faces, with the following solved configuration
0
1234
5
Searches for the index of the array element containing 0
and selects a string for the move required to move it to the top: either by rotating in the x or z axis (or the empty string if it is already there, represented by #{}
in %W{}
notation.)
Then, inspect either array element 1 or 2 (whichever would not be altered by performing the move in the above step), select a string (always rotation in the y axis) for the move required to move the contents of the element to their solved location, and return the concatenated moves.
An issue arises when the index of the array containing 0
is 5, as there are two possible moves that will return it to the top: zz
and xx
. If array element 2 (the front of the cube) contains 2
the cube can be completely solved by zz
, and if it contains 4
it can be solved by xx
. The default is value to be returned is zz
but if the front face contains 3
or 4
the expression k/5*a[2]/3
adds 1 to the index of %W{#{} z x Z X zz xx}
that is returned, correcting it to xx
. (Note that if the front face contains 1
or 3
it doesn't matter whether xx
or zz
is used as in these cases an additional 90 deg rotation will be required about the y axis regardless of whether xx
or zz
is used.)