Codegolfパーマ


20

課題は、行列のパーマネント用のcodegolfを書くことです。

永久n行列のn行列A=( ai,j)は以下のように定義されます

ここに画像の説明を入力してください

ここでS_nのすべての順列の集合を表します[1, n]

例として(wikiから):

ここに画像の説明を入力してください

コードは必要に応じて入力を受け取り、適切な形式で出力できますが、コードに入力を提供するための明確な指示を含む完全に機能する例を回答に含めてください。課題をもう少し面白くするために、マトリックスに複素数を含めることができます。

入力行列は常に正方形で、最大で6 x 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時間置いても意味がありません。それを3日間与えると、人々はフィードバックを与える機会があります。
ピーターテイラー

7
1.エソランだけではありません。たとえば、Bashはfloatをネイティブに扱うことさえできません。特定の数値型がないという理由だけで言語を競合から除外することは、たとえ目的のアルゴリズムを簡単に実装できたとしても、正当な理由がなくてうるさいだけです。2.空の行列についてはまだわかりません。リスト形式では[[]](1行あり、空行列はありません)または[](深さ2、行列ありません)でしょうか?
デニス

4
1. Bashでこの課題を解決することは不可能だとは思っていませんが、コードの大部分を複素数演算に使用すると、パーマネントに関する課題ではなくなります。2.現在の回答のすべてではないにしても、ほとんどは、入力用の行列型の区切りのない言語[[]]です。
デニス

回答:


11

J、5バイト

+/ .*

Jは、パーマネントまたは行列式のビルトインを提供しませんが、その代わりに、マイナーに沿ってu . v y再帰的に展開し、コファクターとマイナーの再帰呼び出しの出力間のyダイアディックを計算する接続詞を提供しますu . v。選択肢uとはv異なる場合があります。たとえば、u =: -/およびを使用してv =: *される-/ .*決定因子です。選択肢は、%/ .!where u=: %/、さらに除算で減少し、v =: !どちらが二項係数であるかによっても可能です。その出力が何を意味するのかはわかりませんが、動詞を自由に選択できます。

47バイトの代替実装私のMathematicaの答えで同じメソッドを使用する。

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

これにより、多項式をシミュレートします 1つの変数を2で累乗した多項式を作成することにより n変数のます。これは、係数リストとして保持され、畳み込みを使用して多項式乗算が実行され、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

05AB1E19 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:まだ短くなる可能性があります。これまでと同じサイズの2番目のソリューションがあります。
エミグナ

空の行列を処理する必要はなくなりました。
デニス

マップを使用して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

ルビー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

Mathematica、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バイト

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

juliaの新しいバージョンで[]は、理解度を下げることができますがusing Combinatoricspermutations関数。を含む、ジュリアのすべての数値型で動作しComplexます。rは、UnitRangeデフォルトの関数引数として定義されたオブジェクトであり、以前の関数引数に依存する場合があります。

オンラインでお試しください!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.