Задача состоит в том, чтобы написать codegolf для гафнианской матрицы . Хафниан 2n
-симметричной 2n
матрицы A
определяется как:
Здесь S 2n представляет множество всех перестановок целых чисел от 1
до 2n
, то есть [1, 2n]
.
Ссылка на википедию говорит о матрицах смежности, но ваш код должен работать для любых вещественно симметричных входных матриц.
Для тех, кто интересуется приложениями Hafnian, ссылка mathoverflow обсуждает еще кое-что.
Ваш код может принимать любые входные данные и выводить их в любом разумном формате, но, пожалуйста, включите в свой ответ полный проработанный пример, включая четкие инструкции о том, как вводить данные в ваш код.
Входная матрица всегда квадратная и будет максимум 16 на 16. Нет необходимости иметь возможность обрабатывать пустую матрицу или матрицы нечетного измерения.
Ссылочная реализация
Вот пример кода Python от Mr. 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
Вики-страница теперь (2 марта 2018 г.) была обновлена ShreevatsaR, чтобы включить другой способ вычисления гафнианского. Было бы очень интересно увидеть этот гольф.
источник
Ответы:
R ,
150142127119 байтПопробуйте онлайн!
Использую тот же трюк, который я обнаружил, играя в гольф по этому ответу, чтобы проиндексировать матрицу
P
, и @Vlo предложил подход, чтобы полностью удалитьfor
цикл для -6 байт!Чтобы создать новый тестовый пример, вы можете сделать
matrix(c(values,separated,by,commas,going,across,rows),nrow=2n,ncol=2n,byrow=T)
.Объяснение: (код тот же; он использует цикл,
apply
а неfor
цикл, но логика в остальном идентична).источник
N
иk
в аргументы функции , чтобы получить его в одном заявлении, удаление{}
и сохранение еще два байта.Pyth , 24 байта
Попробуй это здесь!
Старая версия, 35 байт
Попробуй это здесь!
источник
a[b]
достаточно, чтобы конкурировать).xÍysè<¹sès·<ysè<è
lmao? PS У меня 40 байтов, и он не так хорошо работает, так что не стесняйтесь его публиковать, так как я не смогу закончить, прежде чем уйти домой.Stax ,
23221917 байтЗапустите и отладьте его онлайн
Соответствующее представление ascii той же программы таково.
Программа страдает от некоторой ошибки округления с плавающей запятой. В частности, он сообщает
33673.5000000011
вместо33673.5
. Но я думаю, что точность приемлема, учитывая, что эта программа работает со значениями с плавающей запятой. Это также очень медленно, на пример входов на этой машине уходит почти минуту.источник
05AB1E , 21 байт
Попробуйте онлайн!
Старая версия, 32 байта
Попробуйте онлайн!
Как это работает?
источник
èsè
, ха ... ха-ха ... Я маленький.Желе , 19 байт
Попробуйте онлайн!
Альтернативная версия, 15 байт, задание после даты
Желе наконец получил индексирование n-мерного массива.
Попробуйте онлайн!
Как это работает
19-байтовая версия работает аналогичным образом; он просто должен реализовать
œị
себя.источник
C (gcc) ,
288285282293292272271 байтif(...)...k=0...else...,j=0...
доif(k=j=0,...)...else...
- и выполнил индекс сдвиг.float
матриц.2*j+++1
вj-~j++
.int
объявление типа переменной и не используя функцию факториала, а вместо этого вычисляя значение факториала, используя уже существующий цикл for.S=S/F/(1<<n);
в гольфS/=F*(1<<n);
.Попробуйте онлайн!
объяснение
Попробуйте онлайн!
В основе программы лежит следующий генератор перестановок, который просматривает цикл
S_n
. Все вычисления Hafnian просто основаны на этом - и далее игра в гольф.Попробуйте онлайн!
источник
float
матрицы.2*j+++1
эквивалентноj+j+++1
, что аналогично томуj-(-j++-1)
, что мы можем эффективно использовать побитовое дополнение для сохранения байта:j-~j++
( Попробуйте онлайн )R ,
8478 байтПопробуйте онлайн!
Редактировать: Спасибо Вло за -6 байт.
Кажется, что все здесь реализуют стандартный эталонный алгоритм с перестановками, но я попытался воспользоваться знаниями сообщества, полученными в соответствующей задаче , которая в основном та же самая задача, предназначенная для самого быстрого кода вместо гольфа.
Оказывается, что для языка, который хорош в нарезке матриц (например, R), рекурсивный алгоритм:
hafnian(m) = sum(m[i,j] * hafnian(m[-rows and columns at i,j])
не только быстрее, но и довольно гольфистский. Вот негольфированный код:источник
If
с круглыми скобками, -4 для использования вF
качестве инициализированной переменной, -1 для назначенияn
вif
. tio.run/##XU/LCsIwELz7FcFTVtOQl1pf1/…Желе , 29 байт
Попробуйте онлайн!
Я думаю, что
;@€€Wị@/€€P€
часть, вероятно, может быть проиграна. Нужно вернуться позже, чтобы проверить и добавить объяснение.источник
J
) до игры в гольф . Умы желе думают одинаково ? источникLḶŒ!s€2ḅL‘ịFZµPS÷JḤ$P$
TIOHaskell , 136 байт
-14 байт благодаря овс.
Попробуйте онлайн!
Тьфу ...
источник
MATL ,
292422 байтаПопробуйте онлайн! Или проверьте все тестовые случаи: 1 , 2 , 3 .
Как это работает
источник
Wolfram Language (Mathematica) , 85 байт
Попробуйте онлайн!
источник
Кокос ,
165145128127 байт-1 байт благодаря мистеру Xcoder
Попробуйте онлайн!
источник
Perl 6, 86 байт
источник