Кодегольф постійний


20

Завдання полягає в тому, щоб написати кодогольф для постійної матриці .

Постійне значення n-by- nmatrix A= ( ai,j) визначається як

введіть тут опис зображення

Тут S_nпредставлений набір усіх перестановок [1, n].

Як приклад (з вікі):

введіть тут опис зображення

Ваш код може брати вхід, як би він хотів, і давати вихід у будь-якому розумному форматі, але, будь ласка, включіть у свою відповідь повний відпрацьований приклад, включаючи чіткі інструкції щодо того, як подати вхід до вашого коду. Щоб зробити виклик трохи цікавішим, матриця може містити складні числа.

Вхідна матриця завжди квадратна і буде максимум 6 на 6. Також вам потрібно буде вміти обробляти порожню матрицю, яка має постійний 1. Не потрібно мати можливість обробляти порожню матрицю (вона викликала занадто багато проблеми).

Приклади

Вхід:

[[ 0.36697048+0.02459455j,  0.81148991+0.75269667j,  0.62568185+0.95950937j],
 [ 0.67985923+0.11419187j,  0.50131790+0.13067928j,  0.10330161+0.83532727j],
 [ 0.71085747+0.86199765j,  0.68902048+0.50886302j,  0.52729463+0.5974208j ]]

Вихід:

-1.7421952844303492+2.2476833142265793j

Вхід:

[[ 0.83702504+0.05801749j,  0.03912260+0.25027115j,  0.95507961+0.59109069j],
 [ 0.07330546+0.8569899j ,  0.47845015+0.45077079j,  0.80317410+0.5820795j ],
 [ 0.38306447+0.76444045j,  0.54067092+0.90206306j,  0.40001631+0.43832931j]]

Вихід:

-1.972117936608412+1.6081325306004794j

Вхід:

 [[ 0.61164611+0.42958732j,  0.69306292+0.94856925j,
     0.43860930+0.04104116j,  0.92232338+0.32857505j,
     0.40964318+0.59225476j,  0.69109847+0.32620144j],
   [ 0.57851263+0.69458731j,  0.21746623+0.38778693j,
     0.83334638+0.25805241j,  0.64855830+0.36137045j,
     0.65890840+0.06557287j,  0.25411493+0.37812483j],
   [ 0.11114704+0.44631335j,  0.32068031+0.52023283j,
     0.43360984+0.87037973j,  0.42752697+0.75343656j,
     0.23848512+0.96334466j,  0.28165516+0.13257001j],
   [ 0.66386467+0.21002292j,  0.11781236+0.00967473j,
     0.75491373+0.44880959j,  0.66749636+0.90076845j,
     0.00939420+0.06484633j,  0.21316223+0.4538433j ],
   [ 0.40175631+0.89340763j,  0.26849809+0.82500173j,
     0.84124107+0.23030393j,  0.62689175+0.61870543j,
     0.92430209+0.11914288j,  0.90655023+0.63096257j],
   [ 0.85830178+0.16441943j,  0.91144755+0.49943801j,
     0.51010550+0.60590678j,  0.51439995+0.37354955j,
     0.79986742+0.87723514j,  0.43231194+0.54571625j]]

Вихід:

-22.92354821347135-90.74278997288275j

Ви не можете використовувати жодні попередні функції для обчислення постійних.


12
Не могли б ви усунути складну вимогу? Я думаю, що це руйнує інакше приємний виклик. Кожна мова, яка не має вбудованої складної арифметики, тепер повинна виконувати абсолютно окреме завдання.
xnor

6
Якщо нам потрібно обробити порожню матрицю, ви повинні додати її як тестовий випадок. Той факт, що ви не можете реально представити матрицю 0x0 зі списками, робить це дещо складним. Особисто я просто зняв би цю вимогу.
Денніс

4
Немає сенсу три години класти щось у пісочницю. Дайте йому 3 дні, і люди мають шанс надати відгук.
Пітер Тейлор

7
1. Це не просто езоланг. Bash, наприклад, навіть не може мати справу з поплавцями . Виключати мову з конкуренції лише тому, що їй не вистачає певного числового типу, навіть якщо можна без особливих зусиль реалізовувати потрібний алгоритм, просто вибагливі без поважних причин. 2. Я досі не впевнений у порожній матриці. Буде це [[]](має один рядок, порожня матриця не має) або [](не має глибини 2, матриці) у формі списку?
Денніс

4
1. Мені не доводиться говорити, що неможливо вирішити цю задачу в Баші, але якщо левова частка коду використовується для боротьби зі складною арифметикою чисел, вона перестає бути викликом щодо постійних. 2. Більшість, якщо не всі поточні відповіді - це мови без перерви матриці для введення [[]].
Денніс

Відповіді:


11

J, 5 байт

+/ .*

J не пропонує вбудовані для постійної чи визначальної, але натомість пропонує сполучник, u . v yякий рекурсивно розширюється yвздовж неповнолітніх і обчислює діадію u . vміж кофакторами та виходом рекурсивного дзвінка на неповнолітніх. Вибір uі vможе бути різним. Наприклад, використання u =: -/і v =: *є тим, -/ .*що є визначальним фактором. Вибір можна навіть %/ .!куди u=: %/, зменшити на ділення, а v =: !який є двочленним коефіцієнтом. Я не впевнений, що означає цей результат, але ви можете вільно обирати дієслова.

Альтернативна реалізація для 47 байт з використанням того ж методу у моїй відповіді Mathematica .

_1{[:($@]$[:+//.*/)/0,.;@(<@(,0#~<:)"+2^i.@#)"{

Це імітує многочлен з n змінними, створюючи многочлен з однією змінною, піднятою до потужностей 2. Це проводиться як список коефіцієнтів, а множення поліномів здійснюється за допомогою згортки, а індекс на 2 n буде містити результат.

Інша реалізація на 31 байт є

+/@({.*1$:\.|:@}.)`(0{,)@.(1=#)

що є трішки гольф-версією, заснованою на розширенні Лапласа, взятому з нарису J про визначники .

Використання

   f =: +/ .*
   f 0 0 $ 0 NB. the empty matrix, create a shape with dimensions 0 x 0
1
   f 0.36697048j0.02459455 0.81148991j0.75269667 0.62568185j0.95950937 , 0.67985923j0.11419187  0.50131790j0.13067928 0.10330161j0.83532727 ,: 0.71085747j0.86199765 0.68902048j0.50886302 0.52729463j0.5974208
_1.7422j2.24768
   f 0.83702504j0.05801749 0.03912260j0.25027115 0.95507961j0.59109069 , 0.07330546j0.8569899 0.47845015j0.45077079 0.80317410j0.5820795 ,: 0.38306447j0.76444045 0.54067092j0.90206306 0.40001631j0.43832931
_1.97212j1.60813
   f 0.61164611j0.42958732 0.69306292j0.94856925 0.4386093j0.04104116 0.92232338j0.32857505 0.40964318j0.59225476 0.69109847j0.32620144 , 0.57851263j0.69458731 0.21746623j0.38778693 0.83334638j0.25805241 0.6485583j0.36137045 0.6589084j0.06557287 0.25411493j0.37812483 , 0.11114704j0.44631335 0.32068031j0.52023283 0.43360984j0.87037973 0.42752697j0.75343656 0.23848512j0.96334466 0.28165516j0.13257001 , 0.66386467j0.21002292 0.11781236j0.00967473 0.75491373j0.44880959 0.66749636j0.90076845 0.0093942j0.06484633 0.21316223j0.4538433 , 0.40175631j0.89340763 0.26849809j0.82500173 0.84124107j0.23030393 0.62689175j0.61870543 0.92430209j0.11914288 0.90655023j0.63096257 ,: 0.85830178j0.16441943 0.91144755j0.49943801 0.5101055j0.60590678 0.51439995j0.37354955 0.79986742j0.87723514 0.43231194j0.54571625
_22.9235j_90.7428

1
Нічого собі, я можу сказати.

13

Haskell, 59 байт

a#((b:c):r)=b*p(a++map tail r)+(c:a)#r
_#_=0
p[]=1
p l=[]#l

Це робить подію Лапласа уздовж першого стовпця і використовує, що порядок рядків не має значення. Він працює для будь-якого числового типу.

Введіть як список списків:

Prelude> p [[1,2],[3,4]]
10

2
Завжди вітаємо рішення Haskell!

8

Желе , 10 9 байт

Œ!ŒDḢ€P€S

Спробуйте в Інтернеті!

Як це працює

Œ!ŒDḢ€P€S  Main link. Argument: M (matrix / 2D array)

Œ!         Generate all permutations of M's rows.
  ŒD       Compute the permutations' diagonals, starting with the main diagonal.
    Ḣ€     Head each; extract the main diagonal of each permutation.
      P€   Product each; compute the products of the main diagonals.
        S  Compute the sum of the products.

Це занадто добре!

7

Python 2, 75 байт

Здається, незграбне ... повинно бути зручним.

P=lambda m,i=0:sum([r[i]*P(m[:j]+m[j+1:],i+1)for j,r in enumerate(m)]or[1])

6

05AB1E , 19 14 13 байт

œvyvyNè}Pˆ}¯O

Спробуйте в Інтернеті!

Пояснення

œ              # get all permutations of rows
 v        }    # for each permutation
  yv   }       # for each row in the permutation
    yNè        # get the element at index row-index
        P      # product of elements
         ˆ     # add product to global array
           ¯O  # sum the products from the global array

Трохи шокуюче за розміром відповідь! Не могли б ви дати пояснення?

@Lembik: Видається, що це все-таки може бути коротшим. У мене поки що друге рішення такого ж розміру.
Емінья

Обробка порожніх матриць більше не потрібна.
Денніс

8 байт за допомогою карт . Шкода , що новий 05AB1E не підтримує уявні числа (або я просто не знаю , як), так як ми тепер маємо головну діагональ і це вбудована команда може бути 6 байт: œ€Å\PO.
Кевін Круїссен

5

Python 2, 139 байт

from itertools import*
def p(a):c=complex;r=range(len(a));return sum(reduce(c.__mul__,[a[j][p[j]]for j in r],c(1))for p in permutations(r))

repl.it

Реалізує наївний алгоритм, який сліпо слідує визначенню.


4

MATL, 17 14 байт

tZyt:tY@X])!ps

Спробуйте в Інтернеті

Пояснення

t       % Implicitly grab input and duplicate
Zy      % Compute the size of the input. Yields [rows, columns]
t:      % Compute an array from [1...rows]
tY@     % Duplicate this array and compute all permutations (these are the columns)
X]      % Convert row/column to linear indices into the input matrix
)       % Index into the input matrix where each combination is a row
!p      % Take the product of each row
s       % Sum the result and implicitly display

1
Дуже вражає.

4

Рубі, 74 63 байти

->a{p=0;a.permutation{|b|n=1;i=-1;a.map{n*=b[i+=1][i]};p+=n};p}

Відвертий переклад формули. Кілька байтів збережено завдяки ezrast.

Пояснення

->a{
    # Initialize the permanent to 0
    p=0
    # For each permutation of a's rows...
    a.permutation{|b|
        # ... initialize the product to 1,
        n=1
        # initialize the index to -1; we'll use this to go down the main diagonal
        # (i starts at -1 because at each step, the first thing we do is increment i),
        i=-1
        # iteratively calculate the product,
        a.map{
            n*=b[i+=1][i]
        }
        # increase p by the main diagonal's product.
        p+=n
    }
    p
}

1
reduceнасправді шкодить ваш кількість байтів порівняно з агрегуванням вручну:->a{m=0;a.permutation{|b|n=1;a.size.times{|i|n*=b[i][i]};m+=n};m}
ezrast

@ezrast Дякую! Вдалося також пропустити цю timesпетлю.
m-chrzan

3

Ruby 2.4.0, 59 61 байт

Рекурсивне розширення Лапласа:

f=->a{a.pop&.map{|n|n*f[a.map{|r|r.rotate![0..-2]}]}&.sum||1}

Менше гольфу:

f=->a{
  # Pop a row off of a
  a.pop&.map{ |n|
    # For each element of that row, multiply by the permanent of the minor
    n * f[a.map{ |r| r.rotate![0..-2]}]
  # Add all the results together
  }&.sum ||
  # Short circuit to 1 if we got passed an empty matrix
  1
}

Ruby 2.4 офіційно не випускається. У попередніх версіях .sumїх потрібно буде замінити .reduce(:+), додавши 7 байт.


2

Математика, 54 байти

Coefficient[Times@@(#.(v=x~Array~Length@#)),Times@@v]&

Тепер, коли порожні матриці вже не розглядаються, це рішення є дійсним. Він походить зі сторінки MathWorld про постійні .


@alephalpha Це ідеальна ідея використовувати рядки для ідентифікації коефіцієнтів, але чи не зламалася вона, якби рядки не були унікальними?
милі

2

JavaScript (ES6), 82 байти

f=a=>a[0]?a.reduce((t,b,i)=>t+b[0]*f(a.filter((_,j)=>i-j).map(c=>c.slice(1))),0):1

Звичайно, працює і з порожньою матрицею.


@ETHproductions Я ніколи не вчуся ...
Ніл

1
Саме мій код, щойно опублікований за 14 годин до цього, я спробую додати складні номери
edc65

2

Юлія 0,4 , 73 байти

f(a,r=1:size(a,1))=sum([prod([a[i,p[i]] for i=r]) for p=permutations(r)])

У нових версіях Юлі ви можете опускати []навколо осягань, але потреба using Combinatoricsв permutationsфункції. Працює з усіма типами номерів у Джулії, в тому числі Complex. r- це UnitRangeоб'єкт, визначений як аргумент функції за замовчуванням, який може залежати від попередніх аргументів функції.

Спробуйте в Інтернеті!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.