Kostka Rubika

21

Twoim zadaniem jest stworzenie losowej sekwencji ruchów, których można użyć do szyfrowania Kostki Rubika. Taka walka składa się z dokładnie 25 ruchów. Każdy ruch składa się z liter, UDRLFBpo których opcjonalnie następuje jeden z przyrostków '2.

Notacja ta nazywa się notacją Singmaster. UDRLFBreprezentuje jedną z 6 ścian, a opcjonalny przyrostek '2reprezentuje kąt obrotu. Informacje te nie są w żaden sposób konieczne do rozwiązania zadania.

Aby zapewnić, że jajecznice są „dobrej jakości”, muszą mieć zastosowanie następujące dwie zasady:

  • Dwa kolejne ruchy nie mogą mieć tej samej litery. Ta zakazuje kolejne ruchy UU, DD, RR, LL, FFi BBoraz wszelkie ich kombinacje przy użyciu opcjonalnego przyrostków jak U2Ualbo U'U'.

    Te pary ruchów są zbanowane, ponieważ można je łatwo zredukować do 1 lub 0 ruchów. U2Uma taki sam efekt jak U', R'Rtaki sam efekt jak .

  • Trzy kolejne ruchy nie mogą należeć do tej samej grupy liter. Grupy nas są UD, RLi FB. Zasada ta zakazuje dodatkowo kolejne ruchy UDU, DUD, RLR, LRL, FBF, BFBi wszystkie ich kombinacje przy użyciu opcjonalnego przyrostków jak U2DU, RL'Rlub B2FB'.

    Grupy sortują twarze według osi ruchu. Ui Dnależą do tej samej grupy, ponieważ oba obracają się wokół tej samej osi. Dlatego Uruch nie wpływa na części Dtwarzy, a Druch nie wpływa na części Utwarzy. Dlatego te dwa ruchy mogą być wymieniane, UDUma taki sam efekt jak UUDi można to zredukować do U2D.

Wyzwanie

Napisz skrypt lub funkcję, która generuje jedną losową mieszankę. Brak danych wejściowych. Skrypt / funkcja musi wydrukować 25 ruchów bez separacji lub oddzielonych jedną spacją lub zwrócić odpowiedni ciąg.

Twój program musi być w stanie utworzyć każdą pojedynczą mieszankę, która spełnia powyższe zasady. Oczywiście zakładając, że generator liczb losowych jest prawdziwy losowy, a nie pseudolosowy.

To jest golf golfowy. Najkrótszy kod (liczony w bajtach ) wygrywa.

Przykłady wyników:

Wywołanie skryptu / funkcji 3 razy powinno wydrukować / zwrócić coś takiego:

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

Jeśli oddzielisz ruchy spacjami, każdy:

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'

Zauważ, że wszystkie te dane wyjściowe składają się z 25 ruchów, ale mają różne długości, ze względu na opcjonalne sufiksy. Nie wolno drukować spację, kiedy albo 2czy 'są zastosowania jako przyrostek. Musisz wydrukować L2UR2F'R'U2lub L2 U R2 F' R' U2. L2U R2F'R'U2nie jest dozwolone.

Jakube
źródło
Czy miałeś na myśli, że UR 2nie jest dozwolone? Myślę, że U R2 powinno być dozwolone, ponieważ odstępy między ruchami mają sens.
mbomb007
@ mbomb007 Mam na myśli rzeczy takie jak L2U R2F'R'U2. Unie ma opcjonalnego sufiksu i dlatego nie powinien mieć spacji. Spacja nie powinna zastępować opcjonalnego sufiksu.
Jakube,
Co zrobić, jeśli między każdym ruchem są odstępy? Czy moglibyśmy U F2 L D2 R'...na przykład generować dane ? W tym przypadku nie ma dodatkowej przestrzeni, która moim zdaniem powinna być w porządku.
mbomb007
@ mbomb007 Tak, umieszczę to w opisie.
Jakube,
Czy 2 nie jest przed listem? oO
Oliver Ni

Odpowiedzi:

6

CJam, 47 45 bajtów

W tym rozwiązaniu zastosowano inne podejście niż jakikolwiek inny opublikowany do tej pory. Wykorzystuje zwięzłe operacje listy CJam, aby wygenerować dostępną listę ruchów i wybrać jedną losowo każdą iteraton. Modyfikatory są po prostu generowane niezależnie.

Wypróbuj online.

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

Wyjaśnienie

{               "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";
Runer112
źródło
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;}}

Wewnętrzna pętla generuje wartość z mzakresu, 1..5który po dodaniu do si wzięciu modułu 6 zapewnia, że ​​żadne dwa kolejne ruchy nie będą wykonywane po tej samej stronie sześcianu. Stara wartość parametru mjest przechowywana, na test m*n==9zapewnia, że ​​wartość m= 3 nigdy nie jest generowana dwa razy z rzędu (więc przeciwnych ścian nie można wybrać dwa razy z rzędu; zwróć uwagę na kolejność ścian w ciągu).

Najmniej znaczna część rjest wykorzystywany do określenia, która sufiksu ( ', 2lub null) do wykorzystania, wykorzystując w postaci pustego w końcu "'2".

Zewnętrzna pętla działa 26 razy. Za pierwszym razem Unie można go wybrać, więc printfjest pomijany przy pierwszej iteracji.

Nieskluczony kod w programie testowym

Niegolfowany kod umieszcza odstęp między każdym ruchem dla zachowania przejrzystości (kod golfowy nie, aby zaoszczędzić jeden bajt.) Dodatkowo kod golfowy oszczędza średnik poprzez przeniesienie printfwewnątrz forprzedziału.

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

Typowa wydajność

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
Level River St
źródło
124 bajty
MD XF,
118 bajtów
ceilingcat
4

Pyth 65 66

Nigdy tak naprawdę nie grałem w golfa w Pyth, może napisałem program lub dwa. Jest to w zasadzie rozwiązanie @ steveverrill przetłumaczone na Pyth. Sugestie dotyczące ulepszeń są mile widziane.

Aktualizacja: dodano 1 bajt, aby zaczynał się również kodowanie U. Być może rozwiązanie C polega na niezdefiniowanym zachowaniu, aby działało ...

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

Uważam, że należy to zrobić przy mniejszej liczbie zadań, ale wymagałoby to ode mnie dużej modyfikacji algorytmu. (Cóż, może spróbować.)

Oto wyjaśnienie oparte na kodzie 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 ""
PurkkaKoodari
źródło
Przełącz zmienne Yi Z. Zjest wstępnie zainicjowany na 0, więc zapisujesz pierwsze 3 znaki.
Jakube,
@Jakube Ale potem muszę ustawić n = m(trzecia linia wyjaśnień), co musi oznaczać n = 0pierwszy raz, co z kolei wymagałoby wartości Y0.
PurkkaKoodari
Yjest wstępnie zainicjowany z pustą listą []. I nie sądzę, aby wartość nspraw w pierwszej iteracji.
Jakube,
Przy okazji, twój kod nie produkuje szyfrowania, które zaczyna się od U.
Jakube,
@Jakube dzięki, naprawiono.
PurkkaKoodari
4

JavaScript (ES6) 175 178 204

Edytuj 3 bajty mniej, 1 zmieniając kod i 2 zmieniając sposób liczenia bajtów (nie licząc F=)

Kod pozwalający uniknąć powtórzeń pochodzi z @stevemiller. Jego sposób zarządzania grupami listów jest jeszcze lepszy, ale nie zamierzam go ukraść.

Premia: możesz opcjonalnie określić liczbę ruchów.

(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

Mniej golfa

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

edc65
źródło
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
Mama Fun Roll
źródło
2

Java 8, 189 183 bajtów

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 odpowiedzi C @LevelRiverSt . Sam próbowałem pewnych rzeczy, ale to było krótsze niż to, co miałem ...

Wypróbuj online.

Kevin Cruijssen
źródło
2

Rubin , 116 107 105 95 bajtów

->{(0..r=l=m=24).map{m=rand 6while l==m||r/2==l/2&&l/2==m/2;r=l;l=m;'RLFBUD'[m]+" '2"[rand 3]}}

Wypróbuj online!

Asone Tuhid
źródło
1

Clojure, 223 bajty

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

Zależy to w dużej mierze od wzoru „sekwencja -> podział według -> filtr -> konkat”, służy do filtrowania „nielegalnych” sekwencji twarzy. Sekwencja ta jest następnie mapowana na ciąg wraz z losowym postfiksem (w tym pusty ciąg).

Punkt wyjściowy bez golfa:

(->> (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))
NikoNyrh
źródło