Розв’яжіть кубик Рубіка


38

Напишіть найкоротшу програму, яка вирішує кубик Рубіка (3 * 3 * 3) протягом розумного часу та рухається (скажімо, максимум 5 секунд на вашій машині та менше 1000 рухів).

Вхід у форматі:

UF UR UB UL DF DR DB DL FR FL BR BL UFR URB UBL ULF DRF DFL DLB DBR

(саме цей вхід представляє вирішений куб).
Перші 12 рядків із 2 символів - це краї в положеннях UF, UR, ... BL (U = вгору, F = спереду, R = праворуч, B = назад, L = ліворуч, D = вниз), потім наступні 8 3-символьні рядки - це кути в положеннях UFR, URB, ... DBR.

Вихід повинен дати послідовність рухів у такому форматі:

D+ L2 U+ F+ D+ L+ D+ F+ U- F+

Якщо D1 або D + являє собою поворот D (вниз) обличчям за годинниковою стрілкою на 90 градусів, L2 повертає лицьову сторону L на 180 градусів, U3 або U- являє собою поворот обличчя U проти годинникової стрілки на 90 градусів.
Букви нечутливі до регістру, а пробіли необов’язкові.

Наприклад, вихідний результат правильний для наступного вводу:

RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU

Більш детально, будь ласка, зверніться до змагань з кубиками Томаша Рокіцького , за винятком того, що підрахунок буде зроблений безпосередньо за розміром файлу, як звичайна проблема з гольф-кодом. онлайн тестер включений теж.

Для довідки, найкоротше вже написане рішення - це останній запис у списку переможців конкурсу кубів


Для тих, хто бореться за візуалізацію формату макета:

0-1 2-3 4-5 6-7 8-9 10-11 12-13 14-15 16-17 18-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
UF  UR  UB  UL  DF   DR    DB   DL    FR    FL     BR    BL     UFR      URB      UBL      ULF      DRF      DFL      DLB      DBR

Front:

                 +-------+-------+-------+
                /       /       /       /|
               /  30   /   4   /  27   / |
              +-------+-------+-------+  |
             /       /       /       /|28+
            /   6   /       /   2   / | /|
           +-------+-------+-------+  |/ |
          /       /       /       /|3 +  |
         /  33   /   0   /  24   / | /|21+
        +-------+-------+-------+  |/ | /|
        |       |       |       |26+  |/ |
        |  35   |   1   |   25  | /|  +  |
        |       |       |       |/ | /|47+
        +-------+-------+-------+  |/ | /
        |       |       |       |17+  |/
        |  18   |       |  16   | /|11+
        |       |       |       |/ | /
        +-------+-------+-------+  |/
        |       |       |       |37+
        |  40   |   9   |  38   | /
        |       |       |       |/
        +-------+-------+-------+


Hidden faces:

                 +-------+-------+-------+
                /|       |       |       |
               / |  31   |   5   |  29   |
              +  |       |       |       |
             /|32+-------+-------+-------+
            / | /|       |       |       |
           +  |/ |  22   |       |  20   |
          /|7 +  |       |       |       |
         / | /|23+-------+-------+-------+
        +  |/ | /|       |       |       |
        |34+  |/ |  44   |  13   |  46   |
        | /|  +  |       |       |       |
        |/ | /|43+-------+-------+-------+
        +  |/ | /       /       /       /
        |19+  |/  42   /  12   /  45   /
        | /|15+-------+-------+-------+
        |/ | /       /       /       /
        +  |/  14   /       /  10   /
        |41+-------+-------+-------+
        | /       /       /       /
        |/  39   /   8   /   36  /
        +-------+-------+-------+

3
Чи прийняті інші мови, ніж C / C ++ / Java / Perl / Python?
Єгор Скриптунов

@EgorSkriptunoff Тут так, використовуйте все, що завгодно, тільки не бібліотеки для вирішення кубів.
aditsu

А як щодо скорингу? Звичайний кодовий гол-голінг (байти в програмі) або складний скоринг, як у змаганні 2004 року?
Egor Skriptunoff

2
@jdstankosky, я додав діаграму.
Пітер Тейлор

7
Чи дозволяється нам знімати наклейки і переміщувати їх?
Іссі

Відповіді:


25

C ++ - 1123

Оскільки досі ніхто не публікував жодної відповіді, я вирішив спростити і пограбувати своїм рішенням 2004 року. Це все ще далеко позаду найкоротшого, про який я згадував у питанні.

#include<iostream>
#include<vector>
#define G(i,x,y)for(int i=x;i^y;i++)
#define h(x)s[a[x]/q*q+(a[x]+j)%q-42]
#define B(x)D=x;E=O.substr(j*3,3);G(i,0,3)E+=F[5-F.find(E[2-i])];G(i,0,D.length())D[i]=E[F.find(D[i++])];m.push_back(D);
#define P(a,b)G(i,0,6)G(k,49,52){e[0]=F[i];e[1]=k;m.push_back(e);}G(j,0,24){B(a)B(b)}
#define T C();z=m.size();for(b=c;b;){d=s;G(i,o=w=1,4){w*=z;if(o)G(j,0,w)if(o){s=d;u=j;G(k,0,i){f=m[u%z];G(x,0,f.length()){a=M[F.find(f[x++])];G(i,0,f[x]-48)G(l,0,2){q=3-l;p=4*l;G(j,0,q){t=h(p+3);G(k,-3,0)h(p-k)=h(p-1-k);h(p)=t;}}}u/=z;}C();if(c<b){u=j;G(k,0,i){std::cout<<m[u%z];u/=z;}b=c;o=0;}}}}
std::string s,a,D,E,d,f,e="  ",S="UFURUBULDFDRDBDLFRFLBRBLUFRURBUBLULFDRFDFLDLBDBR",F="ULFBRD",M[]={"KHEB*0.,","KRTI0<8@","KDNS*;2=","IVXG/@7>","BGWP,>4:","QNWT2468"},O=S.substr(24)+"FDRFRUFULFLDRDBRBURUFRFDBDLBLUBURBRDLDFLFULUBLBD";std::vector<std::string>m;int
w,X=8,Y=16,o,c,u,b,z,p,q,t;void C(){c=0;G(i,X,Y)c+=s[i]!=S[i];}main(int
g,char**v){G(i,1,g)s+=v[i];P("U2F1R1L3U2L1R3F1U2","L3R1F3L1R3D2L3R1F3L1R3");T;Y=24;T;X=0;T;m.clear();P("R3D3R1D3R3D2R1L1D1L3D1L1D2L3","R1F3L3F1R3F3L1F1");G(I,5,9){Y=I*6;T}}

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

Приклад виводу для RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU:

L2F3B2F3B1U3F1B3R2F3B1U3F1B3D2F2L3D2L1U2B1L1R3U2R1L3B1U2R1U2L1F1B3U2B1F3L1U2L3R1D3L1R3B2L3R1D3L1R3L3R1D3L1R3B2L3R1D3L1R3B3F1D3B1F3R2B3F1D3B1F3U2F3L3R1B3L1R3U2L3R1B3L1R3F1D2F1L1R3D2R1L3F1D2F3L2U1B1F3L2F1B3U1L2R3L1F3R1L3U2R3L1F3R1L3U1F2U1L1R3F2R1L3U1F2U3L3U3L1U3L3U2L1R1U1R3U1R1U2R3F3U3F1U3F3U2F1B1U1B3U1B1U2B3L1B3R3B1L3B3R1B1B3D3B1D3B3D2B1F1D1F3D1F1D2F3R1F3L3F1R3F3L1F1R3B3R1B3R3B2R1L1B1L3B1L1B2L3R1D3L3D1R3D3L1D1B3D3B1D3B3D2B1F1D1F3D1F1D2F3U3R3U1R3U3R2U1D1R1D3R1D1R2D3

(234 ходи, 0,3 сек тут)


2
Що ти знаєш ... Ще одна відповідь була розміщена протягом декількох секунд :)
aditsu

Хоча це довше, ніж рішення Ruby, я вважаю, що воно краще відповідає критеріям проблеми "в розумний проміжок часу і рухається". Я все ж хотів би побачити рішення, яке в середньому становить менше ~ 50 ходів.
примо

2
@primo Спасибі :) Мій оригінальний код в середньому перевищував 50 рухів, для молодших за 50 років я думаю, що вам або потрібно більше (куб) алгоритмів, або інший підхід, такий як метод Thistlethwaite. Однак ефективність (не в ході) не дуже сумісна з гольфом. У будь-якому випадку, для альтернативних рішень дізнайтеся переможців конкурсу Томаша Рокіцького.
aditsu

23

Python 1166 байт

Значна кількість пробілів залишилось заради читабельності. Розмір вимірюється після видалення цього пропуски і зміни різних рівнів відступу до Tab, Tab Space, Tab Tabі т.д. Я також уникав грати в гольф , який вплинув на продуктивність занадто різко.

T=[]
S=[0]*20,'QTRXadbhEIFJUVZYeijf',0
I='FBRLUD'

G=[(~i%8,i/8-4)for i in map(ord,'ouf|/[bPcU`Dkqbx-Y:(+=P4cyrh=I;-(:R6')]
R=range

def M(o,s,p):
 z=~p/2%-3;k=1
 for i,j in G[p::6]:i*=k;j*=k;o[i],o[j]=o[j]-z,o[i]+z;s[i],s[j]=s[j],s[i];k=-k

N=lambda p:sum([i<<i for i in R(4)for j in R(i)if p[j]<p[i]])

def H(i,t,s,n=0,d=()):
 if i>4:n=N(s[2-i::2]+s[7+i::2])*84+N(s[i&1::2])*6+divmod(N(s[8:]),24)[i&1]
 elif i>3:
  for j in s:l='UZifVYje'.find(j);t[l]=i;d+=(l-4,)[l<4:];n-=~i<<i;i+=l<4
  n+=N([t[j]^t[d[3]]for j in d])
 elif i>1:
  for j in s:n+=n+[j<'K',j in'QRab'][i&1]
 for j in t[13*i:][:11]:n+=j%(2+i)-n*~i
 return n

def P(i,m,t,s,l=''):
 for j in~-i,i:
  if T[j][H(j,t,s)]<m:return
 if~m<0:print l;return t,s
 for p in R(6):
  u=t[:];v=s[:]
  for n in 1,2,3:
   M(u,v,p);r=p<n%2*i or P(i,m+1,u,v,l+I[p]+`n`)
   if r>1:return r

s=raw_input().split()
o=[-(p[-1]in'UD')or p[0]in'RL'or p[1]in'UD'for p in s]
s=[chr(64+sum(1<<I.find(a)for a in x))for x in s]

for i in R(7):
 m=0;C={};T+=C,;x=[S]
 for j,k,d in x:
  h=H(i,j,k)
  for p in R(C.get(h,6)):
   C[h]=d;u=j[:];v=list(k)
   for n in i,0,i:M(u,v,p);x+=[(u[:],v[:],d-1)]*(p|1>n)
 if~i&1:
  while[]>d:d=P(i,m,o,s);m-=1
  o,s=d

Використання зразка:

$ more in.dat
RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU

$ pypy rubiks.py < in.dat
F3R1U3D3B1
F2R1F2R3F2U1R1L1
R2U3F2U3F2U1R2U3R2U1
F2L2B2R2U2L2D2L2F2

Це реалізація алгоритму Thistlethwaite, використовуючи пошук IDA * для вирішення кожного кроку. Оскільки всі евристичні таблиці потрібно обчислювати під час руху, було зроблено кілька компромісів, зазвичай розбиваючи евристику на дві або більше досить однакових розмірів. Це робить обчислення евристичних таблиць у багато сотень разів швидшими, при цьому сповільнюється фаза пошуку, як правило, лише незначно, але це може бути суттєво залежно від початкового стану куба.

Індекс змінної

  • T - основна евристична таблиця.
  • S- розв’язаний стан куба. Кожен окремий фрагмент зберігається як бітова маска, представлена ​​у вигляді символу. Розв’язаний вектор орієнтації визначається як нульовий вектор.
  • I - різні повороти, в порядку, що їх усувають з пошукового простору.
  • G- групи для перекручування перестановок, що зберігаються у вигляді пар, що підлягають заміні. Кожен байт у стислому рядку кодує одну пару. Кожен поворот потребує шести свопів: три для крайового циклу і три для кутового циклу. Стислий рядок містить лише ascii для друку (графіки 32 до 126).
  • M - функція, яка виконує хід, задану Г.
  • N - перетворює перестановку чотирьох об'єктів у число для цілей кодування.
  • H - обчислює евристичне значення для заданого стану куба, що використовується для пошуку глибини переміщення від T.
  • P - виконати пошук на одній глибині однієї фази алгоритму.
  • s - стан перестановки вхідного куба.
  • o - вектор орієнтації вхідного куба.

Продуктивність

Використання набору даних Томаша Рокіцького , цей сценарій в середньому становив 16,02 поворотів за рішення (максимум 35), із середнім часом 472 мс (процесор i5-3330 процесор @ 3,0 ГГц, PyPy 1.9,0). Мінімальний час вирішення становив 233 мс, максимум 2,97, стандартне відхилення 0,488. Використовуючи вказівки щодо оцінки змагань (пробіл не враховується, ключові слова та ідентифікатори вважаються одним байтом довжиною 870), загальна оцінка склала б 13 549.

За останні 46 випадків (випадкові стани) вона становила в середньому 30,83 поворотів на вирішення, із середнім часом 721 мс.


Примітки до алгоритму Thistlethwaite

На користь тому, хто захоче спробувати здійснити Алгоритм Тістлетвейта , ось коротке пояснення.

Алгоритм працює за дуже простим принципом скорочення простору рішення. Тобто, зменшіть куб до стану, коли підмножина скручувань не потрібна для його вирішення, зменшіть його до меншого простору рішення, а потім вирішіть решту, використовуючи лише декілька скручувань, що залишилися.

Спочатку пропонувався Thistlethwaite <L,R,F,B,U,D><L,R,F,B,U2,D2><L,R,F2,B2,U2,D2><L2,R2,F2,B2,U2,D2>. Однак, враховуючи формат введення, я думаю, що простіше спочатку зменшити до <L,R,F2,B2,U,D>(не чверть обороту Fчи B), а потім, <L2,R2,F2,B2,U,D>перш ніж остаточно досягти стану половини обороту. Замість того, щоб пояснити, чому саме так, я думаю, що це стане очевидним після визначення критеріїв для кожної держави.

<L,R,F,B,U,D><L,R,F2,B2,U,D>

Для усунення Fта Bчверть витків, тільки краї повинні бути орієнтовані правильно. Жил Ру має на своєму сайті дуже гарне пояснення, що таке «правильна» та «неправильна» орієнтація, тому я залишу його пояснення. Але в основному, (і саме тому цей формат введення настільки розташовує до Fі Bліквідація), кромка Cubie правильно орієнтована , якщо він відповідає наступному регулярному виразу: [^RL][^UD]. Правильна орієнтація зазвичай позначається символом a, 0а неправильна - 1. В принципі Uі Dнаклейки не можуть з'являтися на Rабо Lособа, або по краях будь Uабо Dкрайової cubies, або вони не можуть бути переміщені на місце , не вимагаючи чверть твіст.F абоB

<L,R,F2,B2,U,D><L2,R2,F2,B2,U,D>

Тут два критерії. По- перше, всі кути повинні бути орієнтовані правильно, а по- друге, кожен з cubies для середнього шару ( FR, FL, BR, BL) повинні бути де - то в середньому шарі. Кутова орієнтація дуже просто визначається з урахуванням формату введення: положення першого Uабо D. Наприклад, URBмає орієнтацію 0(правильно орієнтовану), LDFмає орієнтацію 1та LFUмає орієнтацію 2.

<L2,R2,F2,B2,U,D><L2,R2,F2,B2,U2,D2>

Критерії тут такі: кожне обличчя може містити наклейки лише з обличчя або з боку обличчя прямо навпроти нього. Наприклад, на Uобличчі може бути тільки Uта Dнаклейки, на Rобличчі може бути тільки Rта Lнаклейки, на Fобличчі може бути тільки Fта Bнаклейки і т.д. Найпростіший спосіб забезпечити це , щоб перевірити , якщо кожне ребро частина знаходиться в його "зріз" і кожен кутовий шматок на його "орбіті". Крім того, потрібно звернути увагу на паритет крайових кутів. Хоча, якщо ви перевіряєте лише кутовий паритет, паритет краю також гарантований, і навпаки.

Як повороти впливають на орієнтацію

Uі Dповороти не впливають ні на орієнтацію краю, ні на орієнтацію кута. Шматки можуть бути замінені безпосередньо без оновлення орієнтаційного вектора.

Rі Lповороти не впливають на орієнтацію краю, але вони впливають на орієнтацію кута. Залежно від того, як ви визначаєте свій цикл, зміна орієнтації кута буде або, +1, +2, +1, +2або +2, +1, +2, +1все модульно 3. Зверніть увагу , що R2і L2повороти не впливають на кутовий орієнтації, а +1+2дорівнює нулю по модулю 3, як це +2+1.

Fі Bвпливають як на крайові орієнтації, так і на кутові орієнтації. Крайові орієнтації стають +1, +1, +1, +1(мод 2), а кутові орієнтації такі ж, як Rі для та L. Слід зазначити , що F2і B2впливають ні краю, ні орієнтації кутових орієнтацій.


Відмінний запис. Ви чули про алгоритм Кочімба?
миль

Я маю. В принципі, це той самий алгоритм, за винятком чотирьох фаз, він має лише дві: <L,R,F,B,U,D>-> <L2,R2,F2,B2,U,D>-> <I>. Для вирішення куба потрібно максимум 29 поворотів (замість 52 для Thistlethwaite), але також потрібні дуже великі таблиці пошуку, що було б недоцільно генерувати "на льоту".
примо

@ P0W формат введення трохи заплутаний, я підозрюю, що у вас може виникнути помилка. У кожному випадку я перевіряв результати рішення.
прим

@primo Чи не хотіли б ви опублікувати посилання на код, який не використовується для гольфу, якщо у вас є?
Білоу

12

Рубі, 742 символи

r=->y{y.split.map{|x|[*x.chars]}}
G=r['UF UR UB UL DF DR DB DL FR FL BR BL UFR URB UBL ULF DRF DFL DLB DBR']
o=r[gets]
x=[];[[%w{U UU UUU L LL LLL}+D=%w{D DD DDD},0],[%w{FDFFF RFDFFFRRR}+D,12],[%w{DDDRRRDRDFDDDFFF DLDDDLLLDDDFFFDF}+D,8],[%w{DFLDLLLDDDFFF RDUUUFDUUULDUUUBDUUU}+D,4],[%w{LDDDRRRDLLLDDDRD RRRDLDDDRDLLLDDD LFFFLLLFLFFFLLLF},16]].map{|q,y|x+=[*y..y+3]
3.times{q.map{|e|q|=[e.tr('LFRB','FRBL')]}}
w=->u{x.count{|t|u[t]!=G[t]}}
s=w[o]
(c=(0..rand(12)).map{q.sample}*''
z=o
c.chars{|m|z="=$'*:036\".?BOHKVGRWZ!$@*-0C69<4(E\\INQTMX!$'B-03<9*?6EHYLQPUZ!9'*-?360<$BSFKN[TWJ$'*!-0369<?BHKNEQTWZ!$'*6-039<?BEHKNTWZQ"[20*('FBLRUD'=~/#{m}/),20].bytes.map{|e|z[e/3-11].rotate e%3}}
t=w[z]
(c.chars{|e|$><<e<<'1 '};o=z;s=t)if s>t
)until s<1}

Наведений вище код рубіну ще не в повному обсязі. Є ще можливості вдосконалити код далі (але його вже достатньо як початковий).

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

В силу ймовірнісного характеру іноді може знадобитися більше 5 секунд, щоб вирішити куб, а в рідкісних випадках потрібно більше 1000 ходів.

Приклад виводу (для введення 'RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU') 757 ходів:

F1 R1 R1 F1 F1 F1 R1 R1 R1 L1 L1 L1 F1 D1 L1 L1 D1 D1 D1 D1 L1 B1 D1 
B1 B1 B1 L1 L1 L1 F1 D1 F1 F1 F1 L1 D1 L1 L1 L1 B1 D1 B1 B1 B1 R1 D1 
R1 R1 R1 L1 B1 D1 B1 B1 B1 L1 L1 L1 D1 D1 B1 D1 B1 B1 B1 B1 D1 B1 B1 
B1 L1 D1 L1 L1 L1 D1 D1 D1 D1 D1 R1 D1 R1 R1 R1 R1 F1 D1 F1 F1 F1 R1 
R1 R1 R1 D1 R1 R1 R1 F1 L1 D1 L1 L1 L1 F1 F1 F1 D1 D1 D1 D1 L1 D1 L1 
L1 L1 F1 L1 D1 L1 L1 L1 F1 F1 F1 D1 D1 L1 D1 L1 L1 L1 D1 L1 D1 L1 L1 
L1 L1 D1 L1 L1 L1 D1 R1 D1 D1 D1 R1 R1 R1 D1 D1 D1 B1 B1 B1 D1 B1 D1 
L1 D1 D1 D1 L1 L1 L1 D1 D1 D1 F1 F1 F1 D1 F1 D1 D1 D1 B1 B1 B1 D1 B1 
D1 R1 D1 D1 D1 R1 R1 R1 D1 D1 D1 B1 B1 B1 D1 B1 D1 R1 D1 D1 D1 R1 R1 
R1 D1 B1 D1 D1 D1 B1 B1 B1 D1 D1 D1 L1 L1 L1 D1 L1 D1 B1 D1 D1 D1 B1 
B1 B1 D1 D1 D1 L1 L1 L1 D1 L1 D1 D1 F1 D1 D1 D1 F1 F1 F1 D1 D1 D1 R1 
R1 R1 D1 R1 D1 D1 D1 R1 R1 R1 D1 R1 D1 F1 D1 D1 D1 F1 F1 F1 D1 B1 D1 
D1 D1 B1 B1 B1 D1 D1 D1 L1 L1 L1 D1 L1 D1 D1 D1 F1 F1 F1 D1 F1 D1 L1 
D1 D1 D1 L1 L1 L1 D1 D1 D1 D1 D1 D1 F1 F1 F1 D1 F1 D1 L1 D1 D1 D1 L1 
L1 L1 D1 D1 D1 F1 F1 F1 D1 F1 D1 L1 D1 D1 D1 L1 L1 L1 D1 F1 D1 D1 D1 
F1 F1 F1 D1 D1 D1 R1 R1 R1 D1 R1 D1 D1 D1 F1 F1 F1 D1 F1 D1 L1 D1 D1 
D1 L1 L1 L1 D1 D1 D1 F1 F1 F1 D1 F1 D1 L1 D1 D1 D1 L1 L1 L1 D1 D1 D1 
D1 D1 F1 F1 F1 D1 F1 D1 L1 D1 D1 D1 L1 L1 L1 D1 D1 D1 D1 D1 D1 R1 F1 
D1 F1 F1 F1 D1 D1 D1 R1 R1 R1 D1 F1 L1 D1 L1 L1 L1 D1 D1 D1 F1 F1 F1 
D1 B1 R1 D1 R1 R1 R1 D1 D1 D1 B1 B1 B1 D1 B1 R1 D1 R1 R1 R1 D1 D1 D1 
B1 B1 B1 D1 D1 D1 D1 B1 R1 D1 R1 R1 R1 D1 D1 D1 B1 B1 B1 D1 D1 D1 D1 
D1 D1 B1 B1 B1 D1 F1 D1 D1 D1 B1 D1 F1 F1 F1 D1 D1 D1 R1 R1 R1 D1 L1 
D1 D1 D1 R1 D1 L1 L1 L1 D1 D1 D1 B1 D1 D1 D1 F1 F1 F1 D1 B1 B1 B1 D1 
D1 D1 F1 D1 B1 B1 B1 D1 F1 D1 D1 D1 B1 D1 F1 F1 F1 D1 D1 D1 L1 D1 D1 
D1 R1 R1 R1 D1 L1 L1 L1 D1 D1 D1 R1 D1 F1 R1 R1 R1 F1 F1 F1 R1 F1 R1 
R1 R1 F1 F1 F1 R1 R1 R1 R1 D1 L1 D1 D1 D1 R1 D1 L1 L1 L1 D1 D1 D1 B1 
B1 B1 D1 F1 D1 D1 D1 B1 D1 F1 F1 F1 D1 D1 D1 F1 R1 R1 R1 F1 F1 F1 R1 
F1 R1 R1 R1 F1 F1 F1 R1 F1 D1 D1 D1 B1 B1 B1 D1 F1 F1 F1 D1 D1 D1 B1 
D1 F1 R1 R1 R1 F1 F1 F1 R1 F1 R1 R1 R1 F1 F1 F1 R1 F1 F1 F1 D1 B1 D1 
D1 D1 F1 D1 B1 B1 B1 D1 D1 D1 R1 D1 D1 D1 L1 L1 L1 D1 R1 R1 R1 D1 D1 
D1 L1 D1 R1 R1 R1 D1 L1 D1 D1 D1 R1 D1 L1 L1 L1 D1 D1 D1 R1 D1 D1 D1 
L1 L1 L1 D1 R1 R1 R1 D1 D1 D1 L1 D1 F1 F1 F1 D1 B1 D1 D1 D1 F1 D1 B1 
B1 B1 D1 D1 D1 L1 L1 L1 D1 R1 D1 D1 D1 L1 D1 R1 R1 R1 D1 D1 D1 

Можна значно зменшити кількість рухів, якщо однакові ходи згруповані разом. Тому можна замінити вихід, як

(c.gsub(/(.)\1*/){j=$&.size%4;$><<$1<<j<<' 'if j>0};o=z;s=t)if s>t

Приємно, але іноді на моєму комп’ютері йде більше 20 секунд, в одному випадку це закінчилося за 48,7 сек
aditsu

@aditsu Так. Але це також сильно залежить від того, яким рубіновим перекладачем ви користуєтесь. На моїй машині це зазвичай займає менше 5 секунд.
Говард

Зараз я використовую рубін 1.9.3_p392, часто це займає менше 5 секунд, але я не можу сказати "зазвичай"
aditsu

Спробуйте це ввести:FU FR RU BR DB LD LU LB LF RD DF BU FRU BUR FDR DLB DFL LUB FUL DBR
aditsu

Один запит: чи могли б ви об'єднати послідовності, як U1 U1 U1у єдиний U3?
примо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.