El desafío es escribir codegolf para el hafniano de una matriz . El Hafnian de un 2n
-by- 2n
matriz simétrica A
se define como:
Aquí S 2n representa el conjunto de todas las permutaciones de los enteros de 1
a 2n
, es decir [1, 2n]
.
El enlace de wikipedia habla sobre las matrices de adyacencia, pero su código debería funcionar para cualquier matriz de entrada simétrica de valor real.
Para aquellos interesados en las aplicaciones de Hafnian, el enlace mathoverflow discute un poco más.
Su código puede recibir información de la forma que desee y proporcionar resultados en cualquier formato razonable, pero incluya en su respuesta un ejemplo completo que incluya instrucciones claras sobre cómo suministrar información a su código.
La matriz de entrada siempre es cuadrada y tendrá como máximo 16 por 16. No hay necesidad de poder manejar la matriz vacía o las matrices de dimensión impar.
Implementación de referencia
Aquí hay un ejemplo de código python del 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
La página wiki ahora (2 de marzo de 2018) ha sido actualizada por ShreevatsaR para incluir una forma diferente de calcular el Hafnian. Sería muy interesante ver esto golfizado.
fuente
Respuestas:
R ,
150142127119 bytesPruébalo en línea!
Utiliza el mismo truco que descubrí jugando golf en esta respuesta para indexar la matriz
P
, ¡y @Vlo sugirió un enfoque para eliminar por completo elfor
bucle para -6 bytes!Para crear un nuevo caso de prueba, puede hacerlo
matrix(c(values,separated,by,commas,going,across,rows),nrow=2n,ncol=2n,byrow=T)
.Explicación: (el código es el mismo; utiliza un bucle en
apply
lugar de unfor
bucle, pero la lógica es idéntica).fuente
N
yk
en los argumentos de funciones para conseguir que una sentencia, la eliminación de la{}
y el ahorro de otros dos bytes.Pyth , 24 bytes
Pruébalo aquí!
Versión anterior, 35 bytes
Pruébalo aquí!
fuente
a[b]
es suficiente para competir).xÍysè<¹sès·<ysè<è
lmao? PS Mine tiene 40 bytes y no funciona tan bien, ja, así que siéntete libre de publicarlo, seguro de que puedo terminar antes de irme a casa.Stax ,
23221917 bytesEjecútelo y depúrelo en línea
La representación ascii correspondiente del mismo programa es esta.
El programa sufre algún error de redondeo de coma flotante. En particular, informa en
33673.5000000011
lugar de33673.5
. Pero creo que la precisión es aceptable dado que este programa funciona con valores de coma flotante. También es muy lento, toma casi un minuto para las entradas de ejemplo en esta máquina.fuente
05AB1E , 21 bytes
Pruébalo en línea!
Versión anterior, 32 bytes
Pruébalo en línea!
¿Cómo funciona?
fuente
èsè
, ja ... jaja ... soy punny.Jalea , 19 bytes
Pruébalo en línea!
Versión alternativa, 15 bytes, desafío de fecha posterior
Jelly finalmente obtuvo la indexación de matriz n-dimensional.
Pruébalo en línea!
Cómo funciona
La versión de 19 bytes funciona de manera similar; solo tiene que implementarse
œị
.fuente
C (gcc) ,
288285282293292272271 bytesif(...)...k=0...else...,j=0...
aif(k=j=0,...)...else...
- y realizado un cambio en el índice.float
matrices de soporte .2*j+++1
aj-~j++
.int
declaración de tipo variable superflua y no utilizando una función factorial, sino calculando el valor factorial utilizando un bucle for ya existente.S=S/F/(1<<n);
al golfS/=F*(1<<n);
.Pruébalo en línea!
Explicación
Pruébalo en línea!
En el núcleo del programa se encuentra el siguiente generador de permutación que se repite
S_n
. Todo el cálculo hafniano se basa simplemente en él, y se juega más.Pruébalo en línea!
fuente
float
matrices.2*j+++1
es equivalente aj+j+++1
, que es lo mismo quej-(-j++-1)
, por lo que podemos usar el complemento bit a bit de manera eficiente para guardar un byte:j-~j++
( Pruébelo en línea )R ,
8478 bytesPruébalo en línea!
Editar: Gracias a Vlo por -6 bytes.
Parece que todos aquí están implementando el algoritmo de referencia estándar con permutaciones, pero traté de aprovechar el conocimiento de la comunidad adquirido en el desafío relacionado , que es básicamente la misma tarea dirigida al código más rápido en lugar del golf.
Resulta que para un lenguaje que es bueno para cortar matrices (como R), el algoritmo recursivo:
hafnian(m) = sum(m[i,j] * hafnian(m[-rows and columns at i,j])
no solo es más rápido, sino también bastante golfoso. Aquí está el código sin golf:fuente
If
con paréntesis, -4 para usarF
como variable inicializada, -1 para asignarn
dentro deif
. tio.run/##XU/LCsIwELz7FcFTVtOQl1pf1/…Jalea , 29 bytes
Pruébalo en línea!
Creo que la
;@€€Wị@/€€P€
parte probablemente se puede reducir. Necesito volver más tarde para verificar y agregar una explicación.fuente
J
) antes de jugar golf . ¿Las mentes de gelatina piensan igual ? fuenteLḶŒ!s€2ḅL‘ịFZµPS÷JḤ$P$
TIOHaskell , 136 bytes
-14 bytes gracias a los ovs.
Pruébalo en línea!
Ugh ...
fuente
MATL ,
292422 bytesPruébalo en línea! O verifique todos los casos de prueba: 1 , 2 , 3 .
Cómo funciona
fuente
Wolfram Language (Mathematica) , 85 bytes
Pruébalo en línea!
fuente
De coco ,
165145128127 bytes-1 byte gracias al Sr. Xcoder
Pruébalo en línea!
fuente
Perl 6, 86 bytes
fuente