永久的Codegolf


20

挑战是为矩阵永久性编写代码高尔夫球。

n-by- nMatrix A=(ai,j)的永久变量定义为

在此处输入图片说明

在此S_n表示的所有排列的集合[1, n]

作为一个例子(来自维基):

在此处输入图片说明

您的代码可以随意输入,并以任何合理的格式输出,但是请在答案中包括一个完整的示例,其中包括有关如何向代码提供输入的明确说明。为了使挑战更加有趣,矩阵可以包含复数。

输入矩阵始终为正方形,最多为6 x6。 您还需要能够处理具有永久性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.我仍然不确定空矩阵。列表形式是[[]](有一行,空矩阵没有)还是[](没有深度2,矩阵有)?
丹尼斯

4
1.我不是说不可能用Bash解决这个挑战,但是如果代码中的绝大部分用于处理复数运算,那么它就不再是永久性的挑战。2.大多数(如果不是全部)当前答案是没有输入的矩阵类型中断的语言[[]]
丹尼斯

Answers:


11

J,5个字节

+/ .*

J不提供永久性或行列式的内建函数,而是提供一个沿未成年人u . v y递归扩展y并计算u . v辅因子与未成年人递归调用的输出之间的二元关系的连接。的选择uv可以改变。例如,使用u =: -/v =: *-/ .*决定因素。选择甚至可以通过%/ .!其中u=: %/,通过分割减少,并且v =: !这是二项式系数。我不确定该输出表示什么,但您可以自由选择动词。

在Mathematica 答案中使用相同方法的47个字节的替代实现。

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

这通过创建一个具有升为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

这沿第一列进行了类似Laplace的开发,并认为行的顺序无关紧要。它适用于任何数字类型。

输入为列表列表:

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:感觉它可能会更短。到目前为止,我有第二个相同大小的解决方案。
Emigna '16

不再需要处理空矩阵。
丹尼斯,

使用地图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))

代表

实现天真的算法,盲目地遵循定义。


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 '16

@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我从没学过……
Neil

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

在julia的较新版本中,您可以放任自传[],但是需要using Combinatoricspermutations功能。适用于Julia中的所有Number类型,包括ComplexrUnitRange定义为默认函数参数的对象,该对象可以依赖于先前的函数参数。

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.