Risolvi il cubo di Rubik


38

Scrivi il programma più breve che risolve il cubo di Rubik (3 * 3 * 3) entro un ragionevole lasso di tempo e mosse (diciamo, massimo 5 secondi sulla tua macchina e meno di 1000 mosse).

L'input è nel formato:

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

(questo particolare input rappresenta il cubo risolto).
Le prime 12 stringhe di 2 caratteri sono i bordi nelle posizioni UF, UR, ... BL (U = su, F = anteriore, R = destra, B = indietro, L = sinistra, D = giù), quindi le successive 8 Le stringhe di 3 caratteri sono gli angoli nelle posizioni UFR, URB, ... DBR.

L'output dovrebbe fornire una sequenza di mosse in questo formato:

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

Laddove D1 o D + rappresentano la rotazione della faccia D (giù) di 90 gradi in senso orario, L2 sta ruotando la faccia L di 180 gradi, U3 o U- rappresenta la rotazione della faccia U di 90 gradi in senso antiorario.
Le lettere non fanno distinzione tra maiuscole e minuscole e gli spazi sono opzionali.

Ad esempio, l'output sopra è corretto per il seguente input:

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

Per maggiori dettagli, si prega di fare riferimento al concorso sul cubo di Tomas Rokicki , ad eccezione del fatto che il punteggio verrà effettuato direttamente dalla dimensione del file come un normale problema di golf del codice. È incluso anche un tester online .

Per riferimento, la soluzione più breve già scritta è l'ultima voce nell'elenco dei vincitori del concorso cubo


Per coloro che hanno difficoltà a visualizzare il formato del layout:

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
Sono accettate lingue diverse da C / C ++ / Java / Perl / Python?
Egor Skriptunoff,

@EgorSkriptunoff Qui sì, usa tutto quello che ti piace, senza librerie di risoluzione dei cubi.
aditsu,

E il punteggio? Punteggio di golf di codice abituale (byte nel programma) o punteggio complesso come nel concorso del 2004?
Egor Skriptunoff,

2
@jdstankosky, ho aggiunto un diagramma.
Peter Taylor,

7
Ci è permesso di togliere gli adesivi e spostarli?
Iszi,

Risposte:


25

C ++ - 1123

Dato che finora nessuno ha pubblicato alcuna risposta, ho deciso di semplificare e golfare la mia soluzione del 2004. È ancora molto indietro rispetto a quello più breve che ho menzionato nella domanda.

#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}}

Non è casuale, ma non procede in modo diretto. Risolve prima i bordi, poi gli angoli. Ad ogni passaggio, prova varie combinazioni di un massimo di 4 algoritmi e semplici giri di facce (in sequenza, non in modo casuale), fino a quando non trova un miglioramento nel numero di pezzi risolti, quindi si ripete fino alla risoluzione. Utilizza 2 algoritmi per i bordi e 2 per gli angoli, tradotti in tutte le posizioni del cubo.

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

L2F3B2F3B1U3F1B3R2F3B1U3F1B3D2F2L3D2L1U2B1L1R3U2R1L3B1U2R1U2L1F1B3U2B1F3L1U2L3R1D3L1R3B2L3R1D3L1R3L3R1D3L1R3B2L3R1D3L1R3B3F1D3B1F3R2B3F1D3B1F3U2F3L3R1B3L1R3U2L3R1B3L1R3F1D2F1L1R3D2R1L3F1D2F3L2U1B1F3L2F1B3U1L2R3L1F3R1L3U2R3L1F3R1L3U1F2U1L1R3F2R1L3U1F2U3L3U3L1U3L3U2L1R1U1R3U1R1U2R3F3U3F1U3F3U2F1B1U1B3U1B1U2B3L1B3R3B1L3B3R1B1B3D3B1D3B3D2B1F1D1F3D1F1D2F3R1F3L3F1R3F3L1F1R3B3R1B3R3B2R1L1B1L3B1L1B2L3R1D3L3D1R3D3L1D1B3D3B1D3B3D2B1F1D1F3D1F1D2F3U3R3U1R3U3R2U1D1R1D3R1D1R2D3

(234 mosse, 0,3 secondi qui)


2
Che ne sai ... un'altra risposta è stata pubblicata in pochi secondi :)
aditsu

Sebbene questa sia più lunga della soluzione Ruby, ritengo che si adatti meglio ai criteri del problema "entro un ragionevole lasso di tempo e movimenti". Mi piacerebbe comunque vedere una soluzione con una media di circa ~ 50 mosse.
primo

2
@primo Grazie :) Il mio codice originale era in media oltre 50 mosse, per meno di 50 penso che tu abbia bisogno di più algoritmi (cubo) o di un approccio diverso come il metodo di Thistlethwaite. Tuttavia, l'efficienza (in numero di mosse) non è molto compatibile con il golf. Ad ogni modo, per soluzioni alternative dai un'occhiata ai vincitori del concorso di Tomas Rokicki.
aditsu,

23

Python 1166 byte

È stata lasciata una notevole quantità di spazio bianco per motivi di leggibilità. Il formato è misurato dopo la rimozione di questo spazio vuoto, e la modifica di vari livelli di rientro a Tab, Tab Space, Tab Tab, ecc ho anche evitato qualsiasi golf che ha colpito le prestazioni troppo drasticamente.

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

Esempio di utilizzo:

$ 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

Questa è un'implementazione dell'algoritmo di Thistlethwaite, usando una ricerca IDA * per risolvere ogni passo. Poiché tutte le tabelle euristiche devono essere calcolate al volo, sono stati fatti diversi compromessi, di solito suddividendo un'euristica in due o più parti di dimensioni abbastanza uguali. Questo rende il calcolo delle tabelle euristiche molte centinaia di volte più veloce, mentre rallenta la fase di ricerca, di solito solo leggermente, ma può essere significativo a seconda dello stato iniziale del cubo.

Indice variabile

  • T - la tabella euristica principale.
  • S- uno stato del cubo risolto. Ogni singolo pezzo è memorizzato come una maschera di bit, rappresentata come un personaggio. Un vettore di orientamento risolto è definito come vettore zero.
  • I - i vari colpi di scena, nell'ordine in cui vengono eliminati dallo spazio di ricerca.
  • G- i gruppi per permutazioni di rotazione, memorizzati come coppie da scambiare. Ogni byte nella stringa compressa codifica per una coppia. Ogni giro ha bisogno di sei scambi: tre per il ciclo del bordo e tre per il ciclo dell'angolo. La stringa compressa contiene solo ascii stampabili (carattere da 32 a 126).
  • M - una funzione che esegue una mossa, data da G.
  • N - converte una permutazione di quattro oggetti in un numero, a scopo di codifica.
  • H - calcola il valore euristico per il dato stato del cubo, utilizzato per cercare la profondità di spostamento da T.
  • P - esegue una ricerca a una sola profondità di una singola fase dell'algoritmo.
  • s - lo stato di permutazione del cubo di input.
  • o - il vettore di orientamento del cubo di input.

Prestazione

Utilizzando il set di dati di Tomas Rokicki , questo script ha registrato una media di 16,02 colpi di scena per soluzione (massimo 35), con un tempo medio di 472 ms (CPU i5-3330 a 3,0 Ghz, PyPy 1.9.0). Il tempo minimo di risoluzione è stato di 233 ms con un massimo di 2,97 s, deviazione standard 0,488. Utilizzando le linee guida per il punteggio del concorso (lo spazio bianco non viene conteggiato, le parole chiave e gli identificatori contano come un byte per una lunghezza di 870), il punteggio complessivo sarebbe stato di 13.549.

Negli ultimi 46 casi (gli stati casuali), ha una media di 30,83 colpi di scena per soluzione, con un tempo medio di 721 ms.


Note sull'algoritmo di Thistlethwaite

A beneficio di chiunque voglia tentare di implementare l'algoritmo di Thistlethwaite , ecco una breve spiegazione.

L'algoritmo funziona secondo un principio di riduzione dello spazio della soluzione molto semplice. Ossia, ridurre il cubo a uno stato in cui non è necessario un sottoinsieme di colpi di scena per risolverlo, ridurlo in uno spazio di soluzione più piccolo e quindi risolvere il resto utilizzando solo i pochi colpi di scena rimanenti.

Originariamente Thistlethwaite suggeriva <L,R,F,B,U,D><L,R,F,B,U2,D2><L,R,F2,B2,U2,D2><L2,R2,F2,B2,U2,D2>. Tuttavia, dato il formato di input, penso che sia più facile ridurre prima a <L,R,F2,B2,U,D>(senza un quarto di giro Fo B), e poi <L2,R2,F2,B2,U,D>prima di raggiungere finalmente lo stato di mezzo giro. Invece di spiegare esattamente perché, penso che sarà evidente dopo aver definito i criteri per ogni stato.

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

Per eliminare Fe un Bquarto di giro, solo i bordi devono essere orientati correttamente. Gilles Roux ha una spiegazione molto valida sul suo sito su quale sia l'orientamento 'corretto' e 'errato', quindi lascerò la spiegazione a lui. Ma fondamentalmente, (e questo è il motivo per cui questo formato di ingresso è così adatto allo Fed Beliminazione), un cubetto di bordo sia orientata correttamente se corrisponde alla seguente espressione regolare: [^RL][^UD]. Un orientamento corretto è generalmente indicato con un 0e non corretto con 1. Fondamentalmente Ue Dadesivi non possono essere visualizzati sul Ro Lfacce, o sui bordi delle eventuali Uo Dbordo cubetti, o non possono essere spostate in posizione senza richiedere una FoB quarto di giro.

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

Due criteri qui. In primo luogo, tutti gli angoli devono essere orientate correttamente e secondo, ciascuno dei cubetti di strato intermedio ( FR, FL, BR, BL) devono essere in qualche luogo nello strato centrale. L'orientamento dell'angolo è definito in modo molto semplice dato il formato di input: la posizione del primo Uo D. Ad esempio, URBha orientamento 0(correttamente orientato), LDFha orientamento 1e LFUorientamento 2.

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

I criteri qui sono i seguenti: ogni faccia può contenere solo adesivi dalla sua faccia, o dalla faccia direttamente di fronte. Ad esempio, sul Uviso potrebbero esserci solo Ue Dadesivi, sul Rviso potrebbero esserci solo Re Ladesivi, sul Fviso potrebbero esserci solo Fe Badesivi, ecc. Il modo più semplice per assicurarsi che questo sia verificare se ciascun bordo è inserito la sua "fetta" e ogni angolo nella sua "orbita". Inoltre, è necessario prestare attenzione alla parità edge-corner. Tuttavia, se si controlla solo la parità degli angoli, viene garantita anche la parità dei bordi e viceversa.

In che modo i colpi di scena influenzano l'orientamento

Ue le Dtorsioni non influiscono né sull'orientamento del bordo, né sull'orientamento degli angoli. I pezzi possono essere scambiati direttamente senza aggiornare il vettore di orientamento.

Re le Ltorsioni non influiscono sull'orientamento del bordo, ma influenzano l'orientamento degli angoli. A seconda di come definisci il tuo ciclo, la modifica dell'orientamento dell'angolo sarà +1, +2, +1, +2o +2, +1, +2, +1, tutto il modulo 3. Si noti che R2e L2torsioni non influenzano l'orientamento angolo, come +1+2è zero modulo 3, come è +2+1.

Fe Binfluisce sia sugli orientamenti dei bordi che sugli orientamenti degli angoli. Gli orientamenti dei bordi diventano +1, +1, +1, +1(mod 2) e gli orientamenti degli angoli sono gli stessi di Re L. Si noti che F2e B2influenzano né gli orientamenti bordo, né gli orientamenti angolari.


Ottimo commento. Hai sentito parlare dell'algoritmo di Kociemba?
miglia

Io ho. In linea di principio, è lo stesso algoritmo, tranne che invece di quattro fasi, ha solo due: <L,R,F,B,U,D>-> <L2,R2,F2,B2,U,D>-> <I>. Richiede un massimo di 29 colpi di scena per risolvere un cubo (anziché 52 per Thistlethwaite), ma richiede anche tabelle di ricerca molto grandi, che sarebbe poco pratico generare "al volo".
primo

@ P0W il formato di input è un po 'confuso, sospetto che potresti avere un errore lì. Ogni caso che ho verificato risulta in una soluzione.
primo

@primo Ti dispiacerebbe pubblicare un link al codice non golfato se ce l'hai?
Bilow,

12

Rubino, 742 caratteri

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}

Il codice rubino sopra riportato non è stato ancora completamente giocato. Ci sono ancora possibilità di migliorare ulteriormente il codice (ma è già sufficiente come antipasto).

Risolve il cubo strato per strato ma non utilizza alcun algoritmo specifico ma esegue invece sequenze casuali di mosse fino alla risoluzione del cubo.

A causa della natura probabilistica, a volte potrebbero essere necessari più di 5 secondi per risolvere il cubo e in rari casi sono necessarie più di 1000 mosse.

Esempio di output (per l'ingresso 'RU LF UB DR DL BL UL FU BD RF BR FD LDF LBD FUL RFD UFR RDB UBL RBU') è di 757 mosse:

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 

È possibile ridurre considerevolmente il conteggio delle mosse se le stesse mosse sono raggruppate insieme. Pertanto, si può sostituire l'output come

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

Bello, ma a volte ci vogliono più di 20 secondi sul mio computer, in un caso è finito in 48,7 secondi
aditsu

@aditsu Sì. Ma dipende anche fortemente da quale interprete ruby ​​usi. Sulla mia macchina di solito ci vogliono meno di 5 secondi.
Howard

Attualmente sto usando ruby 1.9.3_p392, spesso ci vogliono meno di 5 secondi ma non posso dire "di solito"
aditsu

Prova questo input:FU FR RU BR DB LD LU LB LF RD DF BU FRU BUR FDR DLB DFL LUB FUL DBR
aditsu

Una richiesta: potresti consolidare sequenze come U1 U1 U1in una singola U3?
primo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.