O desafio é escrever codegolf para o Hafnian de uma matriz . O Hafnian de um 2n
-by- 2n
matriz simétrica A
é definida como:
Aqui S 2n representa o conjunto de todas as permutações dos números inteiros de 1
a 2n
, isto é[1, 2n]
.
O link da wikipedia fala sobre matrizes de adjacência, mas seu código deve funcionar para qualquer matriz de entrada simétrica com valor real.
Para os interessados nas aplicações do Hafnian, o link mathoverflow discute um pouco mais.
Seu código pode receber entrada da maneira que desejar e fornecer saída em qualquer formato razoável, mas inclua na sua resposta um exemplo completo, incluindo instruções claras de como fornecer entrada para o seu código.
A matriz de entrada é sempre quadrada e terá no máximo 16 por 16. Não há necessidade de lidar com a matriz vazia ou matrizes de dimensão ímpar.
Implementação de referência
Aqui está um exemplo de código python do Sr. Xcoder.
from itertools import permutations
from math import factorial
def hafnian(matrix):
my_sum = 0
n = len(matrix) // 2
for sigma in permutations(range(n*2)):
prod = 1
for j in range(n):
prod *= matrix[sigma[2*j]][sigma[2*j+1]]
my_sum += prod
return my_sum / (factorial(n) * 2 ** n)
print(hafnian([[0, 4.5], [4.5, 0]]))
4.5
print(hafnian([[0, 4.7, 4.6, 4.5], [4.7, 0, 2.1, 0.4], [4.6, 2.1, 0, 1.2], [4.5, 0.4, 1.2, 0]])
16.93
print(hafnian([[1.3, 4.1, 1.2, 0.0, 0.9, 4.4], [4.1, 4.2, 2.7, 1.2, 0.4, 1.7], [1.2, 2.7, 4.9, 4.7, 4.0, 3.7], [0.0, 1.2, 4.7, 2.2, 3.3, 1.8], [0.9, 0.4, 4.0, 3.3, 0.5, 4.4], [4.4, 1.7, 3.7, 1.8, 4.4, 3.2]])
262.458
A página wiki agora (2 de março de 2018) foi atualizada por ShreevatsaR para incluir uma maneira diferente de calcular o Hafniano. Seria muito interessante ver isso jogar golfe.
fonte
Respostas:
R ,
150142127119 bytesExperimente online!
Utiliza o mesmo truque que descobri aplicando esta resposta para indexar a matriz
P
, e o @Vlo sugeriu uma abordagem para remover completamente ofor
loop de -6 bytes!Para criar um novo caso de teste, você pode fazer
matrix(c(values,separated,by,commas,going,across,rows),nrow=2n,ncol=2n,byrow=T)
.Explicação: (o código é o mesmo; ele usa
apply
umfor
loop em vez de um loop, mas a lógica é idêntica).fonte
N
ek
entrar em argumentos de função para obter uma declaração, removendo{}
e salvando outros dois bytes.Pitão , 24 bytes
Experimente aqui!
Versão antiga, 35 bytes
Experimente aqui!
fonte
a[b]
é suficiente para competir).xÍysè<¹sès·<ysè<è
lmao? PS Mine tem 40 bytes e não está funcionando tão bem hah, fique à vontade para publicá-lo, sem saber se posso terminar antes de precisar ir para casa.Stax ,
23221917 bytesExecute e depure on-line
A representação ascii correspondente do mesmo programa é essa.
O programa sofre de algum erro de arredondamento de ponto flutuante. Em particular, ele relata em
33673.5000000011
vez de33673.5
. Mas acho que a precisão é aceitável, pois esse programa opera com valores de ponto flutuante. Também é muito lento, demorando quase um minuto para as entradas de exemplo nesta máquina.fonte
05AB1E , 21 bytes
Experimente online!
Versão antiga, 32 bytes
Experimente online!
Como funciona?
fonte
èsè
, hah ... haha ... eu sou insignificante.Geléia , 19 bytes
Experimente online!
Versão alternativa, 15 bytes, desafio pós-datas
Jelly finalmente obteve uma indexação de matriz n-dimensional.
Experimente online!
Como funciona
A versão de 19 bytes funciona de maneira semelhante; apenas tem que se implementar
œị
.fonte
C (GCC) ,
288285282293292272271 bytesif(...)...k=0...else...,j=0...
para a qual oif(k=j=0,...)...else...
jogador jogou - e executou uma mudança de índice.float
matrizes.2*j+++1
paraj-~j++
.int
declaração de tipo de variável supérflua e não usando uma função fatorial, mas calculando o valor fatorial usando um loop for já existente.S=S/F/(1<<n);
emS/=F*(1<<n);
.Experimente online!
Explicação
Experimente online!
No cerne do programa está o seguinte gerador de permutação que circula
S_n
. Todo o cálculo hafniano é simplesmente construído sobre ele - e ainda mais jogado.Experimente online!
fonte
float
matrizes.2*j+++1
é equivalente aj+j+++1
, que é o mesmo quej-(-j++-1)
, para que possamos usar o complemento bit a bit de maneira eficiente para salvar um byte:j-~j++
( Experimente on-line )R ,
8478 bytesExperimente online!
Edit: Obrigado ao Vlo por -6 bytes.
Parece que todo mundo aqui está implementando o algoritmo de referência padrão com permutações, mas tentei tirar proveito do conhecimento da comunidade adquirido no desafio relacionado , que é basicamente a mesma tarefa direcionada ao código mais rápido em vez do golfe.
Acontece que, para uma linguagem que é boa em fatiar matrizes (como R), o algoritmo recursivo:
hafnian(m) = sum(m[i,j] * hafnian(m[-rows and columns at i,j])
não é apenas mais rápido, mas também bastante desafiante. Aqui está o código não destruído:fonte
If
entre parênteses, -4 para usarF
como variável inicializada, -1 para atribuirn
dentro deif
. Você podeGelatina , 29 bytes
Experimente online!
Eu acho que a
;@€€Wị@/€€P€
parte provavelmente pode ser jogada para baixo. Precisa voltar mais tarde para verificar e adicionar uma explicação.fonte
J
) antes de jogar golfe . Mentes de geléia pensam da mesma forma ? sourceLḶŒ!s€2ḅL‘ịFZµPS÷JḤ$P$
TIOHaskell , 136 bytes
-14 bytes graças a ovs.
Experimente online!
Ugh ...
fonte
MATL ,
292422 bytesExperimente online! Ou verifique todos os casos de teste: 1 , 2 , 3 .
Como funciona
fonte
Língua Wolfram (Mathematica) , 85 bytes
Experimente online!
fonte
Coco ,
165145128127 bytes-1 byte graças ao Sr. Xcoder
Experimente online!
fonte
Perl 6, 86 bytes
fonte