¿Es un cubo de Rubik?

25

Un pasatiempo venerado de los pedantes es señalar que las imágenes de "Cubos de Rubik" (en camisetas, carteles, etc.) en realidad no tienen solución.

Lo primero que debe verificarse es que el cubo esté formado por las piezas correctas. Para poder resolverse, un cubo necesita seis colores, cada uno con nueve cuadrados. El cubo también necesita que cada unidad de borde y esquina (estos son los cubos más pequeños que conforman el cubo) para ser únicos. No solo deben ser únicos, sino que si dos piezas centrales están opuestas entre sí, ninguna pieza de borde o esquina puede contener ambos colores.

Una vez que tenga un cubo que esté formado por todas las piezas correctas, aún debe verificar que pueda resolverse. Aquí hay un par de reglas, por lo que consultaré a un experto para que las explique, el spoiler a continuación explica cómo podemos hacer esto. Si está interesado en resolver el problema por su cuenta, no necesita visitar el sitio para comprender o participar en este desafío.

Explicación vinculada

Su tarea es tomar un patrón como entrada y determinar si de hecho es un cubo de Rubik solucionable. Para que sea solucionable debe haber una forma de realizar movimientos válidos en un cubo para que el cubo tenga un solo color en cada cara (y las diferentes caras tengan colores diferentes). La mayoría de los cubos de Rubik tienen un color estándar (el blanco es opuesto al amarillo, etc.). No puede suponer que el estado de resolución sigue a este color particular.

Un movimiento válido es la rotación en sentido horario o antihorario de una sola cara del cubo. Con la rotación de la cara del cubo, también se giran los cuadrados que bordean la cara, permaneciendo conectados a la cara que estaban tocando anteriormente.

IO

Puede tomar el cubo de cualquier manera razonable. Si su idioma tiene algún tipo de "cara de cubo" incorporada, bueno para usted, está bien como entrada, de lo contrario puede tomar una matriz 2D de la red, del cubo, de 1 3 por 3 listas para cada cara. Solo se razonable. Si desea saber si un formato específico es aceptable, hágame un comentario o hágame ping en el chat y agregaré al desafío para indicar su validez.

Su formato de entrada solo necesita admitir hasta 9 colores posibles.

Para la salida, este es un problema de decisión, por lo que debe generar un valor constante para "Sí, este es un cubo de Rubik válido" y un valor constante diferente para "No, este no es un cubo de Rubik válido".


Este es el por lo que las respuestas se puntuarán en bytes, siendo mejores menos bytes.

Casos de prueba

Aquí hay casos de prueba. Están formateados como la red de un cubo con cada cuadrado como una sola letra. Diferentes letras representan diferentes colores. Se pueden agregar más casos de prueba a pedido.

Soluble

   RRR
   RRR
   RRR
GGGWWWBBBOOO
GGGWWWBBBOOO
GGGWWWBBBOOO
   YYY
   YYY
   YYY


   GRR
   GRR
   ORW
WWRBWYBOOGGY
GGRBWGYBBOOO
OOGRWGYWWRBB
   WYO
   YYB
   YYB

Insoluble

   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
Asistente de trigo
fuente
14
Me siento obligado a señalar que el cubo de Rubik en tu avatar no tiene solución. Solo tiene 4 cuadrados en el lado que nos enfrenta, mientras que un cubo normal de Rubik debería tener 9. Sin mencionar los símbolos extraños en la parte superior de los cuadrados.
DJMcMayhem
2
@DJMcMayhem Mis hijos tienen cubos de Rubik con solo cuatro "subcubos".
Adám
2
@ H.PWiz No, no puedes. Eso estaba implícito en mis definiciones, pero lo haré explícito en la pregunta.
Wheat Wizard
2
Su especificación no incluye una descripción completa de las tres leyes de paridad del cubo. 1. Es imposible tener solo 1 borde invertido 180 grados (mencionado) 2. Es imposible tener solo 1 esquina torcida 120 grados (no mencionado) 3. Es imposible tener una permutación extraña de los cubos (no mencionado). ) Voy a emitir un voto cerrado hasta que esto se resuelva. Consulte ryanheise.com/cube/cube_laws.html para obtener una explicación.
Level River St
44
@LevelRiverSt Tenga en cuenta que el cubo de Rubik es autónomo, cualquiera puede derivar en la formulación matemática y las leyes de paridad de forma independiente.
user202729

Respuestas:

14

Cúbicamente , 1664 1631 1089 bytes

⇒FD2F'R'D2RUR'D2RFD2F'U'
⇒Ff1F'
⇒LFf1F'L'
⇒F'f1F
⇒F2f1F2
⇒L'F2f1F2L
⇒D'F'f1FD
⇒LR'FLR'DLR'B2L'RDL'RFL'RU2
⇒LFf8F'L'
⇒R'F'f8FR
⇒Ff8F'
⇒F'f8F
⇒ULU'f8UL'U'
⇒U'R'Uf8U'RU
⇒F2f8F2
⇒Df15D'
⇒D'f15D
⇒D2f15D2
⇒UF2UF2D'L2B2U'B2DL2F2D2B2D2F2
⇒U'DL2UD'B2
⇒UF2UF2D'L2B2D'R2UR2F2D2B2U2B2
⇒BL'BU2D2F'RF'U2D2
⇒LD'F2U'B2U'RU2R'F2R2F2D'R2DF2D
⇒B2URB2D2B2RB2U'D'L2D'B2
⇒B2LF'U'B2UFL'R2B2U'D2L2D'B2U
⇒B2RB2D2B2RB2U'L2UD'F2U'F2B2
⇒D2R'FUB2U'F'RU2B2D'F2R2UF2UF2
⇒B2R2U'L'D2B2U2R'U2R2F2L2R2UR2
⇒D2L'B2U2F2RUL2U'F2R2U'R2U2F2DL2D'
⇒UB2U'L2DL2B2DB2D'B2
⇒BR'BL2B'RBL2B2
⇒UF2B2U'F2B2U'F2L2R2B2R2
⇒R2U'F2DR2UF2D'R2DF2R2D'F2
⇒U'F2DF2UL2F2DL2DF2L2D2F2
⇒U2D'L2U'F2L2U'B2L2R2U'L2B2
⇒F2D'R2U2L2B2UF2L2U2F2L2UF2R2
⇒[f1]3
⇒[f2f37]3
⇒[f3f38]3
⇒[f4f39]3
⇒[f5f40]3
⇒[f6f41]3
⇒[f7f42]3
⇒[f8f43]2
⇒[f9f44]2
⇒[f10f45]2
⇒[f11f46]2
⇒[f12f47]2
⇒[f13f48]2
⇒[f14f49]2
⇒[f15f50]2
⇒[f16f51]2
⇒[f17f52]2
⇒[f18f53]2
⇒[f19f54]2
⇒[f20f55]3
⇒[f21f56]4
⇒[f22f57]5
⇒[f23f58]6
⇒[f24f59]7
⇒[f25f60]8
⇒[f26f61]9
⇒[f27f62]9[f27f62]2
⇒[f28f63]9[f28f63]3
⇒[f29f64]9[f29f64]4
⇒[f30f65]2
⇒[f31f66]3
⇒[f32f67]4
⇒[f33f68]5
⇒[f34f69]6
⇒[f35f70]7
rs[f36f71]8

Salida si tiene solución: Solved!
Salida si no tiene solución: (vacío, sin salida)

La entrada debe formatearse como un volcado de cubo cúbico (consulte la Debugsección). Esto fue explícitamente permitido por el OP.

Explicación

Este programa adopta el enfoque de usar un Algoritmo del Diablo para iterar sobre cada estado posible del cubo en el mismo grupo que el cubo resuelto. Si el cubo tiene solución, se resolverá en algún momento antes de que el algoritmo haya finalizado (suponiendo que el algoritmo que utilicé funcione correctamente).

Cada línea que comienza con (0x84 en la página de códigos de Cubically) es una definición de función; Estas funciones se complementan entre sí para formar el algoritmo del diablo real. La primera línea a ejecutar es la última:

rs[f36f71]8

rlee un cubo de stdin y establece el cubo de memoria en él. spone al intérprete en "modo de resolución", lo que significa que sale e imprime Solved!si el cubo se resuelve (después de no resolverse) en cualquier momento. El resto de los comandos (que simplemente se repiten f36f718 veces) corresponden al algoritmo final en la parte inferior de la página vinculada:

(D) = (CP) = (CPT8) = [(CPC8)(CPT7)]8 (3,847,762,288,469,010,006,992 moves)

(D) is the Devil's Algorithm. If you apply it to the cube, it will be solved at some point before you have done the algorithm once. As you can see, it is terribly long, nearly a thousand times more moves than there are possible positions.

¿Cómo puedo ejecutarlo?

Puedes probarlo en línea , pero ese enlace no funciona. TIO casi definitivamente expirará antes de que termine este algoritmo (el tiempo de ejecución máximo para un intérprete es de 60 segundos). Si el cubo no se puede resolver, este algoritmo tomará hasta 11 millones de años para que Cubically termine (a ~ 15.2 millones de movimientos por segundo, que es lo que obtiene mi IDE Cloud9 ).

Además, necesita mucha memoria para realizar 3 sextillones de movimientos. Cúbicamente puede realizar alrededor de 4 millones de movimientos por segundo, pero el proceso probablemente se cancele debido a la memoria comprometida en exceso . Muere después de 15 segundos en mi VM con 512 MB de memoria. ¿Por qué realizar movimientos en una memoria de matriz plana ya asignada cuesta? Encontró una pérdida de memoria (o veinte) y la arregló .

Aquí hay una versión mucho más legible que se comporta de la misma manera.

¡Pero realmente quiero ver que funciona!

El primer movimiento real que se ejecuta en el algoritmo de este demonio es F2, por lo que el cubo más rápido para resolver sería uno codificado con F2:

   000
   000
   555
113222133444
113222133444
113222133444
   000
   555
   555

De hecho, esto se ejecuta en 0.007 segundos en TIO .

¿Cómo se puede mejorar esto?

Ciertamente hay más algoritmos del diablo; He encontrado uno que usa menos de la trigésima parte de los movimientos que este hace. Sin embargo, eso tendría un costo de varios miles de bytes (alrededor de 100 MB más) y varias docenas de horas de convertir un complejo circuito hamiltoniano a código cúbico.

También es posible eliminar algunas de las funciones y colocarlas directamente en el bucle en la parte inferior. Sin embargo, voy a sacrificar algunos bytes por cierta legibilidad.

Además, estoy considerando una modificación del comportamiento de bucle de Cubically para poder repetir más fácilmente los algoritmos 7 u 8 veces (en lugar de simplemente codificarlos con las llamadas de función repetidas 7 u 8 veces en la fuente). O haré algo de magia con el bloc de notas, y jugaré golf usando más bucles.

Tenga en cuenta que continuaré optimizando todo lo posible en el intérprete, ¡así que esto puede funcionar en una PC promedio en algún momento en el futuro!


Cúbicamente, 2 bytes

r▦

Me gusta más la respuesta anterior, así que estoy agregando esto como una solución alternativa. Esto se ejecuta en menos de un segundo, a diferencia de unos pocos millones de años.

r    read cube from standard in
 ▦   and solve it

Salida si el cubo tiene solución: (nada)
Salida si el cubo no tiene solución: Error: The cube has reached an unsolvable state.

MD XF
fuente
¿Funciona esto si intercambiamos lados? Por ejemplo, 2 es opuesto a 4 en el volcado del cubo, ¿funciona si 2 es opuesto a 5 y 4 es opuesto a 0?
Wheat Wizard
1
@WheatWizard Sí, el modo de resolución comprueba si cada cara tiene un número entero único y si ese número entero es el único en la cara.
MD XF
Ok como debería. No estaba familiarizado con Cubically lo suficiente como para saber si este era el caso o no por su descripción.
Wheat Wizard
@WheatWizard Solo asegurándome de que te entiendo correctamente: esto es (en la línea de) a lo que te referías , ¿es así?
MD XF
Sí. Y debería ser solucionable.
Wheat Wizard
4

APL (Dyalog Classic) , 190 174 bytes

{∧/~∊(×1 2 3|+.-⌿↑⊃∘⍋¨¨¨a)({2|≢∪{⍵⌊⍵[⍵]}⍣≡⍵,0}¨⍳⌿↑⌽b)((∪≢∩)¨/b←(⊃∘⍋⌽⊢)¨¨¨a),6≢≢∪⊃⊃a←{c4⍴⊂⍬⋄c[+/1≠i],←(≠/×i←↑⍳33){⊂⌽⍣⍺⊢⍵~' '}¨,⌿(3|∘.+⍨⍳3)⍉⍤¯11 0 1\⍵1c}¨⍵(3 3∘⍴¨1 1∘⌷¨⍵)}

Pruébalo en línea!

El argumento es una matriz de 3x2 (fila0: frente atrás, fila1: izquierda derecha, fila2: arriba abajo) de matrices de 3x3 caracteres. Devuelve 1 para un cubo de Rubik solucionable, 0 de lo contrario.

En el enlace TIO, la función t, que no está incluida en el recuento de caracteres, lee 9 líneas de entrada, las convierte del formato de entrada predeterminado (una red) a la matriz 3x2 x 3x3 requerida, llama a la solución e imprime OK si el resultado es como se esperaba

El algoritmo divide el cubo dado en 26 cubos: cadenas de longitud 3 (esquinas), 2 (bordes) y 1 (centros). También genera los 26 cubos de un cubo resuelto con los mismos 6 cubos centrales. Deben cumplirse todos los siguientes criterios:

  • no hay duplicados entre los 6 centros

  • los conjuntos de cubos dados / resueltos coinciden, hasta la rotación, por ejemplo, considerar 'WBR'y 'BRW'el mismo cubito, pero no'BWR'

  • las paridades tanto de la permutación de la esquina como de la permutación del borde son pares

  • la suma módulo 3 de los índices de rotación de esquina (por ejemplo, tomando la letra "más pequeño" Bcomo punto de referencia que tenemos: 'BRW'→0, 'WBR'→1, 'RWB'→2) partido entre los cubos dados y resueltos; lo mismo para las esquinas módulo 2

ngn
fuente