Під час недбалого скручування кубика Рубіка навколо мене син зауважив, що він продовжує повертатися до вирішеного стану. Я майже впевнений, що спочатку він думав, що це якась магія вуду, але я пояснив, що якщо ви будете продовжувати повторювати ту саму послідовність рухів, вона завжди повернеться до початкового стану. Врешті-решт
Звичайно, будучи дитиною, йому довелося спробувати це для себе і вибрав «випадкову» послідовність, яку він вважав би хитрою. Він втратив трек після десяти повторів або близько того, і запитав мене, скільки разів йому доведеться повторити це. Не знаючи послідовності, яку він використовував, я сказав йому, що не знаю, але щоб ми могли написати програму, щоб це з'ясувати.
Це місце, куди ви заходите. Звичайно, я міг би просто щось збити, але він хотів би набрати це в собі. Він ще не дуже швидкий машиніст, тому мені потрібна найкоротша програма .
Об'єктивна
Враховуючи послідовність витків, виведіть найменшу кількість разів, щоб це було виконано, щоб повернути куб у початковий стан. Це код гольфу, тому виграє найменше байт. Ви можете написати програму або функцію, і всі інші звичайні параметри за замовчуванням застосовуються.
Вхідні дані
Введення - це послідовність кроків, прийнятих у вигляді рядка, списку чи іншого формату, відповідного вашій мові. Не соромтеся використовувати роздільник (чи ні) між ходами, якщо в рядковій формі.
Існує шість "основних" кроків, які необхідно враховувати разом із їх перевертаннями:
R - Turn the right face clockwise
L - Turn the left face clockwise
U - Turn the up (top) face clockwise
D - Turn the down (bottom) face clockwise
F - Turn the front face clockwise
B - Turn the back face clockwise
Звороти зображуються додаванням просте позначення '
після букви. Це вказує на те, що ви повертаєте це обличчя проти годинникової стрілки, тому F'
повертаєте переднє обличчя проти годинникової стрілки і F F'
повертаєте його в початковий стан відразу.
Для зацікавлених у цьому виклику використовується обмежений набір нотаток про Singmaster . У Ruwix є приємна анімація, якщо ви хочете побачити її в дії.
Вихідні дані
Вихід - це мінімальна кількість разів, яка повинна бути виконана послідовністю введення.
Приклади
Input Output
FF' -> 1
R -> 4
RUR'U' -> 6
LLUUFFUURRUU -> 12
LUFFRDRBF -> 56
LF -> 105
UFFR'DBBRL' -> 120
FRBL -> 315
Ось (досить наївний) вирішувач для порівняння ваших відповідей, написаних на Java. Він також приймає 2
подвійні ходи (тому четвертий випадок еквівалентний L2U2F2U2R2U2
).
import java.util.ArrayList;
import java.util.List;
public class CycleCounter{
public static void main(String[] args){
int[] cube = new int[54];
for(int i=0;i<54;i++)
cube[i] = i;
String test = args.length > 0 ? args[0] : "RUR'U'";
List<Rotation> steps = parse(test);
System.out.println(steps.toString());
int count = 0;
do{
for(Rotation step : steps)
cube = step.getRotated(cube);
count++;
}while(!isSorted(cube));
System.out.println("Cycle length for " + test + " is " + count);
}
static List<Rotation> parse(String in){
List<Rotation> steps = new ArrayList<Rotation>();
for(char c : in.toUpperCase().toCharArray())
switch(c){
case 'R':steps.add(Rotation.R);break;
case 'L':steps.add(Rotation.L);break;
case 'U':steps.add(Rotation.U);break;
case 'D':steps.add(Rotation.D);break;
case 'F':steps.add(Rotation.F);break;
case 'B':steps.add(Rotation.B);break;
case '\'':
steps.add(steps.get(steps.size()-1));
case '2':
steps.add(steps.get(steps.size()-1));
break;
}
return steps;
}
static boolean isSorted(int[] in){for(int i=0;i<in.length-1;i++)if(in[i]>in[i+1])return false;return true;}
enum Rotation{
R(new int[]{-1,-1,42,-1,-1,39,-1,-1,36, -1,-1,2,-1,-1,5,-1,-1,8, 20,23,26,19,-1,25,18,21,24, -1,-1,11,-1,-1,14,-1,-1,17, 35,-1,-1,32,-1,-1,29,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1}),
L(new int[]{9,-1,-1,12,-1,-1,15,-1,-1, 27,-1,-1,30,-1,-1,33,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1, 44,-1,-1,41,-1,-1,38,-1,-1, -1,-1,6,-1,-1,3,-1,-1,0, 47,50,53,46,-1,52,45,48,51}),
U(new int[]{2,5,8,1,-1,7,0,3,6, 45,46,47,-1,-1,-1,-1,-1,-1, 9,10,11,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1, 18,19,20,-1,-1,-1,-1,-1,-1, 36,37,38,-1,-1,-1,-1,-1,-1}),
D(new int[]{-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,24,25,26, -1,-1,-1,-1,-1,-1,42,43,44, 29,32,35,28,-1,34,27,30,33, -1,-1,-1,-1,-1,-1,51,52,53, -1,-1,-1,-1,-1,-1,15,16,17}),
F(new int[]{-1,-1,-1,-1,-1,-1,18,21,24, 11,14,17,10,-1,16,9,12,15, 29,-1,-1,28,-1,-1,27,-1,-1, 47,50,53,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,8,-1,-1,7,-1,-1,6}),
B(new int[]{51,48,45,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,0,-1,-1,1,-1,-1,2, -1,-1,-1,-1,-1,-1,26,23,20, 38,41,44,37,-1,43,36,39,42, 33,-1,-1,34,-1,-1,35,-1,-1});
private final int[] moves;
Rotation(int[] moves){
this.moves = moves;
}
public int[] getRotated(int[] cube){
int[] newCube = new int[54];
for(int i=0;i<54;i++)
if(moves[i]<0)
newCube[i] = cube[i];
else
newCube[moves[i]] = cube[i];
return newCube;
}
}
}