As matrizes de Pauli são um conjunto de matrizes 2x2 que aparecem muito comumente na física quântica (não, você não precisa conhecer nenhuma física quântica para esse desafio). Se incluirmos a identidade no conjunto, as quatro matrizes são:
σ0 = σ1 = σ2 = σ3 =
[1 0] [0 1] [0 -i] [1 0]
[0 1] [1 0] [i 0] [0 -1]
Multiplicando dois destes dará sempre uma outra matriz Pauli, embora possa ser multiplicada por uma das fases complexas 1
, i
, -1
, -i
. Por exemplo ,.σ1σ3 = -iσ2
Sua tarefa é multiplicar um número de matrizes Pauli e retornar a matriz e a fase resultantes. A entrada será fornecida como uma sequência de dígitos não vazia 0
para 3
representar as matrizes para . A saída deve ser uma cadeia de caracteres contendo um único dígito para a matriz resultante, opcionalmente precedida por , ou para indicar a fase ( é para ).σ0
σ3
i
-
-i
-
-1
Você pode escrever um programa ou função, recebendo entrada via STDIN (ou alternativa mais próxima), argumento da linha de comando ou argumento da função e emitindo o resultado via STDOUT (ou alternativa mais próxima), valor de retorno da função ou parâmetro da função (saída).
Você não deve usar nenhum recurso interno (ou de terceiros) relacionado às matrizes Pauli.
Isso é código de golfe, a resposta mais curta (em bytes) vence.
Casos de teste
1 => 1
13 => -i2
000 => 0
123 => i0
03022 => 3
02132230 => -i3
1320130100032 => i2
311220321030322113103 => -2
0223202330203313021301011023230323 => -i0
1323130203022111323321112122313213130330103202032222223 => -1
fonte
Respostas:
Pitão, 47 bytes
Eu acho que isso ainda é jogável. Mas supera muito o CJam.
Experimente on-line: Demonstration or Test Suite
Explicação
Determinar o tipo de matriz resultante é simplesmente armazenar todos os números.
Ao multiplicar 2 matrizes
A*B
, a fase muda, se não uma das matrizes forσ0
eA != B
.fonte
Python 2,
108898786 bytes(Obrigado a @grc e @xnor pela ajuda)
Explicação
Vamos dividir o coeficiente e a matriz base. Se focarmos apenas na matriz base, obteremos esta tabela de multiplicação (por exemplo ,
13
é-i2
, então colocamos2
):que passa a ser a mesma coisa que fazer xor bit a bit.
Agora vamos nos concentrar nos coeficientes. Se deixarmos
0123
denotar1,i,-1,-i
respectivamente, obtemos:Para isso, primeiro verificamos se qualquer número é 0
m*y
, cuidando da coluna esquerda e da linha superior. Adicionar(m-y)%3
então fornece:que está perto, exceto que temos em
2
vez de3
. Nós explicamos isso realizando*3/2
.Para indexação, notamos que, se pegarmos a string
"--i"
e selecionarmos cada segundo caractere a partir dos índices0123
que obtivermos"-i","-","i",""
.fonte
3-n%4
como~n%4
. Eu suspeito que você pode expressarm*y and(m-y)%3*3/2
mais curto em uma corda mágica, mas minha primeira tentativa877449216>>2*m+8*y
só empatou. Há também uma fórmula algébrica bastante bonita, que seY=m^y
, a expressão é(m-y)*(y-Y)*(Y-m)/2
, mas é longa.~
, que bom - o off-by-one estava me incomodando: / Tenho certeza de que tambémm*y and(m-y)%3*3/2
pode ser reduzido, mas passei a noite toda e não cheguei a lugar nenhum ... voltarei a ele se eu tenho tempo. Talvez o fato de eu ter liberdade mod 4 possa ajudar.Retina , 77 bytes
Pensei em usar essa oportunidade para exibir um novo recurso Retina: loops de vários estágios. Isso deve reduzir consideravelmente muitas tarefas (especialmente a substituição condicional).
Retina é minha própria linguagem de programação baseada em regex. O código-fonte pode ser agrupado em estágios: cada estágio consiste em duas linhas em que o primeiro contém a regex (e potencialmente alguma configuração) e a segunda linha é a sequência de substituição. As etapas são aplicadas ao STDIN em ordem e o resultado final é impresso em STDOUT.
Você pode usar o acima diretamente como um arquivo de origem com a
-s
opção de linha de comando. No entanto, não estou contando a opção, porque você também pode colocar cada linha em um arquivo separado (então você perde 15 bytes para as novas linhas, mas adiciona +15 para os arquivos adicionais).Explicação
A novidade desta solução é
)
a penúltima etapa. Isso fecha um loop de vários estágios. Não há correspondência(
, o que significa que o loop inicia implicitamente no primeiro estágio. Portanto, os sete primeiros estágios são repetidos até que uma passagem completa pelos sete pare de alterar o resultado. Esses 7 estágios simplesmente realizam várias transformações que reduzem gradualmente o número de matrizes na cadeia e combinam fases. Quando alcançamos o resultado final, nenhum dos sete padrões corresponde mais e o loop termina. Depois, adicionamos um 0 se ainda não houver um dígito no resultado (como os estágios acima simplesmente eliminam todas as identidades, incluindo o resultado).Aqui está o que as etapas individuais fazem:
Combina todos os pares de
i
em-
para reduzir os caracteres da fase.Agora, se houver dois caracteres idênticos consecutivos restantes, são uma
--
ou duas matrizes idênticas. Nos dois casos, multiplicá-los fornece a identidade. Mas como não precisamos de identidades, removemos todas elas e as identidades explícitas0
também. Esta etapa é repetida em si mesma+
até que o resultado pare de mudar. Isso garante que coisas como123321
sejam resolvidas completamente, de forma que a próxima etapa possa assumir que todos os pares de dígitos são distintos.Na verdade, são duas transformações separadas em uma (para golfitude). Observe que se a primeira alternativa corresponder
$2
e$3
estiver vazia, e se a segunda corresponder$1
estiver vazia. Portanto, isso pode ser decomposto nessas duas etapas:Isso apenas troca todos os pares de dígitos e adiciona um sinal de menos. Desde que removeu todos os
0
s e todos os pares idênticos, isto só irá corresponder12
,23
,31
,21
,32
,13
. Essa etapa pode parecer estranha, mas me permite verificar apenas metade desses casos mais tarde, porque os que não puderem ser processados serão trocados aqui na próxima iteração.A outra parte do estágio acima foi:
Isso gradualmente move os
-
sinais para a esquerda (uma posição por iteração). Faço isso de modo que, em última análise, todos estejam próximos um do outro e sejam resolvidos na etapa anterior.Agora, esses três estágios simplesmente resolvem os três pares de produtos. Como eu disse acima, isso capturará apenas metade dos casos relevantes, mas a outra metade será tratada na próxima iteração, após a etapa anterior ter trocado todos os pares.
Este é o último estágio do loop. É semelhante ao que se desloca
-
para a esquerda, excetoi
. A principal diferença é que este trocai
apenas com dígitos. Se eu usasse(.)i
, nos casos em que eu recebesse um-i
oui-
os dois, seriam trocados indefinidamente e o programa não seria encerrado. Portanto, isso apenas os troca à direita dos-
sinais. Isso é suficiente - desde que todos-
ei
apareçam juntos em algum momento, eles possam ser resolvidos corretamente.A etapa final (fora do loop). Lembre-se de que sempre excluímos todas as identidades; portanto, se o resultado for realmente a identidade (vezes uma fase), não teremos mais o dígito necessário na saída; por isso, o adicionamos novamente.
Como exemplo, aqui estão todas as formas intermediárias de
0223202330203313021301011023230323
(pulando estágios que não executam nenhuma alteração):fonte
CJam,
5856 bytesEstou certo de que isso pode ser muito praticado, mas aqui vai:
Experimente on-line aqui ou execute o pacote completo aqui
fonte