Inverter o algoritmo do cubo de Rubik

19

Sempre que você faz um movimento no Cubo de Rubik, há um movimento inverso que desfaz o primeiro movimento. Por esse motivo, todo algoritmo (conjunto de movimentos) possui um algoritmo reverso que desfaz o primeiro algoritmo.

O objetivo deste desafio é encontrar o inverso de um determinado algoritmo.

Especificação:

A entrada consiste em uma matriz de movimentos individuais. Cada movimento é uma sequência de comprimento 1 ou 2. É claro que você pode usar qualquer formato de entrada que faça mais sentido no seu idioma. Cada movimento consiste na estrutura Xou X'ou X2, onde Xé uma letra maiúscula ou minúscula.

Para reverter X, basta substituí-lo por X'. Da mesma forma, X'torna-se X. X2por outro lado, não é alterado.

Para criar a saída, inverta cada movimento e, em seguida, inverta a matriz.

Exemplos (cadeias separadas por espaços):

R => R'

D U' => U D'

S T A C K => K' C' A' T' S'

A2 B2 => B2 A2

Pontuação:

Isso é código-golfe, então a menor quantidade de bytes ganha. Não são permitidas brechas padrão.

Julian Lachniet
fonte
É R2-> R2'ou B-> B3permitido?
CalculatorFeline
2
Ter que lidar X3ou X1teria sido uma boa adição ao desafio.
Shaggy
11
"Por causa disso, todo algoritmo (conjunto de movimentos) tem um algoritmo reverso que desfaz o primeiro algoritmo" isso é verdade para todos os algoritmos? Porque eu acho que os algoritmos de hash são de sentido único. Significa que ele não possui algoritmos reversos, certo? por favor me avise
Avishek Saha
4
@AvishekSaha: Para problemas do Cubo de Rubik, "algoritmo" é restrito ao significado "uma sequência de movimentos que você pode fazer no Cubo". Nesse sentido, não existe um algoritmo de hash unidirecional no cubo.
Ross Presser 07/07
5
Deveria ter tido D2R2como um caso de teste ...
Neil

Respostas:

7

Python 2 , 71 57 54 53 bytes

-15 bytes graças a ovs! -3 bytes graças a Rod.

lambda l:[i.strip("'")+" '"[len(i):]for i in l[::-1]]

Experimente online!

E / S de sequência, 70 bytes

lambda s:' '.join(i.strip("'")+"'"*(len(i)<2)for i in s.split()[::-1])

Experimente online!

totalmente humano
fonte
11
53 bytes
ovs 6/07/07
7

V , 13 10 bytes

æGÇä/á'Ó''

Experimente online!

3 bytes salvos graças a @nmjmcman apontando meu recurso favorito. Explicação:

æG          " Revere the order of every line
  Ç         " On every line not containing...
   ä/       " a digit:
     á'     "   Append an '
       Ó    "   Remove every instance on this line
        ''  "     Of two single quotes
DJMcMayhem
fonte
Like ärepresenta um regex quando compilado no vim?
Downgoat
@Downgoat Yes! Faz. Traduzida no vim, esta solução é :g!/\d/norm A'<CR>:%s/''//g<CR>gg:g/^/m0<CR>Mais informações sobre como o V comprime expressões regulares podem ser encontradas aqui
DJMcMayhem
@DJMcMayhem Não há finais implícitos como o seu recurso favorito? Experimente online!
precisa saber é o seguinte
3
Sei que é tarde demais, mas isso não funciona para mim. Transforma um R2 em um 2R, o que não é válido
Jamie Sanborn
7

Retina 0.8.2 , 27 26 bytes

\w
$&'
''

'2'
2
O$^`.'?2?

Experimente online! O link inclui casos de teste. Explicação: O primeiro estágio adiciona um apóstrofo após cada alfanumérico. Isso resulta em apóstrofos duplos (com ou sem um 2 inclusivo) que precisam ser removidos. A etapa final reverte os movimentos.

Neil
fonte
Isso poderia ser melhorado com o lançamento do Retina 1.0 ?
MD XF
@MDXF Parece que O$^é na verdade ainda a melhor maneira de reverter uma lista de partidas, então a contagem de bytes é realmente inalterada na Retina 1.
Neil
5

JavaScript (ES6), 45 bytes

s=>s.map(([a,b])=>b?+b?a+b:a:a+"'").reverse()

A solução mais curta é usar o Array IO. Uso simples e apropriado da destruição de argumentos.

A saída da string é de +8 bytes para .join` `.

Entrada de sequência, saída de matriz: 69 bytes

(s,k=[])=>s.replace(/\S\S?/g,([a,b])=>k.unshift(b?+b?a+b:a:a+"'"))&&k

f=

(s,k=[])=>s.replace(/\S\S?/g,([a,b])=>k.unshift(b?+b?a+b:a:a+"'"))&&k

;

console.log(["R", "D U'", "S T A C K", "A2 B2"].map(e => `${e} => ${f(e)}`));
<textarea oninput="out.value=(f(this.value)||[]).join` `" placeholder="input here"></textarea>
<textarea id="out" readonly></textarea>

Conor O'Brien
fonte
Agradável. Por que nunca penso em desestruturar parâmetros de função ?! :(
Salsicha
Você deve ser capaz de substituir .reverse()com ::reverseeconomia de 1 byte mas fazendo ES7
Downgoat
@Downgoat Algum lugar onde eu possa testar o ES7?
Conor O'Brien
@ ConorO'Brien você pode usar babel REPL on-line (carrapato executar e todas as caixas pré-definidos para toda a característica): babeljs.io/repl
Downgoat
4

Gelatina , 11 bytes

ḟ;ċ?”'ḣ2µ€Ṛ

Um link monádico que retorna uma lista de listas de caracteres (uma "matriz" de "cadeias").

Experimente online! (O rodapé evita esmagar a saída, exibindo a lista dividida em espaços.)

Quão?

ḟ;ċ?”'ḣ2µ€Ṛ - Link: list of lists of characters             e.g. ["F'", "D2" , "R"]
        µ€  - perform the chain to the left for €ach turn instruction:
    ”'      -   literal "'" character
   ?        -   if:
  ċ         -     count (number of "'" in the instruction) i.e.:  1   , 0    , 0
ḟ           -   then: filter out                                  "F"
 ;          -   else: concatenate                                       "D2'", "R'"
      ḣ2    -   head to index 2                                   "F" , "D2" , "R'"
          Ṛ - reverse                                            ["R'", "D2" , "F"]
Jonathan Allan
fonte
10 bytes com o novo Jelly.
usar o seguinte comando
4

JavaScript (ES6), 46 bytes

Recebe entrada como uma matriz de movimentos.

a=>a.map(m=>m[1]?+m[1]?m:m[0]:m+"'").reverse()

Teste-o

Digite uma lista de movimentos separados por vírgula.

o.innerText=(f=
a=>a.map(m=>m[1]?+m[1]?m:m[0]:m+"'").reverse()
)((i.value="S,T,A,C,K").split`,`);oninput=_=>o.innerText=f(i.value.split`,`)
<input id=i><pre id=o>


Explicação

a=>

Função anônima tomando a matriz de movimentos como argumento via parâmetro a.

a.map(m=>                       )

Mapeie a matriz, passando cada string por uma função, onde mestá a string atual.

 m[1]?

Verifique se a sequência contém um segundo segundo caractere ( "'"ou "2").

+m[1]?

Se tentar converter essa cadeia de caracteres em um número inteiro. Se a string é "2", ela se torna 2verdadeira. Se a corda é "'", ela se torna NaN, o que é falsey.

m

Se o teste anterior for verdadeiro, basta retornar m.

:m[0]

Caso contrário, retorne o primeiro caractere de m.

:m+"'"

Se a sequência não contiver um segundo caractere, retorne manexado com a '.

.reverse()

Inverta a matriz modificada.

Shaggy
fonte
Desculpe, acabei de ver isso. Minha própria resposta é semelhante ao seu: P
Conor O'Brien
2

Python ,  51  48 bytes

lambda a:[(v+"'")[:2-("'"in v)]for v in a[::-1]]

Uma função sem nome, recebendo e retornando listas de strings.

Experimente online!

Inverte a lista de entrada com a[::-1]; anexa a 'a cada entrada com v+"'"; chefia cada um com 1 ou 2 caracteres, dependendo do original ter 'ou não um [:2-("'"in v)].

Jonathan Allan
fonte
2

Python 3 , 91 89 72 70 69 65 bytes

lambda s:[i[0]+(len(i)-2and"'"or"2"*("2"==i[1]))for i in s[::-1]]

Experimente online! (Com caixas de teste)

Aparentemente, você não precisa receber entrada e saída como seqüências de caracteres, portanto, é possível uma solução de 69 bytes

sagiksp
fonte
AFAIK você pode excluir o espaço depoislen(i)==1
Stephen
@StepHen Huh, não sabia que era permitido (sabia que alguns intérpretes permitiu, só não sabia o que é permitido em codegolf)
sagiksp
2
Os idiomas são definidos por seus intérpretes aqui; portanto, se funcionar em qualquer intérprete, é válido.
Shaggy
Se o intérprete permitir, você poderá fazê-lo. Isso é tudo que o código-golfe se preocupa;)
Stephen
len(i)-2é menor do que len(i)==1(lembre-0 é Falsey)
Stephen
1

Haskell , 43 bytes

map f.reverse
f[x]=x:"'"
f[x,c]=x:[c|c>'1']

Experimente online! Declara uma função anônima map f.reverse. Vincule ge use como g["S","T","A","C","K"].

Laikoni
fonte
1

PHP , 81 bytes

<?foreach(array_reverse($_GET)as$v)$r[]=$v[1]?$v[1]<2?$v[0]:$v:"$v'";print_r($r);

Experimente online!

Jörg Hülsermann
fonte
1

05AB1E , 13 bytes

RεÐ1èQ''si«ëK

Experimente online!

Explicação

RεÐ1èQ''si«ëK
R             # Reverse input array
 ε            # Map over each element...
  Ð1èQ         # Is the second char in the element the first one? (Uses the fact that in python indexing loops)
      ''       # Push '
        s      # Swap top items of stack
         i     # If the question above is true...
          «     # Concatenate
           ë   # Else
            K   # Push element without '  
Datboi
fonte
1

J, 25 bytes

J lida bem com isso, além da infeliz sequência de escape necessária para representar uma única citação:

|.,&''''`}:@.(''''={:)&.>

Precisamos representar a lista usando dados em caixa, pois é uma mistura de itens de um e dois caracteres, portanto:

  • &.> - "em desmarcar", que significa desmarcar cada elemento, execute a operação a seguir (ou seja, os símbolos explicados abaixo) e, em seguida, reencaixe quando terminar
  • (''''={:) "se o segundo caractere for uma aspas simples" ....
  • @. (O verbo da agenda de J, um tipo de declaração ternária generalizada ou uma declaração de caso) "execute o segundo item na lista da agenda, caso contrário, execute o primeiro"
  • }: (o segundo item da lista da agenda), "remova o último caractere", ou seja, as aspas simples
  • `(Verbo de ligação de J) Você pode pensar nisso como o separador de itens da agenda
  • ,&'''' (primeiro item da lista da agenda) "adicione uma única citação ao final"
  • |. "marcha ré"

Experimente online!

Jonah
fonte
0

Ruby , 44 bytes

->a{a.reverse.map{|i|i[1]?i.tr(?',''):i+?'}}

Experimente online!

Asone Tuhid
fonte
0

Java 8, 141 128 126 bytes

a->new StringBuffer(a.replaceAll("(.)","$1'").replace("'''","").replaceAll("(.)'","'$1").replaceAll("'(.)'2","2$1")).reverse()

Recebe a entrada como única, Stringsem espaços (ie RUR'URU2R'U).

Explicação:

Experimente online.

a->new StringBuffer(           // Method with String parameter and StringBuffer return-type
  a.replaceAll("(.)","$1'")    //1  Add an apostrophe after every character
   .replace("'''","")          //2  Remove all occurrences of three adjacent apostrophes
   .replaceAll("(.)'","'$1")   //3  Reverse letter+apostrophe to apostrophe+letter
   .replaceAll("'(.)'2","2$1") //4  Reverse letter+2 to 2+letter and remove aphostrophes
  ).reverse()                  //5 Reverse everything

Exemplo das etapas acima, com as seguintes entradas: RUR'URU2R'U

  1. RUR'URU2R'UR'U'R'''U'R'U'2'R'''U'
  2. R'U'R'''U'R'U'2'R'''U'R'U'RU'R'U'2'RU'
  3. R'U'RU'R'U'2'RU''R'UR'U'R'U'2R'U
  4. 'R'UR'U'R'U'2R'U'R'UR'U'R2UR'U
  5. 'R'UR'U'R2UR'UU'RU2R'U'RU'R'
Kevin Cruijssen
fonte