Sequenze di identità sul cubo di Rubik


32

Una sequenza di mosse è una sequenza di mosse (svolte) su un cubo di Rubik (per la notazione guarda in basso). Oltre alla sequenza di mosse vuota, ci sono molte altre sequenze di mosse che non hanno alcun effetto sul cubo. Chiamiamo queste sequenze di mosse sequenze di identità.

Alcune di queste sequenze di identità sono ovvie da determinare, come U2 R R' U2o U D2 U' D2. Nel primo, vengono eseguite due mosse casuali U2 Re successivamente annullate immediatamente R' U2. Il secondo è simile. Le prime due mosse casuali U D2e successivamente vengono annullate, ma in ordine inverso U' D2. Funziona solo perché la mossa ha Ueffetto solo sui pezzi del livello superiore e la mossa ha D2effetto solo sui pezzi del livello inferiore. Puoi vedere una visualizzazione di queste due sequenze di mosse.

U2 RR 'U2 U D2 U 'D2

Altre sequenze di identità potrebbero non essere affatto ovvie. Ad esempio la sequenza R' U' R' F' U F U' R' F R F' U' R U2 R. È piuttosto lungo, ma non ha alcun effetto sul cubo.

inserisci qui la descrizione dell'immagine

Sposta notazione

Una mossa descrive il giro di uno strato di una delle sei facce del cubo. Una mossa consiste in una lettera che rappresenta la faccia seguita da un suffisso opzionale che rappresenta l'angolo di virata.

Le lettere e le facce corrispondenti sono U (Su - il lato rivolto verso l'alto), D (Giù - il lato rivolto verso il basso), R (Destra - il lato rivolto verso destra), L (Sinistra - il lato rivolto verso sinistra) , F (anteriore: il lato rivolto verso di te) e B (posteriore: il lato rivolto verso di te).

Se non c'è suffisso, la faccia viene ruotata di 90 gradi in senso orario, il suffisso 'significa, la faccia viene ruotata di 90 gradi in senso antiorario e il suffisso 2significa che la faccia viene ruotata di 180 gradi in senso orario.

In caso di problemi con la notazione, basta usare http://alg.cubing.net , dove è possibile visualizzare tali sequenze di mosse.

La sfida

Il tuo compito è scrivere un programma, che determina se una sequenza di mosse è un'identità o meno.

È possibile scrivere un programma completo o una funzione. Dovrebbe ricevere una stringa contenente una sequenza di spostamenti (gli spostamenti sono separati da spazi) come input (tramite STDIN, argomento della riga di comando, argomento prompt o funzione) e output (tramite valore di ritorno o STDOUT) un valore booleano o un intero corrispondente ( True - 1 - sequenza identità / False - 0 - non sequenza identità).

Se il suffisso 'crea problemi nel linguaggio di programmazione, è possibile utilizzare un simbolo diverso, ma non a cifre. R F2 U3non è permesso.

Questo è codegolf, quindi vince il codice più breve (in byte).

Casi test

"" -> True
"U2 R R' U2" -> True
"U D2 U' D2" -> True
"U2 R U2 R'" -> False
"R' U' R' F' U F U' R' F R F' U' R U2 R" -> True
"L'" -> False
"B B2 B' B2" -> True
"D D2 D'" -> False
"R F' D2 U B' F2 B' U2 D2 F2 B2 U F R'" -> True
"D2 U' R2 U F2 D2 U' R2 U' B' L2 R' B' D2 U B2 L' D' R2" -> False
"R U R' U' R' F R2 U' R' U' R U R' F' R2 U R2 U' R2 U' D R2 U' R2 U R2 D'" -> True
"R U R' U' R' F R2 U' R' U' R U R' F' R2 U' R2 U R2 U' D R2 U' R2 U R2 D'" -> False
"B2 F2 U' F2 U R2 F2 U2 B D' R' D' R2 D' F2 U' F U R2 U R B D B D2 L2 D' F2 U D' R' D B R2 D2 F2 R' F2 D2" -> True
"R U2 R' U R' U2 R U2 R U R' U' R' U R U2" -> False
"U F B' R' U F' R U' F' B L U' F L'" -> False
"R2 U' R' U' R U R U R U' R" -> False
"R' F R' B2 R F' R' B2 R2" -> False

Cosa c'è che non va R F2 U3?
John Dvorak,

2
Voglio solo assicurarmi che tutti abbiano gli stessi presupposti. Se lo consentissi U3, potresti semplicemente lanciare il suffisso in una cifra.
Jakube,

3
Sono più abituato alla notazione che utilizza T-Top, B-Bottom e P-Posterior (retro). Alla gente probabilmente piaceva solo vedere la sequenza R2 D2.
mbomb007,

2
@ mbomb007 Riesco a capire T per la parte superiore, ma non ho mai visto P per la parte posteriore e non capirò il suo significato se non fosse per il tuo commento ...
John Dvorak,

2
@ mbomb007 Ho visto anche quella notazione, ma non è né comune né vecchia come la notazione Singmaster originale, e non so perché la gente voglia rovinare l'originale. Sebbene David Singmaster (per quanto ne so) non l'abbia menzionato, ho osservato che tutti i volti sono perfettamente coerenti e senza scontri se considerati come direzioni piuttosto che posizioni. That is F(orward), B(ackward), L(eft), R(ight), U(p), D(own)
Level River St,

Risposte:


14

Haskell, 263 261 247 243 caratteri

c[x]=[x]
c(x:"2")=[x,x]
c(x:_)=[x,x,x]
s!a@[x,y,z]=case s of
 'R'|x>0->[x,-z,y]
 'B'|y>0->[z,y,-x]
 'U'|z>0->[-y,x,z]
 'L'|x<0->[x,z,-y]
 'F'|y<0->[-z,y,x]
 'D'|z<0->[y,-x,z]
 _->a
r=[-2..2]
i=mapM id[r,r,r]
f w=i==foldr(map.(!))i(c=<<words w)

Algoritmo piuttosto diretto; ogni cubetto è composto da 1,2,4 o 8 pezzi che ne codificano la posizione e l'orientamento; 4 pezzi per cubicolo di bordo, 8 per cubetto di angolo, 7 cubetti sono fissi.

c c trasforma ciascuna parola dell'ingresso in una sequenza di turni CW e !invia ciascun blocco in base a un turno. iè la posizione i dentity. fè il principale f unzione.

Non sono troppo contento della cfunzione homp, ma non riesco nemmeno a trovare un modo per accorciarlo (@Nimi lo ha fatto, tuttavia)


Che ne dici di c(x:"2")=[x,x]e c(x:_)=[x,x,x]. Salva 2 byte.
nimi

Se usi i=sequence[s,s,s]e cambi tutte le tuple in elenchi (cioè: (x,y,z)diventa [x,y,z]) - salveranno ~ 9 caratteri. Allineando ne salva altri 4. Eliminare il _caso da !salva un altro 11.
MtnViewMark

@MtnViewMark fatto e migliorato i, grazie. Non sei sicuro di cosa intendi per allineamento i- tieni presente che appare due volte nella definizione per f. Non sei sicuro di cosa intendi lasciando cadere il _caso: o lasciarlo _->acompletamente o spostarlo in alto produce un'eccezione di modello non esaustivo e spostarlo in alto non salva comunque alcun personaggio. Sono riuscito a salvare 5 personaggi lì, tuttavia.
John Dvorak,

Ottima soluzione Ho controllato tutti i casi di test.
Jakube,

Ancora una volta, complimenti per la tua soluzione. Da quando hai presentato il codice più breve, ricevi la ricompensa del valore di 100 reputazione.
Jakube,

4

Cubicamente , 6 4 byte

¶=8%

Vinco: P

¶=8%
¶     read a string, evaluate as Cubically code
 =8   set notepad to (notepad == 8th face)
   %  print notepad

Il blocco note è inizializzato su zero. L'ottava "faccia" contiene 1 se il cubo è irrisolto e 0 altrimenti.

Provalo online!


3
Sembra una lingua interessante. Ma poiché la lingua è stata creata dopo la pubblicazione della sfida, non è idonea per la vittoria.
Jakube,

2
@Jakube Sono d'accordo sul fatto che non dovrebbe essere accettato, solo perché è una lingua con i builtin di Cubo di Rubik pubblicati così tardi dopo la sfida e decimando così completamente le altre risposte. Ma è tecnicamente ammissibile per vincere secondo meta (la regola non competitiva è stata in qualche modo revocata).
MD XF,

3

J - 232, 220, 381, 315 296 byte

Questa soluzione codifica tutte le operazioni come permutazioni della faccia e funziona in base al fatto che tutte le torsioni della faccia sono effettivamente le stesse, sotto una rotazione dell'intero cubo.

Modifica : un po 'più di golf

f=:+/~6&*
r=:4 :'y f&.>(]{^:x~)&.C.;/i.2 4'"0
t=:((r~0),_4<\44#.inv 1478253772705907911x)&C.&.
Y=:(C.(,0 2 r 4 5),;/4 f&i.8)&{^:t
X=:((,1 1 0 2 r 2 4 3 1)C.C.;/0 4 2 5 f i.8)&{^:t
61".@A."1'=: ',"#~6 3$'D0XR1YF1XU2YB3XL3Y'
T=:[:(_2".@}.'(i.48)-:'&(,,[))[:(,'^:',])/&.>@|.&.;:[:''''&=@{.`]},:&'3'

Altro che i tentativi precedenti, questo non prende rotazione angolo in considerazione.

fè solo una funzione di aiuto. rfa la rotazione di una faccia. una faccia è codificata come segue:

  1. tutti gli angoli con incrementi di 6
  2. tutti i bordi con incrementi di sei

questo ordine facilita la codifica di rotazioni e colpi di scena. tè un avverbio che torce la faccia sotto una certa rotazione del cubo, selezionando la faccia.

Xe Ysono avverbi che prendono come argomento a sinistra il numero in quella direzione dell'intero cubo.

La riga successiva definisce tutte le rotazioni: 3 caratteri per rotazione: il nome, il numero di rotazioni e la direzione.

L'ultima riga definisce il verbo di prova T, convertendo 3 e 'in notazione di potenza, capovolgendo l'ordine di operazione aggiungendo il vettore di prova e definendo infine l'intera cosa.

Maggiori dettagli su richiesta.

tests =: (] ;. _2) 0 : 0

 U2 R R' U2
 U D2 U' D2
 U2 R2 R'
 R' U' R' F' U F U' R' F R F' U' R U2 R
 L'
 B B2 B' B2
 D D2 D'
 R F' D2 U B' F2 B' U2 D2 F2 B2 U F R'
 D2 U' R2 U F2 D2 U' R2 U' B' L2 R' B' D2 U B2 L' D' R2
 R U R' U' R' F R2 U' R' U' R U R' F' R2 U R2 U' R2 U' D R2 U' R2 U R2 D'
 R U R' U' R' F R2 U' R' U' R U R' F' R2 U' R2 U R2 U' D R2 U' R2 U R2 D'
 B2 F2 U' F2 U R2 F2 U2 B D' R' D' R2 D' F2 U' F U R2 U R B D B D2 L2 D' F2 U D' R' D B R2 D2 F2 R' F2 D2
 R U2 R' U R' U2 R U2 R U R' U' R' U R U2
 U F B' R' U F' R U' F' B L U' F L'
 R2 U' R' U' R U R U R U' R
 R' F R' B2 R F' R' B2 R2
)
res =: 1 1 1 0 1 0 1 0 1 0 1 0 1 0 0 0 0
res ([,],:=) T"1 tests NB. passes all tests.
1 1 1 0 1 0 1 0 1 0 1 0 1 0 0 0 0
1 1 1 0 1 0 1 0 1 0 1 0 1 0 0 0 0
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

NB. some handy display methods:
dispOrig=: (". ;._2) 0 :0
   _   _   _   5  29  11   _   _   _   _   _   _
   _   _   _  47  _1  35   _   _   _   _   _   _
   _   _   _  23  41  17   _   _   _   _   _   _
   3  27   9   0  24   6   1  25   7   2  26   8
  45  _3  33  42  _6  30  43  _5  31  44  _4  32
  21  39  15  18  36  12  19  37  13  20  38  14
   _   _   _   4  28  10   _   _   _   _   _   _
   _   _   _  46  _2  34   _   _   _   _   _   _
   _   _   _  22  40  16   _   _   _   _   _   _
)
ind =: dispOrig i.&, i. 48 NB. indices of i.48 in the original display

disp =: (9 12$(,dispOrig) ind}~ ])
changed =: 1 : '(u ~:&disp ]) i.48' NB. use to debug permutation verbs: L ch
vch =: 1 :'disp  ((]+_*=) u)'
NB. viewmat integration RGB
cm =: 255 * 1 0 0 , 1 1 1, 0 1 0, 1 1 0, 1 0.5 0, 0 0 1,: 0 0 0 NB. colormap
NB. use as:  "cube i. 48" for seeing a nice folded out cube.
cube =: cm viewmat (>&7 + >&15 + >&23 + >&31 + >& 39 + >&47)@|@disp@]

11
"poiché i risultati dei miei test non corrispondono a quelli indicati ..." come in, la tua soluzione non funziona? Non lo pubblicherei allora ...
John Dvorak,

Hai ragione. Risolto il problema ora.
jpjacobs,

Ho aggiunto 4 casi di test aggiuntivi. Due di loro restituiscono ancora il risultato falso. Sembra che ignori l'orientamento degli angoli.
Jakube,

@jpjacobs Ora c'è una generosità di 100 rappresentanti sulla domanda. Vuoi correggere il tuo codice?
Jakube,

Voilà, fatto. Ora solo ridurlo.
jpjacobs,

2

Python 3: 280 caratteri

Questo non è un partecipante alla sfida. In primo luogo perché ho chiesto la sfida da solo e in secondo luogo perché non è il mio codice. Tutti i crediti appartengono a Stefan Pochmann , che ha scoperto questo fantastico modo di simulare un cubo di Rubik. Ho solo giocato a golf e alcuni piccoli cambiamenti rispetto alla sfida.

def f(a):
 s=t="UF UR UB UL DF DR DB DL FR FL BR BL UFR URB UBL ULF DRF DFL DLB DBR".split()
 for m in a.split():q="FLBR FRBL FDBU FUBD URDL ULDR".split()['UDLRFB'.index(m[0])];n=2+"2'".find(m[-1]);s=[[p,p.translate(str.maketrans(q,q[n:]+q[:n]))][m[0]in p]for p in s]
 return s==t

L'idea alla base è la seguente. srappresenta la posizione dei pezzi di UF, URe così via. Ad esempio: s = ['DF', 'BL', ...]significa che il pezzo UFè nella posizione DF, il pezzo URè nella posizione BL, ...

Come cambia la posizione di un pezzo quando si fa una mossa. Se Uesegui un movimento, tutti gli adesivi (colori) dello Ustrato, che erano rivolti verso la faccia anteriore, si spostano sulla faccia sinistra. Gli adesivi della faccia sinistra si spostano sul retro, questi a destra e questi sulla faccia anteriore. Codificato da FLBR. Alcuni esempi: UFpassa a UL, UFRpassa a ULFe così via. Pertanto, applicare una mossa significa semplicemente tradurre le facce dei pezzi nel livello corrispondente.

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.