Коротка рубікова сутичка


21

Ваше завдання - створити випадкову послідовність рухів, яку можна використати для того, щоб скремтувати кубик Рубіка. Така сутичка складається рівно з 25 ходів. Кожен хід складається з літер, UDRLFBнеобов'язково супроводжуваних одним із суфіксів '2.

Ця нотація називається позначенням Singmaster. UDRLFBявляє собою одну з 6 граней, а необов'язковий суфікс '2являє собою кут повороту. Ця інформація жодним чином не потрібна для вирішення поставленого завдання.

Щоб переконатись у тому, що сутички "хорошої якості", повинні застосовуватися наступні два правила:

  • Два послідовні ходи не повинні мати однакову букву. Це забороняє послідовні кроки UU, DD, RR, LL, FFі BBвсі їхні комбінації з використанням додаткових суфіксів , як U2Uабо U'U'.

    Ці переміщення пари заборонені, оскільки їх можна легко скоротити до 1 або 0 ходів. U2Uмає той же ефект U', що і R'Rтой самий ефект, що і .

  • Три послідовні ходи не повинні бути однієї групи літер. Літерні групи UD, RLі FB. Це правило додатково забороняє послідовні кроки UDU, DUD, RLR, LRL, FBF, BFBі всі їхні комбінації з використанням додаткових суфіксів , як U2DU, RL'Rабо B2FB'.

    Групи сортують грані за їх віссю переміщення. Uі Dзнаходяться в одній групі, тому що обидва обертаються навколо однієї осі. Тому Uрух не впливає на частини Dобличчя, а Dрух не впливає на частини Uобличчя. Тому два ходи можуть бути обмінені, UDUмає той же ефект UUD, що і це можна звести до U2D.

Виклик

Напишіть сценарій або функцію, яка генерує одну випадкову кодировку. Введення немає. Сценарій / функція повинна надрукувати 25 ходів без відокремлення або розділення одним пробілом або повернення відповідного рядка.

Ваша програма повинна вміти створювати кожну кодировку, яка відповідає правилам, наведеним вище. Звичайно, припускаючи, що генератор випадкових чисел справжній випадковий, а не псевдовипадковий.

Це код-гольф. Виграє найкоротший код (рахується в байтах ).

Приклади виходів:

Викликаючи сценарій / функцію 3 рази, слід надрукувати / повернути щось на кшталт:

R'B2R2F2R2FB'R2DR2ULFB2RB'U2B'FL'BR'U'RB'
U'DBR'B2U'B'U'RUF'B'RDR2U'B'LR'B'F2D2UF2L'
BR2F'B'R'D'R'U2B'F2D2R'F2D'F'D2R2B'L2R'UB'R2L'D

Якщо розділити ходи пробілом кожен:

R2 L' F2 U2 D' R2 L2 F L' D2 U R B D' U2 L B2 L U B2 D U2 R' D2 U'
B R D2 F U2 B' R2 F2 B' U' L' R2 B U2 R' D B' F' U2 R' B' L R D2 R2
B2 R2 U D' B R D' R L2 D2 L2 R B2 F U' F2 B2 U' F U' D F R2 U2 B'

Зауважте, що всі ці результати складаються з 25 ходів, але мають різну довжину через необов'язкові суфікси. Не дозволяється друкувати пробіл, коли 2або 'використовується як суфікс. Ви повинні надрукувати L2UR2F'R'U2або L2 U R2 F' R' U2. L2U R2F'R'U2не дозволено.


Ви мали на увазі, що UR 2це не дозволено? U R2 треба дозволити, я думаю, оскільки пробіли між рухами мають сенс.
mbomb007

@ mbomb007 Я маю на увазі такі речі, як L2U R2F'R'U2. Uне має необов'язкового суфікса, і тому він не повинен мати пробілу. Пробіл не повинен бути заміною необов’язкового суфікса.
Якубе

Що робити, якщо між ходом є пробіли? Ми могли б вивести U F2 L D2 R'..., наприклад? У цьому випадку немає зайвого місця, яке, на мою думку, повинно бути нормальним згідно вашого правила.
mbomb007

@ mbomb007 Так, я вкладу це в опис.
Якубе

Чи не два перед листом? oO
Олівер Ні

Відповіді:


6

CJam, 47 45 байт

Це рішення використовує підхід, який відрізняється від будь-якого іншого, розміщеного до цих пір. Скористайтеся операціями стислого списку CJam, щоб генерувати доступний список переміщення та вибирати один навмання кожен ітератон. Модифікатори просто генеруються незалежно.

Спробуйте в Інтернеті.

{BA^2/6,_B-?A:B-mr0=:A"UDRLFB"=3mr[L2'']=}25*

Пояснення

{               "Loop...";
  BA^2/           "If the two previous moves were not from the same group, ...";
  6,              "... then produce the available move list [0 1 2 3 4 5], ...";
  _B-             "... else produce the available move list [0 1 2 3 4 5] with
                   the second previous move removed";
  ?
  A:B             "Save the previous move as the second previous move";
  -               "Remove the previous move from the available move list";
  mr0=            "Randomly select an available move";
  :A              "Save this move as the previous move";
  "UDRLFB"=       "Map this move to its character (implicitly printed)";
  3mr[L2'']=      "Randomly select a modifier (implicitly printed)";
}25*            "... 25 times";

9

С, 129

f(){int i,n,m,r,s,t;for(i=26;i--;i<25&&printf("%c%c","URFDLB"[s%6],"'2"[r%3])){for(n=m,t=1;t;t=m*n==9)m=(r=rand()%15)/3+1;s+=m;}}

Внутрішня петля генерує значення mв діапазоні, 1..5який при додаванні sта прийнятті по модулю 6 забезпечує відсутність двох послідовних рухів на одній стороні куба. Старе значення mзберігається в, nі тест m*n==9гарантує, що значення m= 3 ніколи не формується двічі поспіль (тому протилежні грані не можна вибирати двічі поспіль; відзначте порядок граней у рядку.)

Найменш значна частина rвикористовується для визначення , який суфікс ( ', 2або нуль) , щоб використовувати, скориставшись нульовим символом в кінці "'2".

Зовнішня петля проходить 26 разів. Перший раз Uйого не можна вибирати, тому printfпридушується для першої ітерації.

Невикористаний код у тестовій програмі

Код, який не використовується для гольфу, ставить простір між кожним ходом для ясності (код гольфу не робить, щоб зберегти один байт.) Додатково код гольфу зберігає крапку з комою, переміщуючи printfвсередині forдужки.

f(){
  int i,n,m,r,s,t;
  for(i=26;i--;){
    for(n=m,t=1;t;t=m*n==9)m=(r=rand()%15)/3+1;
    s+=m;
    i<25&&printf("%c%c ","URFDLB"[s%6],"'2"[r%3]);
  }
}

main(){
  int j;
  srand(time(0));
  for(j=0;j<5;j++)f(), puts("");
}

Типовий вихід

U' B D2 B' R' L F' D2 B D2 B2 R' B2 U D2 F' R U R' L B' L R2 B2 F'
U B U B F L2 D2 B' U' L B L R' D B U' D R D' B' F2 D' B D R
L D F2 B2 R' U F B' D2 L U R' L' U2 F' R F D U2 B L' B' U L2 F'
R2 B' F2 R2 L2 F' U2 L U' B' F R' D' F2 D F' L2 U2 R' D' B2 D F R2 L'
U2 F2 B2 D' F D F R L2 U' B D2 L' R D R F2 R' F2 U2 D R' D2 L F2



4

Pyth, 65 66

Я ніколи насправді не займався гольфуванням в Pyth, можливо, написав програму чи дві. Це в основному рішення @ steveverrill , перекладене на Pyth. Пропозиції щодо вдосконалення вітаються.

Оновлення: додано 1 байт, щоб також почалися сутички U. Можливо, рішення C покладається на невизначену поведінку, щоб змусити його працювати ...

=YO6V25JZK1WK=GO15=Z/+3G3=Kq9*ZJ)~YZpd+@"URFDLB"%Y6?@"'2"%G3>2%G3k

Я вважаю, що це потрібно робити з меншими завданнями, але це вимагає від мене багато чого змінити алгоритм. (Що ж, може спробувати.)

Ось пояснення на основі коду С:

=YO6           s = random.choice(range(6))
V25            for i in range(25):
  JZ               n = m
  K1               t = 1
  WK               while t:
    =GO15              r = random.choice(range(15))
    =Z/+3G3            m = (r + 3) / 3
    =Kq9*ZJ            t = 9 == m * n
  )
  ~YZ              s += m
  pd               print(..., end = " ")
  +                ... + ...
  @"URFDLB"%Y6     "URFDLB"[s % 6]
  ?@"'2"%G3>2%G3k  "'2"[G % 3] if 2 > G % 3 else ""

Переключити змінні Yта Z. Zпопередньо ініціалізується з 0, тому ви зберігаєте перші 3 символи.
Якубе

@Jakube Але тоді мені потрібно встановити n = m(3-й рядок пояснення), який повинен означати n = 0перший раз, що, у свою чергу, вимагатиме Y0
PurkkaKoodari

Yпопередньо ініціалізується з порожнім списком []. І я не думаю, що значення має nзначення в першій ітерації.
Якубе

До речі, ваш код не створює сутичок, які починаються з U.
Якубе

@Jakube спасибі, виправлено.
PurkkaKoodari

4

JavaScript (ES6) 175 178 204

Відредагуйте 3 байти менше, 1 змінивши код і 2 змінивши спосіб підрахунку байтів (не рахуючи F=)

Код, щоб уникнути повторів, взято з @stevemiller. Його спосіб управління буквеними групами ще кращий, але я не збираюсь його красти.

Бонус: за бажанням можна вказати кількість ходів.

(n=25,R=n=>Math.random()*n|0)=>(r=>{for(N=_=>'UDRLFB'[(r-=~R(5))%6],b=N(a=N(s=''));n;~(a+b+c).search('^([UD]*|[RL]*|[FB]*)$')?0:s+=(--n,a=b,b=c)+["","'",2][R(3)])c=N()})(0)||s

Менше гольфу

(n = 25) => 
{
  R = n => Math.random()*n | 0;
  N = _ => 'UDRLFB'[(r += 1+R(5)) % 6];
  r = 0;
  b = N();
  a = N();
  for(s = '' ; n; )
     c = N(),
     ~(a+b+c).search('^([UD]*|[RL]*|[FB]*)$')
       ? 0
       : s += (--n, a=b, b=c) + ["","'",2][R(3)];
  return s
}

Тест

var F=
(n=25,R=n=>Math.random()*n|0)=>(r=>{for(N=_=>'UDRLFB'[(r-=~R(5))%6],b=N(a=N(s=''));n;~(a+b+c).search('^([UD]*|[RL]*|[FB]*)$')?0:s+=(--n,a=b,b=c)+["","'",2][R(3)])c=N()})(0)||s

function go() {
  console.log(F(+M.value))
}

go()
Moves <input type=number min=1 id=M value=25 max=999>
<button onclick='go()'>Test</button>


2

Javascript - 112

for(c=b=j=25,r=Math.random;j;c+b-5|c-m&&b-m?document.write("URFBLD"[j--,c=b,b=m]+" 2'"[0|r()*3]+" "):0)m=0|r()*6



1

Clojure, 223 байт

(let[R(range)F(fn[f p c](apply concat(filter f(partition-by p c))))](apply str(map str(take 25(F(fn[p](<(count p)3))(zipmap"UDLF""1122")(F(fn[p](=(count p)1))int(for[_ R](rand-nth"UDRLFB")))))(for[_ R](rand-nth[""\'\2])))))

Це значною мірою покладається на шаблон "послідовність -> розділення -> - фільтр -> конмат", він використовується для фільтрації "незаконних" послідовностей граней. Потім ця послідовність відображається у рядку разом із випадковим постфіксом (включаючи порожній рядок).

Нестандартний вихідний пункт:

(->> (for[_(range)](rand-nth"UDRLFB"))
     (partition-by int)           ; "identity" would be the correct fn to use here
     (filter(fn[p](=(count p)1))) ; Only one identical value in partition
     (apply concat)
     (partition-by(zipmap"UDLF""1122")) ; R & B are in the implicit nil group
     (filter(fn[p](<(count p)3)))       ; Only 1 or 2 consecutive faces from a group
     (apply concat)
     (take 25))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.