Um venerado tempo de passagem dos pedantes é apontar que as imagens dos "Cubos de Rubik" (em camisetas, pôsteres etc.) não são realmente solucionáveis.
A primeira coisa que deve ser verificada é que o cubo é composto pelas peças certas. Para ser solucionável, um cubo precisa de seis cores, cada uma com nove quadrados. O cubo também precisa que cada unidade de borda e canto (esses são os cubos menores que compõem o cubo) sejam exclusivos. Não apenas devem ser únicas, mas se duas peças centrais estiverem opostas, nenhuma aresta ou peça de canto pode conter ambas as cores.
Depois de ter um cubo composto de todas as peças certas, você ainda precisa verificar se ele pode ser solucionado. Existem algumas regras aqui, então vou recorrer a um especialista para explicá-las, o spoiler abaixo explica como podemos fazer isso. Se você estiver interessado em resolver o problema por conta própria, não precisará visitar o site para entender ou participar desse desafio.
Sua tarefa é pegar um padrão como entrada e determinar se é de fato um cubo de Rubik solucionável. Para ser solucionável, deve haver uma maneira de executar movimentos válidos em um cubo para que o cubo tenha apenas uma cor em cada face (e as diferentes faces tenham cores diferentes). A maioria dos cubos de Rubik tem uma cor padrão (branco é oposto a amarelo etc.). Você não pode assumir que o estado de resolução segue essa cor específica.
Um movimento válido é a rotação no sentido horário ou anti-horário de uma única face do cubo. Com a rotação da face do cubo, todos os quadrados adjacentes à face também são rotacionados, permanecendo conectados à face em que estavam tocando anteriormente.
IO
Você pode pegar o cubo de qualquer maneira razoável. Se seu idioma possui algum tipo de "face do cubo" embutido, bom para você, isso é bom como entrada; caso contrário, você pode pegar uma matriz 2D da rede, do cubo, 1 3 por 3 listas para cada face. Apenas seja razoável. Se você quiser saber se um formato específico é aceitável, faça um comentário ou envie um ping para mim no bate-papo, e eu adicionarei o desafio de declarar sua validade.
Seu formato de entrada precisa suportar apenas 9 cores possíveis.
Para saída, este é um problema de decisão, portanto, você deve gerar um valor constante para "Sim, este é um cubo de Rubik válido" e um valor constante diferente para "Não, este não é um cubo de Rubiks válido".
Isso é código-golfe, então as respostas serão pontuadas em bytes, com menos bytes sendo melhores.
Casos de teste
Aqui estão os casos de teste. Eles são formatados como a rede de um cubo com cada quadrado como uma única letra. Letras diferentes representam cores diferentes. Mais casos de teste podem ser adicionados mediante solicitação.
Solvable
RRR
RRR
RRR
GGGWWWBBBOOO
GGGWWWBBBOOO
GGGWWWBBBOOO
YYY
YYY
YYY
GRR
GRR
ORW
WWRBWYBOOGGY
GGRBWGYBBOOO
OOGRWGYWWRBB
WYO
YYB
YYB
Insolúvel
RRR
RRR
RRR
GGGWWWBBBOOO
GGGWWWBBBOOO
GGGWYWBBBOOO
YWY
YYY
YYY
RRR
RRR
RRR
GGGWWWBBBOOO
GGGWWWBBBOOO
GGGWWWBBBOOO
YWY
YYY
YYY
RRR
RRR
GGG
GGYWYWRBBOBO
GGYWWWROBOOO
GGYWWWRBBOOO
BBB
YWY
YYY
RRW
RRW
GGG
GGYWWYEOBROO
GGYWWYEBBROO
GGOWWYWBBROO
BBB
YYW
YYO
fonte
Respostas:
Cubicamente ,
166416311089 bytesSaída se solucionável:
Solved!
Saída se não solucionável:(vazio, sem saída)
A entrada deve ser formatada como um despejo de cubo cubicamente (consulte a
Debug
seção). Isso foi explicitamente permitido pelo OP.Explicação
Esse programa adota a abordagem de usar o algoritmo do diabo para iterar todos os estados possíveis do cubo no mesmo grupo que o cubo resolvido. Se o cubo for solucionável, ele será resolvido em algum momento antes da conclusão do algoritmo (assumindo que o algoritmo que eu usei funcione corretamente).
Toda linha que começa com
⇒
(0x84 na página de código do Cubically) é uma definição de função; essas funções são construídas uma para a outra para compor o algoritmo real do diabo. A primeira linha a ser executada é a última:r
lê um cubo de stdin e define o cubo de memória para ele.s
coloca o intérprete em "solvemode", o que significa que ele sai e é impressoSolved!
se o cubo for resolvido (após não ter sido resolvido) a qualquer momento. O restante dos comandos (que simplesmente se repetemf36f71
8 vezes) correspondem ao algoritmo final na parte inferior da página vinculada:Como posso executá-lo?
Você pode experimentá-lo online , mas esse link não funciona. O TIO atingirá o tempo limite quase definitivamente antes que esse algoritmo termine (o tempo de execução máximo para um intérprete é de 60 segundos). Se o cubo não puder ser solucionado, esse algoritmo levará até 11 milhões de anos para terminar o Cubically (com ~ 15,2 milhões de movimentos por segundo, que é o que o meu Cloud9 IDE obtém).
Além disso, você precisa de muita memória para executar três movimentos de sextilhões. Cubicamente pode executar cerca de 4 milhões de movimentos por segundo, mas o processo provavelmente será eliminado devido à memória supercomprometida . Ele morre após 15 segundos na minha VM com 512 MB de memória.Por que executar movimentos em uma matriz plana já alocada custa memória? Encontrou um vazamento de memória (ou vinte) e o corrigiu .Aqui está uma versão muito mais legível que se comporta da mesma maneira.
Mas eu realmente quero ver que funciona!
O primeiro movimento real que é executado no algoritmo desse diabo é
F2
, portanto, o cubo mais rápido de resolver seria um embaralhadoF2
:Isso realmente é executado em 0,007 segundos no TIO .
Como isso pode ser melhorado?
Certamente existem mais algoritmos do diabo; Eu encontrei um que usa menos de um trigésimo dos movimentos que este faz. No entanto, isso custaria vários milhares de bytes (cerca de 100 MB a mais) e várias dezenas de horas de conversão de um complexo circuito hamiltoniano em código cubicamente.
Também é possível remover algumas das funções e colocá-las diretamente no loop na parte inferior. No entanto, vou sacrificar alguns bytes por alguma legibilidade.
Além disso, estou considerando uma modificação do comportamento de loop do Cubically para que eu possa repetir mais facilmente os algoritmos 7 ou 8 vezes (em vez de apenas codificá-los com as chamadas de função repetidas 7 ou 8 vezes na fonte). Ou eu vou trabalhar um pouco de mágica com o bloco de notas, e jogar golfe usando mais loops.
Observe que continuarei a otimizar tudo o que for possível no intérprete; portanto, isso poderá funcionar em um PC comum em algum momento no futuro!
Cubicamente, 2 bytes
Eu gosto mais da resposta acima, então estou adicionando isso como uma solução alternativa. Isso ocorre em menos de um segundo, em oposição a alguns milhões de anos.
Saída se o cubo for solucionável: (nada)
Saída se o cubo for insolúvel:
Error: The cube has reached an unsolvable state.
fonte
APL (Dyalog Classic) ,
190174 bytesExperimente online!
O argumento é uma matriz 3x2 (linha0: frente para trás, linha1: esquerda direita, linha2: cima para baixo) de matrizes de caracteres 3x3. Retorna 1 para um cubo de Rubik solucionável, 0 caso contrário.
No link TIO, a função
t
, que não está incluída na contagem de caracteres, lê 9 linhas de entrada, as converte do formato de entrada padrão (uma rede) para a matriz 3x2 x 3x3 necessária, chama a solução e imprime OK se o resultado é como esperado.O algoritmo divide o cubo fornecido em 26 cubos - seqüências de comprimento 3 (cantos), 2 (arestas) e 1 (centros). Também gera os 26 cubos de um cubo resolvido com os mesmos 6 cubos centrais. Todos os seguintes critérios devem ser atendidos:
não há duplicatas entre os 6 centros
os conjuntos de dados / cubinhos resolvidos corresponder, até a rotação - por exemplo, considerar
'WBR'
e'BRW'
ao mesmo cubinho, mas não'BWR'
as paridades da permutação de canto e da borda são iguais
a soma modulo-3 dos índices de rotação de canto (por exemplo, tomando a letra "menor"
B
como ponto de referência temos:'BRW'→0
,'WBR'→1
,'RWB'→2
) jogo entre os cubos de dados e resolvidos; mesmo para os cantos módulo 2fonte