Las matrices de Pauli son un conjunto de matrices de 2x2 que aparecen con mucha frecuencia en física cuántica (no, no es necesario conocer ninguna física cuántica para este desafío). Si incluimos la identidad en el conjunto, las cuatro matrices son:
σ0 = σ1 = σ2 = σ3 =
[1 0] [0 1] [0 -i] [1 0]
[0 1] [1 0] [i 0] [0 -1]
Multiplicando dos de estos dará siempre otra matriz Pauli, aunque puede ser multiplicado por una de las fases complejas 1
, i
, -1
, -i
. Por ejemplo, .σ1σ3 = -iσ2
Su tarea es multiplicar varias matrices de Pauli y devolver la matriz y la fase resultantes. De entrada será dado como una cadena no vacía de dígitos 0
a 3
representa las matrices a . La salida debe ser una cadena que contenga un solo dígito para la matriz resultante, opcionalmente precedida por , o para indicar la fase ( es para ).σ0
σ3
i
-
-i
-
-1
Puede escribir un programa o función, tomando la entrada a través de STDIN (o la alternativa más cercana), argumento de línea de comando o argumento de función y generando el resultado a través de STDOUT (o la alternativa más cercana), el valor de retorno de la función o el parámetro de función (out).
No debe utilizar ninguna función integrada (o de terceros) relacionada con las matrices Pauli.
Este es el código de golf, gana la respuesta más corta (en bytes).
Casos de prueba
1 => 1
13 => -i2
000 => 0
123 => i0
03022 => 3
02132230 => -i3
1320130100032 => i2
311220321030322113103 => -2
0223202330203313021301011023230323 => -i0
1323130203022111323321112122313213130330103202032222223 => -1
fuente
Respuestas:
Pyth, 47 bytes
Supongo que esto todavía es golfable. Pero supera a CJam por mucho.
Pruébelo en línea: Demostración o conjunto de pruebas
Explicación
Determinar el tipo de matriz resultante es simplemente exportar todos los números.
Al multiplicar 2 matrices
A*B
, la fase cambia, si ninguna de las matrices esσ0
yA != B
.fuente
Python 2,
108898786 bytes(Gracias a @grc y @xnor por la ayuda)
Explicación
Dividamos el coeficiente y la matriz base. Si nos centramos solo en la matriz base, obtenemos esta tabla de multiplicación (por ejemplo ,
13
es-i2
, así que ponemos2
):que resulta ser lo mismo que hacer bitor xor.
Ahora centrémonos en los coeficientes. Si dejamos
0123
denotar1,i,-1,-i
respectivamente, obtenemos:Para esto, primero verificamos si cualquiera de los números es 0 haciendo
m*y
, cuidando la columna izquierda y la fila superior. Agregar(m-y)%3
luego da:que está cerca, excepto que tenemos en
2
lugar de3
. Tenemos en cuenta esto mediante la realización*3/2
.Para la indexación, notamos que si tomamos la cadena
"--i"
y seleccionamos cada segundo carácter a partir de los índices0123
que obtenemos"-i","-","i",""
.fuente
3-n%4
tan~n%4
. Sospecho que puedes expresarm*y and(m-y)%3*3/2
más corto en una cuerda mágica, pero mi primer intento877449216>>2*m+8*y
solo empató. También hay una fórmula bastante algebraica, que siY=m^y
, la expresión es(m-y)*(y-Y)*(Y-m)/2
, pero eso es largo.~
, bien, el fuera de lugar me estaba molestando: / Estoy bastante seguro de que tambiénm*y and(m-y)%3*3/2
se puede acortar, pero pasé toda la noche y no llegué a ningún lado ... Volveré a eso si tener tiempo. Tal vez el hecho de que tengo libertad mod 4 podría ayudar.Retina , 77 bytes
Pensé en aprovechar esta oportunidad para mostrar una nueva función de Retina: bucles de varias etapas. Esto debería acortar considerablemente muchas tareas (especialmente el reemplazo condicional).
Retina es mi propio lenguaje de programación basado en expresiones regulares. El código fuente se puede agrupar en etapas: cada etapa consta de dos líneas donde la primera contiene la expresión regular (y potencialmente alguna configuración) y la segunda línea es la cadena de reemplazo. Las etapas se aplican a STDIN en orden y el resultado final se imprime a STDOUT.
Puede usar lo anterior directamente como un archivo fuente con el
-s
interruptor de línea de comandos. Sin embargo, no estoy contando el cambio, porque también puede colocar cada línea en un archivo separado (luego pierde 15 bytes para las nuevas líneas, pero agrega +15 para los archivos adicionales).Explicación
Lo nuevo de esta solución es
)
la penúltima etapa. Esto cierra un ciclo de múltiples etapas. No hay coincidencia(
, lo que significa que el ciclo comienza implícitamente en la primera etapa. Por lo tanto, las primeras 7 etapas se repiten hasta que un pase completo a través de las 7 deja de cambiar el resultado. Estas 7 etapas simplemente realizan varias transformaciones que reducen gradualmente el número de matrices en la cadena y combinan fases. Una vez que alcanzamos el resultado final, ninguno de los siete patrones coincide más y el ciclo termina. Luego, agregamos un 0 si todavía no hay un dígito en el resultado (ya que las etapas anteriores simplemente eliminan todas las identidades, incluido el resultado).Esto es lo que hacen las etapas individuales:
Combina todos los pares de
i
en-
para reducir los caracteres de fase.Ahora, si quedan dos caracteres idénticos consecutivos, es una
--
o dos matrices idénticas. En cualquier caso, multiplicarlos da la identidad. Pero no necesitamos identidades, por lo que las eliminamos todas y también las identidades explícitas (0
s). Esta etapa se repite en sí misma+
hasta que el resultado deja de cambiar. Esto asegura que cosas como123321
se resuelvan por completo, de modo que el siguiente paso pueda suponer que todos los pares de dígitos son distintos.Esto es en realidad dos transformaciones separadas en una (para golfitude). Tenga en cuenta que si la primera alternativa coincide,
$2
y$3
están vacías, y si la segunda coincide,$1
está vacía. Entonces esto se puede descomponer en estos dos pasos:Esto simplemente intercambia todos los pares de dígitos y agrega un signo menos. Desde que eliminó todas
0
s y todos los pares idénticos, esto sólo coincidirá12
,23
,31
,21
,32
,13
. Este paso puede parecer extraño, pero me permite verificar solo la mitad de estos casos más adelante, porque los que no puedo procesar se intercambiarán aquí en la próxima iteración.La otra parte de la etapa anterior fue:
Esto mueve gradualmente los
-
signos hacia la izquierda (una posición por iteración). Hago esto de manera tal que, en última instancia, estén todos juntos y se resuelvan en el paso anterior.Estas tres etapas ahora simplemente resuelven los tres pares de productos. Como dije anteriormente, esto solo detectará la mitad de los casos relevantes, pero la otra mitad se resolverá en la próxima iteración, después de que el paso anterior intercambiara todos los pares.
Esta es la última etapa del ciclo. Es similar al que se desplaza
-
hacia la izquierda, exceptoi
. La principal diferencia es que este se intercambiai
solo con dígitos. Si lo usara(.)i
, en los casos en que obtenga uno-i
oi-
los dos se intercambiarían indefinidamente y el programa no terminaría. Entonces esto solo los cambia a la derecha de los-
signos. Esto es suficiente: siempre que todos-
yi
aparezcan juntos en algún momento, se pueden resolver correctamente.El paso final (fuera del bucle). Recuerde que siempre eliminamos todas las identidades, por lo que si el resultado es en realidad la identidad (multiplicada por una fase), ya no tendremos el dígito requerido en la salida, así que lo volveremos a agregar.
Como ejemplo, aquí están todas las formas intermedias de
0223202330203313021301011023230323
(omitiendo etapas que no realizan ningún cambio):fuente
CJam,
5856 bytesEstoy seguro de que esto se puede jugar mucho, pero aquí va:
Pruébelo en línea aquí o ejecute la suite completa aquí
fuente