Решить кубик Рубика

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 двухсимвольных строк - это ребра в позициях 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  /
        +-------+-------+-------+
aditsu
источник
3
Принимаются ли другие языки, кроме C / C ++ / Java / Perl / Python?
Егор Скриптунов
@EgorSkriptunoff Здесь да, используйте все, что вам нравится, только нет библиотек, решающих кубы.
aditsu
А как насчет выигрыша? Обычный код - оценка в гольфе (байты в программе) или сложная оценка, как в конкурсе 2004 года?
Егор Скриптунов
2
@jdstankosky, я добавил диаграмму.
Питер Тейлор
7
Разрешено ли снимать наклейки и перемещать их?
Изи

Ответы:

25

С ++ - 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 с здесь)

aditsu
источник
2
Что вы знаете ... другой ответ был опубликован в течение нескольких секунд :)
aditsu
Хотя это и дольше, чем решение Ruby, я считаю, что оно лучше соответствует критериям задачи «в разумные сроки и на ход». Я все еще хотел бы видеть решение, которое в среднем составляет ~ 50 ходов.
Примо
2
@primo Спасибо :) В моем исходном коде было в среднем более 50 ходов, для менее 50 я думаю, что вам нужно либо больше (кубических) алгоритмов, либо другой подход, такой как метод Thistlethwaite. Однако эффективность (в количестве ходов) не очень совместима с игрой в гольф. Так или иначе, для альтернативных решений проверьте победителей конкурса Томаса Рокицки.
адитсу
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]. Правильная ориентация обычно обозначается как « 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 Да. Но это также сильно зависит от того, какой интерпретатор ruby ​​вы используете. На моей машине это обычно занимает менее 5 секунд.
Говард
В настоящее время я использую ruby 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?
Примо