Rubik's Cube Scrambles


21

Sua tarefa é criar uma sequência aleatória de movimentos, que pode ser usada para embaralhar um cubo de Rubik. Essa disputa é composta de exatamente 25 movimentos. Cada movimento consiste nas letras UDRLFBseguidas opcionalmente por um dos sufixos '2.

Essa notação é chamada de notação Singmaster. UDRLFBrepresenta uma das 6 faces e o sufixo opcional '2representa o ângulo de viragem. Esta informação não é necessária para resolver a tarefa.

Para garantir que as disputas sejam de 'boa qualidade', as duas regras a seguir devem ser aplicadas:

  • Dois movimentos consecutivos não devem ter a mesma letra. Esta proíbe os lances consecutivos UU, DD, RR, LL, FFe BBe todas as suas combinações usando os sufixos opcionais como U2Uou U'U'.

    Esses pares de movimentos são banidos porque podem ser facilmente reduzidos a 1 ou 0 movimentos. U2Utem o mesmo efeito que U', R'Ro mesmo efeito que .

  • Três jogadas consecutivas não devem ser do mesmo grupo de letras. Os grupos de letras são UD, RLe FB. Esta regra também proíbe os lances consecutivos UDU, DUD, RLR, LRL, FBF, BFBe todas as suas combinações usando os sufixos opcionais como U2DU, RL'Rou B2FB'.

    Os grupos classificam as faces pelo seu eixo de movimento. Ue Destão no mesmo grupo, porque ambos giram em torno do mesmo eixo. Portanto, um Umovimento não influencia os pedaços do Drosto, e um Dmovimento não influencia os pedaços do Urosto. Portanto, os dois movimentos podem ser trocados, UDUtêm o mesmo efeito que UUD, e isso pode ser reduzido para U2D.

Desafio

Escreva um script ou uma função que gere uma disputa aleatória. Não há entrada. O script / função deve imprimir os 25 movimentos sem separação ou separados por um espaço ou retornar a sequência correspondente.

Seu programa deve ser capaz de criar todos os embaralhamento, o que satisfaz as regras acima. Obviamente, assumindo que o gerador de números aleatórios é verdadeiro aleatório, e não pseudo-aleatório.

Isso é código-golfe. O código mais curto (contado em bytes ) vence.

Exemplos de saídas:

Chamar o script / função 3 vezes deve imprimir / retornar algo como:

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 você separar os movimentos por um espaço cada:

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'

Observe que todas essas saídas consistem em 25 movimentos, mas têm comprimentos diferentes, devido aos sufixos opcionais. Não é permitido imprimir um espaço, quando um 2ou 'é usado como sufixo. Você tem que imprimir L2UR2F'R'U2ou L2 U R2 F' R' U2. L2U R2F'R'U2não é permitido.


Você quis dizer que UR 2não é permitido? U R2 deve ser permitido, acho, já que os espaços entre os movimentos fazem sentido.
mbomb007

@ mbomb007 Quero dizer coisas como L2U R2F'R'U2. Unão possui sufixo opcional e, portanto, não deve ter espaço. Um espaço não deve substituir o sufixo opcional.
Jakube 5/03

E se houver espaços entre cada movimento? Poderíamos produzir U F2 L D2 R'..., por exemplo? Nesse caso, não há um espaço extra , que eu acho que deveria ficar bem de acordo com sua regra.
mbomb007

@ mbomb007 Sim, vou colocá-lo na descrição.
Jakube 5/03

Não é o 2 antes da carta? oO
Oliver Ni

Respostas:


6

CJam, 47 45 bytes

Esta solução usa uma abordagem diferente de qualquer outra postada até agora. Ele tira proveito das operações de lista concisa do CJam para gerar a lista de movimentação disponível e selecionar uma aleatoriamente a cada iteração. Modificadores são simplesmente gerados de forma independente.

Experimente online.

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

Explicação

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

O loop interno gera um valor mdentro da faixa 1..5que, quando adicionado se obtido no módulo 6, garante que não haja dois movimentos consecutivos no mesmo lado do cubo. O valor antigo de mé armazenado ne o teste m*n==9garante que o valor m= 3 nunca seja gerado duas vezes em uma linha (portanto, faces opostas não podem ser selecionadas duas vezes em uma linha; observe a ordem das faces na sequência).

A parte significativa de menos ré utilizado para decidir que sufixo ( ', 2ou nulo) para utilização, aproveitando o carácter nulo no final da "'2".

O loop externo é executado 26 vezes. A primeira vez, Ununca pode ser selecionada, printfsendo suprimida na primeira iteração.

Código não jogado no programa de teste

O código não golfado coloca um espaço entre cada movimentação para maior clareza (o código golfado não salva, a fim de salvar um byte.) Além disso, o código golfado economiza um ponto-e-vírgula realocando o printfdentro do forcolchete.

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

Saída típica

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.

Eu nunca realmente joguei golfe em Pyth, talvez tenha escrito um ou dois programas. Esta é basicamente a solução do @ steveverrill traduzida para Pyth. Sugestões de melhoria são bem-vindas.

Atualização: adicionado 1 byte para começar a embaralhar U. Talvez a solução C esteja confiando em um comportamento indefinido para fazê-lo funcionar ...

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

Acredito que isso deva ser feito com menos atribuições, mas isso exigiria que eu modificasse bastante o algoritmo. (Bem, pode tentar.)

Aqui está uma explicação baseada no código 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 ""

Alterne as variáveis Ye Z. Zé pré-inicializado com 0, para salvar os 3 primeiros caracteres.
Jakube 6/03/15

@Jakube Mas então eu preciso set n = m(3ª linha explicação), o que deve significar n = 0a primeira vez, que por sua vez exigiria Ya ser 0.
PurkkaKoodari

Yé pré-inicializado com uma lista vazia []. E eu não acho que o valor nimporta na primeira iteração.
Jakube 6/03

Btw, seu código não produz misturas que começam com U.
Jakube 6/03

@Jakube obrigado, corrigido.
PurkkaKoodari

4

JavaScript (ES6) 175 178204

Edite 3 bytes a menos, 1 alterando o código e 2 alterando a maneira como os bytes são contados (sem contar F=)

O código para evitar repetições é retirado de @stevemiller. Sua maneira de gerenciar os grupos de cartas é ainda melhor, mas não vou roubá-la.

Bônus: você pode opcionalmente especificar o número de movimentos.

(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

Menos golfe

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

Teste

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

Porta da resposta C de @LevelRiverSt . Eu tentei algumas coisas sozinho, mas isso foi mais curto do que o que eu tinha ..

Experimente online.



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

Isso depende muito do padrão "sequência -> partição por -> filtro -> concat"; é usado para filtrar sequências "ilegais" de faces. Esse seq é então mapeado para string junto com um postfix aleatório (incluindo a string vazia).

Ponto de partida não destruído:

(->> (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))
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.