Codegolf yang permanen

20

Tantangannya adalah menulis codegolf untuk permanen sebuah matriks .

Permanen dari n-by- nmatrix A= ( ai,j) didefinisikan sebagai

masukkan deskripsi gambar di sini

Berikut S_nmerupakan himpunan semua permutasi dari [1, n].

Sebagai contoh (dari wiki):

masukkan deskripsi gambar di sini

Namun kode Anda dapat mengambil input yang diinginkan dan memberikan output dalam format apa pun yang masuk akal, tetapi harap sertakan dalam jawaban Anda contoh yang lengkap, termasuk instruksi yang jelas tentang cara memasok input ke kode Anda. Untuk membuat tantangan sedikit lebih menarik, matriks dapat menyertakan bilangan kompleks.

Matriks input selalu berbentuk persegi dan paling banyak 6 x 6. Anda juga harus dapat menangani matriks kosong yang permanen 1. Tidak perlu lagi menangani matriks kosong (itu menyebabkan terlalu banyak masalah).

Contohnya

Memasukkan:

[[ 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 ]]

Keluaran:

-1.7421952844303492+2.2476833142265793j

Memasukkan:

[[ 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]]

Keluaran:

-1.972117936608412+1.6081325306004794j

Memasukkan:

 [[ 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]]

Keluaran:

-22.92354821347135-90.74278997288275j

Anda tidak boleh menggunakan fungsi yang sudah ada sebelumnya untuk menghitung permanen.


sumber
12
Bisakah Anda menghapus persyaratan yang rumit? Saya pikir itu menghancurkan tantangan yang bagus. Setiap bahasa yang tidak memiliki aritmatika rumit bawaan kini harus melakukan tugas yang benar-benar terpisah.
xnor
6
Jika kami perlu menangani matriks kosong, Anda harus menambahkannya sebagai test case. Fakta bahwa Anda tidak dapat benar-benar mewakili matriks 0x0 dengan daftar membuat ini sedikit sulit. Secara pribadi, saya baru saja menghapus persyaratan itu.
Dennis
4
Tidak ada gunanya menaruh sesuatu di kotak pasir selama 3 jam. Berikan 3 hari dan orang-orang memiliki kesempatan untuk memberikan umpan balik.
Peter Taylor
7
1. Bukan hanya esolang. Bash, misalnya, bahkan tidak bisa menangani mengapung . Mengecualikan bahasa dari kompetisi hanya karena tidak memiliki tipe numerik tertentu, bahkan jika dapat dengan mudah mengimplementasikan algoritma yang diinginkan, hanya menjadi pemilih tanpa alasan yang baik. 2. Saya masih tidak yakin tentang matriks kosong. Apakah [[]](memiliki satu baris, matriks kosong tidak) atau [](tidak memiliki kedalaman 2, matriks lakukan) dalam bentuk daftar?
Dennis
4
1. Saya tidak yakin bahwa tidak mungkin untuk menyelesaikan tantangan ini di Bash, tetapi jika bagian terbesar dari kode digunakan untuk berurusan dengan bilangan aritmatika kompleks, itu berhenti menjadi tantangan tentang permanen. 2. Sebagian besar jika tidak semua jawaban saat ini adalah bahasa tanpa jeda jenis matriks untuk input [[]].
Dennis

Jawaban:

11

J, 5 byte

+/ .*

J tidak menawarkan builtin untuk permanen atau determinan tetapi sebaliknya menawarkan konjungsi u . v yyang secara rekursif berkembang di ysepanjang anak di bawah umur dan menghitung diad u . vantara kofaktor dan output dari panggilan rekursif pada anak di bawah umur. Pilihan udan vdapat bervariasi. Misalnya, menggunakan u =: -/dan v =: *merupakan -/ .*penentu. Pilihan bahkan dapat berdasarkan %/ .!mana u=: %/, dikurangi dengan pembagian, dan v =: !yang merupakan koefisien binomial. Saya tidak yakin apa artinya output itu tetapi Anda bebas memilih kata kerja Anda.

Implementasi alternatif untuk 47 byte menggunakan metode yang sama dalam jawaban Mathematica saya .

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

Ini mensimulasikan polinomial dengan n variabel dengan membuat polinomial dengan satu variabel dinaikkan ke pangkat 2. Ini diadakan sebagai daftar koefisien dan penggandaan polinomial dilakukan menggunakan konvolusi, dan indeks pada 2 n akan berisi hasilnya.

Implementasi lain untuk 31 byte adalah

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

yang merupakan versi yang sedikit golf berdasarkan ekspansi Laplace yang diambil dari esai J pada determinan .

Pemakaian

   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
mil
sumber
1
Wow hanya itu yang bisa saya katakan.
13

Haskell, 59 byte

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

Ini melakukan pengembangan seperti Laplace di sepanjang kolom pertama, dan menggunakan urutan baris tidak masalah. Ini bekerja untuk semua tipe numerik.

Input adalah sebagai daftar daftar:

Prelude> p [[1,2],[3,4]]
10
Sievers Kristen
sumber
2
Selalu sambut solusi Haskell!
8

Jelly , 10 9 byte

Œ!ŒDḢ€P€S

Cobalah online!

Bagaimana itu bekerja

Œ!Œ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.
Dennis
sumber
Itu terlalu bagus!
7

Python 2, 75 byte

Sepertinya kikuk ... harusnya bisa dikalahkan.

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

05AB1E , 19 14 13 byte

œvyvyNè}Pˆ}¯O

Cobalah online!

Penjelasan

œ              # 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
Emigna
sumber
Jawaban yang sedikit mengejutkan! Bisakah Anda memberikan penjelasan?
@Lembik: Rasanya seperti itu bisa lebih pendek lagi. Saya punya solusi kedua dengan ukuran yang sama sejauh ini.
Emigna
Menangani matriks kosong tidak lagi diperlukan.
Dennis
8 byte dengan menggunakan peta . Terlalu buruk 05AB1E baru tidak mendukung nomor imajiner (atau saya hanya tidak tahu bagaimana), karena kita sekarang memiliki builtin diagonal utama dan ini bisa menjadi 6 bytes: œ€Å\PO.
Kevin Cruijssen
5

Python 2, 139 byte

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

Menerapkan algoritma naif yang secara membabi buta mengikuti definisi.

Jonathan Allan
sumber
4

MATL, 17 14 byte

tZyt:tY@X])!ps

Cobalah secara Online

Penjelasan

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
Suever
sumber
1
Sangat mengesankan.
4

Rubi, 74 63 byte

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

Terjemahan langsung dari formula. Beberapa byte disimpan berkat ezrast.

Penjelasan

->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
}
m-chrzan
sumber
1
reducesebenarnya menyakiti jumlah byte Anda dibandingkan dengan menggabungkan secara manual:->a{m=0;a.permutation{|b|n=1;a.size.times{|i|n*=b[i][i]};m+=n};m}
ezrast
@ezrast Terima kasih! Berhasil bermain golf di timesloop itu juga.
m-chrzan
3

Ruby 2.4.0, 59 61 byte

Ekspansi Laplace Rekursif:

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

Kurang bermain golf:

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 tidak dirilis secara resmi. Pada versi sebelumnya, .sumperlu diganti dengan .reduce(:+), menambahkan 7 byte.

ezrast
sumber
2

Mathematica, 54 byte

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

Sekarang matriks kosong tidak lagi dipertimbangkan, solusi ini valid. Itu berasal dari halaman MathWorld di permanen .

mil
sumber
@alephalpha Itu ide yang bagus untuk menggunakan baris untuk mengidentifikasi koefisien tetapi tidak akan pecah jika baris tidak unik?
mil
2

JavaScript (ES6), 82 byte

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

Bekerja dengan matriks kosong juga, tentu saja.

Neil
sumber
@ ETHproduksi Saya tidak pernah belajar ...
Neil
1
Tepat kode saya, baru saja diterbitkan 14 jam sebelumnya, saya akan mencoba menambahkan angka kompleks
edc65
2

Julia 0.4 , 73 byte

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

Dalam versi julia yang lebih baru, Anda dapat menjatuhkan []sekitar pemahaman, tetapi perlu using Combinatoricsuntuk permutationsfungsi. Bekerja dengan semua jenis Nomor di Julia, termasuk Complex. radalah UnitRangeobjek yang didefinisikan sebagai argumen fungsi default, yang dapat bergantung pada argumen fungsi sebelumnya.

Cobalah online!

gggg
sumber