Під час недбалого скручування кубика Рубіка навколо мене син зауважив, що він продовжує повертатися до вирішеного стану. Я майже впевнений, що спочатку він думав, що це якась магія вуду, але я пояснив, що якщо ви будете продовжувати повторювати ту саму послідовність рухів, вона завжди повернеться до початкового стану. Врешті-решт
Звичайно, будучи дитиною, йому довелося спробувати це для себе і вибрав «випадкову» послідовність, яку він вважав би хитрою. Він втратив трек після десяти повторів або близько того, і запитав мене, скільки разів йому доведеться повторити це. Не знаючи послідовності, яку він використовував, я сказав йому, що не знаю, але щоб ми могли написати програму, щоб це з'ясувати.
Це місце, куди ви заходите. Звичайно, я міг би просто щось збити, але він хотів би набрати це в собі. Він ще не дуже швидкий машиніст, тому мені потрібна найкоротша програма .
Об'єктивна
Враховуючи послідовність витків, виведіть найменшу кількість разів, щоб це було виконано, щоб повернути куб у початковий стан. Це код гольфу, тому виграє найменше байт. Ви можете написати програму або функцію, і всі інші звичайні параметри за замовчуванням застосовуються.
Вхідні дані
Введення - це послідовність кроків, прийнятих у вигляді рядка, списку чи іншого формату, відповідного вашій мові. Не соромтеся використовувати роздільник (чи ні) між ходами, якщо в рядковій формі.
Існує шість "основних" кроків, які необхідно враховувати разом із їх перевертаннями:
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;
}
}
}