Rubik's Cube Scrambles


21

Ihre Aufgabe ist es, eine zufällige Abfolge von Zügen zu erstellen, mit denen Sie einen Rubik's Cube verschlüsseln können. Ein solches Scramble besteht aus genau 25 Zügen. Jeder Zug besteht aus den Buchstaben, UDRLFBoptional gefolgt von einem der Suffixe '2.

Diese Notation wird als Singmaster-Notation bezeichnet. UDRLFBStellt eine der 6 Flächen dar und das optionale Suffix gibt '2den Drehwinkel an. Diese Informationen sind in keiner Weise zur Lösung der Aufgabe erforderlich.

Um sicherzustellen, dass die Scrambles von "guter Qualität" sind, müssen die folgenden zwei Regeln gelten:

  • Zwei aufeinanderfolgende Züge dürfen nicht denselben Buchstaben haben. Dies verbietet die aufeinanderfolgenden bewegt UU, DD, RR, LL, FFund BBund alle Kombinationen der optionalen Suffixe verwenden , wie U2Uoder U'U'.

    Diese Zugpaare sind gesperrt, da sie leicht auf 1 oder 0 Züge reduziert werden können. U2Uhat den gleichen Effekt wie U', R'Rden gleichen Effekt wie .

  • Drei aufeinanderfolgende Züge dürfen nicht derselben Buchstabengruppe angehören. Die Buchstabengruppen sind UD, RLund FB. Diese Regel zusätzlich verbietet die aufeinanderfolgenden bewegt UDU, DUD, RLR, LRL, FBF, BFBund alle Kombinationen der optionalen Suffixe wie unter Verwendung von U2DU, RL'Roder B2FB'.

    Die Gruppen sortieren die Gesichter nach ihrer Bewegungsachse. Uund Dbefinden sich in derselben Gruppe, da sich beide um dieselbe Achse drehen. Daher beeinflusst eine UBewegung nicht die Teile des DGesichts und eine DBewegung beeinflusst nicht die Teile des UGesichts. Daher können die beiden Züge getauscht werden, UDUhat den gleichen Effekt wie UUD, und dieser kann auf reduziert werden U2D.

Herausforderung

Schreiben Sie ein Skript oder eine Funktion, die ein zufälliges Scramble generiert. Es erfolgt keine Eingabe. Das Skript / die Funktion muss die 25 Züge ohne Trennung oder durch ein Leerzeichen getrennt drucken oder die entsprechende Zeichenfolge zurückgeben.

Ihr Programm muss in der Lage sein, jedes einzelne Scramble zu erstellen, das die oben genannten Regeln erfüllt. Natürlich unter der Annahme, dass der Zufallszahlengenerator ein wahrer Zufall und kein Pseudozufall ist.

Das ist Code-Golf. Der kürzeste Code (in Bytes gezählt ) gewinnt.

Beispiele für Ausgaben:

Wenn Sie das Skript / die Funktion dreimal aufrufen, sollte Folgendes gedruckt / zurückgegeben werden:

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

Wenn Sie die Züge jeweils durch ein Leerzeichen trennen:

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'

Beachten Sie, dass alle diese Ausgaben aus 25 Zügen bestehen, aber aufgrund der optionalen Suffixe unterschiedliche Längen haben. Es ist nicht erlaubt, ein Leerzeichen zu drucken, wenn entweder 2oder 'als Suffix verwendet werden. Sie müssen L2UR2F'R'U2oder drucken L2 U R2 F' R' U2. L2U R2F'R'U2ist nicht erlaubt.


Meinten Sie UR 2ist nicht erlaubt? U R2 sollte erlaubt sein, denke ich, da abstände zwischen zügen sinnvoll sind.
mbomb007

@ mbomb007 Ich meine Sachen wie L2U R2F'R'U2. Uhat kein optionales Suffix und sollte daher kein Leerzeichen enthalten. Ein Leerzeichen darf kein Ersatz für das optionale Suffix sein.
Jakube,

Was ist, wenn zwischen jeder Bewegung Leerzeichen sind? Könnten wir U F2 L D2 R'...zum Beispiel ausgeben ? In diesem Fall gibt es kein zusätzliches Leerzeichen, was nach Ihrer Regel meiner Meinung nach in Ordnung sein sollte.
mbomb007

@ mbomb007 Ja, ich werde es in die Beschreibung aufnehmen.
Jakube,

Steht die 2 nicht vor dem Brief? oO
Oliver Ni

Antworten:


6

CJam, 47 45 Bytes

Diese Lösung verwendet einen Ansatz, der sich von allen bisher veröffentlichten unterscheidet. Es nutzt CJams prägnante Listenoperationen, um die verfügbare Verschiebungsliste zu generieren und bei jeder Iteration eine zufällige auszuwählen. Modifikatoren werden einfach unabhängig generiert.

Probieren Sie es online aus.

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

Erläuterung

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

Die innere Schleife erzeugt einen Wert min dem Bereich, 1..5der, wenn zu sModulo 6 addiert und genommen, sicherstellt, dass sich keine zwei aufeinander folgenden Züge auf derselben Seite des Würfels befinden. Der alte Wert von mwird in gespeichert nund der Test m*n==9stellt sicher, dass der Wert m= 3 niemals zweimal hintereinander generiert wird (daher können gegenüberliegende Flächen nicht zweimal hintereinander ausgewählt werden; beachten Sie die Reihenfolge der Flächen in der Zeichenfolge.)

Das niedrigstwertige Teil rverwendet wird , das Suffix zu entscheiden ( ', 2oder null) verwendet werden , am Ende der Vorteil der Null - Zeichen unter "'2".

Die äußere Schleife läuft 26 mal. Das erste Mal Ukann nie ausgewählt werden, wird also printffür die erste Iteration unterdrückt.

Ungolfed Code im Testprogramm

Der ungolfed Code fügt aus Gründen der Klarheit zwischen den einzelnen Zügen ein Leerzeichen ein (der golfed Code nicht, um ein Byte zu sparen.) Zusätzlich speichert der golfed Code ein Semikolon, indem er printfdie forKlammer umsetzt .

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

Typische Ausgabe

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

Ich habe noch nie richtig in Pyth Golf gespielt, vielleicht ein oder zwei Programme geschrieben. Dies ist im Grunde die in Pyth übersetzte Lösung von @ steveverrill. Verbesserungsvorschläge sind willkommen.

Update: 1 Byte hinzugefügt, damit auch die Verschlüsselung beginnt U. Vielleicht basiert die C-Lösung auf undefiniertem Verhalten, damit es funktioniert ...

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

Ich bin der Meinung, dass dies mit weniger Aufgaben erledigt werden sollte, aber dafür müsste ich den Algorithmus stark modifizieren. (Nun, könnte versuchen.)

Hier ist eine Erklärung basierend auf dem C-Code:

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

Wechseln Sie die Variablen Yund Z. Zwird mit 0 vorinitialisiert, so dass Sie die ersten 3 Zeichen speichern.
Jakube,

@Jakube Aber dann muss ich einstellen n = m(3. Erklärungszeile), was n = 0das erste Mal bedeuten muss , was wiederum Y0 sein
müsste

Ywird mit einer leeren Liste vorinitialisiert []. Und ich denke nicht, dass der Wert von nDingen in der ersten Iteration wichtig ist.
Jakube

Übrigens erzeugt Ihr Code keine Scrambles, die mit beginnen U.
Jakube

@ Jakube danke, behoben.
PurkkaKoodari

4

JavaScript (ES6) 175 178 204

3 Bytes weniger bearbeiten , 1 durch Ändern des Codes und 2 durch Ändern der Art und Weise, wie Bytes gezählt werden (nicht gezählt F=)

Der Code zur Vermeidung von Wiederholungen stammt von @stevemiller. Seine Art, die Briefgruppen zu verwalten, ist noch besser, aber ich werde es nicht stehlen.

Bonus: Sie können optional die Anzahl der Züge angeben.

(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

Weniger golfen

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

Prüfung

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 Bytes

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

Port der C-Antwort von @LevelRiverSt . Ich habe einige Dinge selbst ausprobiert, aber das war kürzer als das, was ich hatte.

Probieren Sie es online aus.



1

Clojure, 223 Bytes

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

Dies hängt stark von dem Muster "sequence -> partition-by -> filter -> concat" ab, mit dem "unzulässige" Folgen von Gesichtern herausgefiltert werden. Diese Sequenz wird dann zusammen mit einem zufälligen Postfix (einschließlich der leeren Zeichenfolge) einer Zeichenfolge zugeordnet.

Ungolfed Startpunkt:

(->> (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))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.