Cubo di Rubik Scrambles


21

Il tuo compito è creare una sequenza casuale di mosse, che può essere utilizzata per rimescolare un cubo di Rubik. Un tale scramble è composto esattamente da 25 mosse. Ogni mossa consiste in lettere UDRLFBopzionalmente seguite da uno dei suffissi '2.

Questa notazione è chiamata la notazione Singmaster. UDRLFBrappresenta una delle 6 facce e il suffisso opzionale '2rappresenta l'angolo di rotazione. Questa informazione non è in alcun modo necessaria per risolvere l'attività.

Per garantire che i scrambles siano di "buona qualità", devono essere applicate le seguenti due regole:

  • Due mosse consecutive non devono avere la stessa lettera. Questo vieta le mosse consecutive UU, DD, RR, LL, FFe BBe tutte le loro combinazioni utilizzando i suffissi opzionali come U2Uo U'U'.

    Queste coppie di mosse sono bandite, perché possono essere facilmente ridotte a 1 o 0 mosse. U2Uha lo stesso effetto di U', R'Rlo stesso effetto di .

  • Tre mosse consecutive non devono appartenere allo stesso gruppo di lettere. I gruppi di lettere sono UD, RLe FB. Questa regola vieta inoltre le mosse consecutive UDU, DUD, RLR, LRL, FBF, BFBe tutte le loro combinazioni utilizzando i suffissi opzionali come U2DU, RL'Ro B2FB'.

    I gruppi ordinano le facce in base all'asse di spostamento. Ue Dfanno parte dello stesso gruppo, poiché entrambi ruotano attorno allo stesso asse. Pertanto una Umossa non influenza i pezzi del Dviso e una Dmossa non influenza i pezzi del Uviso. Pertanto le due mosse possono essere scambiate, UDUha lo stesso effetto di UUDe questo può essere ridotto a U2D.

Sfida

Scrivi uno script o una funzione, che genera uno scramble casuale. Non ci sono input. Lo script / funzione deve stampare le 25 mosse senza separazione o separate da uno spazio o restituire la stringa corrispondente.

Il tuo programma deve essere in grado di creare ogni singolo scramble, che soddisfi le regole di cui sopra. Naturalmente supponendo che il generatore di numeri casuali sia vero casuale e non pseudo casuale.

Questo è code-golf. Vince il codice più breve (conteggiato in byte ).

Esempi di output:

Chiamare lo script / funzione 3 volte dovrebbe stampare / restituire qualcosa del tipo:

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

Se separi le mosse di uno spazio ciascuna:

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'

Si noti che tutte queste uscite sono composte da 25 mosse, ma hanno lunghezze diverse, a causa dei suffissi opzionali. Non è consentito stampare uno spazio, quando uno 2o entrambi 'sono usati come suffisso. Devi stampare L2UR2F'R'U2o L2 U R2 F' R' U2. L2U R2F'R'U2non è permesso.


Intendi dire UR 2non è permesso? U R2 dovrebbe essere consentito, credo, poiché gli spazi tra le mosse hanno un senso.
mbomb007,

@ mbomb007 Intendo cose come L2U R2F'R'U2. Unon ha suffisso opzionale e quindi non dovrebbe avere uno spazio. Uno spazio non dovrebbe essere una sostituzione per il suffisso opzionale.
Jakube

E se ci fossero spazi tra ogni mossa? Potremmo produrre U F2 L D2 R'..., per esempio? In questo caso, non c'è spazio extra , che secondo me dovrebbe andare bene secondo la tua regola.
mbomb007,

@ mbomb007 Sì, lo inserirò nella descrizione.
Jakube

Il 2 non è prima della lettera? oO
Oliver Ni

Risposte:


6

CJam, 47 45 byte

Questa soluzione utilizza un approccio diverso da qualsiasi altro pubblicato finora. Sfrutta le operazioni concise dell'elenco di CJam per generare l'elenco di spostamenti disponibili e selezionarne uno a caso per ogni iteraton. I modificatori vengono semplicemente generati in modo indipendente.

Provalo online.

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

Spiegazione

{               "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

C, 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;}}

Il loop interno genera un valore mnell'intervallo 1..5che, se aggiunto se preso nel modulo 6, assicura che non vi siano due mosse consecutive sullo stesso lato del cubo. Il vecchio valore di mè archiviato ne il test m*n==9assicura che il valore m= 3 non sia mai generato due volte di seguito (quindi le facce opposte non possono essere raccolte due volte di fila; notare l'ordine delle facce nella stringa).

La parte meno significativa rè utilizzato per decidere quale suffisso ( ', 2o nullo) uso, approfittando del carattere nullo alla fine "'2".

L'anello esterno viene eseguito 26 volte. La prima volta, Unon può mai essere scelto, quindi printfviene soppresso per la prima iterazione.

Codice non registrato nel programma di test

Il codice non golfizzato mette uno spazio tra ogni mossa per chiarezza (il codice golfed non lo fa, al fine di salvare un byte.) Inoltre il codice golfed salva un punto e virgola riposizionando printfall'interno della forparentesi.

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("");
}

Uscita tipica

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

Non ho mai giocato a golf su Pyth, forse ho scritto un programma o due. Questa è sostanzialmente la soluzione di @ steveverrill tradotta in Pyth. Suggerimenti di miglioramento sono i benvenuti.

Aggiornamento: aggiunto 1 byte per iniziare anche lo scramble U. Forse la soluzione C si basa su comportamenti indefiniti per farlo funzionare ...

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

Credo che questo dovrebbe essere fatto con meno incarichi, ma ciò richiederebbe di modificare molto l'algoritmo. (Beh, potrebbe provare.)

Ecco una spiegazione basata sul codice C:

=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 ""

Cambia le variabili Ye Z. Zè preinizializzato con 0, quindi si salvano i primi 3 caratteri.
Jakube

@Jakube Ma poi devo impostare n = m(terza riga di spiegazione), che deve significare n = 0la prima volta, che a sua volta richiederebbe Yessere 0.
PurkkaKoodari

Yè preinizializzato con un elenco vuoto []. E non credo che il valore delle ncose nella prima iterazione.
Jakube

A proposito, il tuo codice non produce scrambles che iniziano con U.
Jakube

@Jakube grazie, risolto.
PurkkaKoodari,

4

JavaScript (ES6) 175 178 204

Modifica 3 byte in meno, 1 modificando il codice e 2 modificando il modo in cui vengono contati i byte (senza contare F=)

Il codice per evitare ripetizioni è preso da @stevemiller. Il suo modo di gestire i gruppi di lettere è ancora migliore, ma non ho intenzione di rubarlo.

Bonus: puoi facoltativamente specificare il numero di mosse.

(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

Meno golf

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

Test

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

2

Java 8, 189 183 byte

v->{for(int i=26,n,m=0,r=0,s=0,t;i-->0;){for(n=m,t=1;t>0;t=m*n==9?1:0)m=(r=(int)(Math.random()*15))/3+1;s+=m;if(i<25)System.out.print("URFDLB".charAt(s%6)+(r%3<1?"'":r%3<2?"2":""));}}

Porta della risposta C di @LevelRiverSt . Ho provato alcune cose da solo, ma questo è stato più breve di quello che avevo ..

Provalo online.



1

Clojure, 223 byte

(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])))))

Questo si basa fortemente sul modello "sequenza -> partizione per -> filtro -> concat", viene utilizzato per filtrare sequenze "illegali" di facce. Questo seq viene quindi mappato su stringa insieme a un postfix casuale (inclusa la stringa vuota).

Punto di partenza non golfato:

(->> (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))
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.