不重叠矩阵总和


25

不重叠矩阵总和

给定k个长度为n的数组,使用每个数组中的一个元素输出可能的最大和,这样就不会有两个元素来自同一索引。保证k <= n。

输入项

一个非空整数数组的非空列表。

输出量

代表最大和的整数。

例子

Input -> Output
[[1]] -> 1
[[1, 3], [1, 3]] -> 4
[[1, 4, 2], [5, 6, 1]] -> 9
[[-2, -21],[18, 2]] -> 0
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] -> 15
[[1, 2, 3, 4], [5, 4, 3, 2], [6, 2, 7, 1]] -> 16
[[-2, -1], [-1, -2]] -> -2

5
数学有趣的事实:对于方阵,这是矩阵永久热带半环,其在地方的使用操作(最大,+)(+,*)。
xnor

Answers:


9

果冻10 6个字节

ZŒ!ÆṭṀ

在线尝试!

(@Dennis保存了4个字节,他指出Jelly内置了“主对角线总和”。我希望它具有其中的一个;以前的解决方案在不使用内置函数的情况下实现了该操作。Æṭ定义为“迹线”,但迹线仅针对平方矩阵定义; Jelly也对矩形矩阵实现了概括。)

相对于其他答案的改进主要来自于一种更简单的算法(因此更易于表达)。该程序最初是用Brachylog v2({\p\iᶠ∋₎ᵐ+}ᶠot)编写的,但是Jelly有一些内置程序的内置程序,这些程序必须在Brachylog中进行拼写,因此该程序简短了一些。

说明

ZŒ!ÆṭṀ
Z            Swap rows and columns
 Œ!          Find all permutations of rows (thus columns of the original)
   Æṭ        {For each permutation}, take the sum of the main diagonal
     Ṁ       Take the maximum

应该清楚的是,对于该问题的任何解决方案,我们都可以置换原始矩阵的列,以将该解决方案放在主对角线上。因此,此解决方案可以简单地将其反向,找到排列的所有可能的主要对角线。

请注意,“置换列”操作的执行方式是“转置,置换行”,而无需费心将其转回。该算法的其余部分碰巧是关于主对角线对称的,因此我们不需要撤消转置,因此可以节省一个字节。


ZŒ!ÆṭṀ保存四个字节。在线尝试!
丹尼斯

好吧,丹尼斯似乎在:P
Quintec '18

我不知道该内置函数是否曾经出现过?
ais523

不确定,但可能不是。ZŒ!ŒD§ṀḢ在记住那Æṭ件事之前,我实际上建议过。
丹尼斯

8

J,28个字节

>./@({.+1$:@|:\.|:@}.)@[^:]#

在线尝试!

 >./ @  (   {.   +         1 $:@|:\. |:@}.       )       @[^:] #
(max of (1st row + recursive call on each "minor")) or count of arg if 0

在这里,递归调用完成了,$:它代表了包含它的最大的匿名函数。我们很幸运在J中拥有该原语x u\. y,该原语适用uy通过抑制xin 中项长度的连续不等式而获得的连续“后缀” y。在这里,我们想压低连续的列以获得“次要”,因此我们转置|:的较低行(或tail }.y,然后在其后缀的转置上递归。


2
嗨,欢迎来到PPCG!我为您的解决方案添加了“ 在线试用”链接,以便其他人可以对其进行验证。
Galen Ivanov '18

7

Python 3中94个90 89 84 80字节

多亏了xnor -4个字节(使用集合而不是列表)!

f=lambda x,y={-1}:x>[]and max(e+f(x[1:],y|{i})for(i,e)in enumerate(x[0])if{i}-y)

在线尝试!


好方法!您可以进行y设置以缩短成员资格检查:f=lambda x,y={-1}:x>[]and max(e+f(x[1:],y|{i})for(i,e)in enumerate(x[0])if{i}-y)
xnor

@xnor:这个-1技巧真的很聪明:)非常感谢!
ბიმო

7

外壳12 11 9字节

▲mȯΣ►L∂PT

在线尝试!

感谢BMO建议ais523的答案和2字节的节省,我设法进一步改善了这一点,然后BMO减少了2个字节。


先前的解决方案(14个字节)

▲moΣz!¹fS=uΠmŀ

在线尝试!

我无法建立测试套件,因为此答案明确使用了第一个命令行参数 command。但是Husk根本不使用STDIN,因此我在其中包括了所有测试用例,因此您只需在参数字段中复制粘贴以将其签出即可。还要注意,Husk中的数组在输入时可能在元素之间不包含空格。

怎么运行的?

代码细目

▲moΣz!¹fS=uΠmŀ     Full program. Takes a 2D list from CLA 1 and outputs to STDOUT.
            mŀ     Length range of each list. 
           Π       Cartesian product.
       fS=u        Discard those combinations which have at least 1 non-unique element.
 mo                Map over the combinations with the following predicate:
    z!¹            Zip the 2D list input with the current combination and index accordingly.
   Σ               Sum the resulting elements.
▲                  Finally, pick the maximum.

1个42561个

必须从每个索引中准确选择一个索引,以使没有两个索引对应。因此,我们生成行的长度范围,仅保留不重复的行,产生以下组合(每个组合是一列而不是一行,以节省空间):

1个21个32321个31个32

然后,程序在输入列表中为组合的每个元素建立索引,返回:

1个41个242651个51个6

9


5

JavaScript(ES6), 74  71字节

感谢@tsh识别2个无用的字节,这些字节用于修复错误
由于@tsh,节省了3个字节

f=([a,...r],k,i=1)=>a?Math.max(...a.map(n=>k&(i+=i)?-1/0:n+f(r,k|i))):0

在线尝试!


@Shaggy但不可能以构成0从输入阵列,-1+(-1)-2它是正确的答案。
瓦尔说莫妮卡(

1
f=([a,...r],k,i=1)=>a?Math.max(...a.map(c=>k&(i+=i)?-1/0:c+f(r,k|i))):0很奇怪,但是会Math.max保存字节...
tsh

4

果冻13 12字节

ẈŒpQƑƇị"€¹§Ṁ

在线尝试!

替代版本,11字节

ZLœ!Lị"€¹§Ṁ

这使用了新添加的œ!内置函数,该函数生成给定长度的所有排列。

在线尝试!

怎么运行的

ẈŒpQƑƇị"€¹§Ṁ  Main link. Argument: M (matrix)

Ẉ             Widths; compute the length of each row.
              For an n×m matrix, this yields an array m copies of n.
 Œp           Cartesian product; promote each n to [1, ..., n], then form all arrays
              that pick one k out of all m copies of [1, ..., n].
   QƑƇ        Comb by fixed unique; keep only arrays that do not change by
              deduplicating their entries.
         ¹    Identity; yield M.
      ị"€     For each of the arrays of unique elements, use its m entries to index
              into the m rows of M.
          §   Take the sums of all resulting vectors.
           Ṁ  Take the maximum.

啊...我几乎用XLṗL代替张贴了相同的答案J€Œp
暴民埃里克(Erik the Outgolfer)

4

Haskell,65个字节

f(u:v)=maximum[e+f(take i<>drop(i+1)<$>v)|(i,e)<-zip[0..]u]
f _=0

在线尝试!

解释与取消

该函数take i<>drop(i+1)获取一个列表并删除position处的元素i

该函数f获取e位置上每个可能i的元素,i从其余元素中删除该位置上的元素,并添加e到递归计算的最优值中:

f(u:v)=maximum[e+f(removeElementAt i<$>v)|(i,e)<-zip[0..]u]

空列表的基本情况就是0

f _=0

2

Brachylog,18个字节

{hl⟦kp;?z₀∋₍ᵐ+}ᶠot

在线尝试!

说明

                ot      The output is the biggest result of…
{             }ᶠ        …finding all outputs to the following predicate:
 hl⟦k                     Construct the range [0, …, n-1]
     p                    Take a permutation of that range
      ;?z₀                Zip that permutation with the Input, stopping when all elements of
                            the input are used (important because the range is possibly
                            bigger than the length of the input)
          ∋₍ᵐ             In each element of the zip, take the head'th element of the tail
             +            Sum the result

2

Perl 6的50 49个字节

{max map *.map({.[$++]}).sum,permutations [Z] $_}

在线尝试!

即使permutations通话很长,也很短。这是一个匿名代码块,它使用列表列表并返回一个数字。

说明:

{                                               } # Anonymous code block
 max                                              # Finds the maximum
                             permutations         # Of all permutations
                                          [Z] $_  # Of the transposed input
     map                                          # When mapped to
                        .sum # The sum of
         *.map({.[$++]})     # The diagonal of the matrix

2

K(OK) 40,32,28, 19个字节

-13个字节感谢ngn!

{|/+/(prm'x)@''!#x}

在线尝试!

初始解决方案:

{|/+/'x./:/:(*t),'/:t:{x~?x}#+!(#x)##*x}

在线尝试!

注意:不适用于第一个测试用例[[1]]

说明:

{ } -带参数的功能 x

                                   #     - creata a list
                               (#x)      - with length number of rows of x
                                    #*x  - of the length of the first row
                              !          - odometer (ranged permutations)
                             +           - transpose
                            #            - filter out the rows
                      {x~?x}             - that have duplicates
                    t:                   - save it to t 
                ,'/:                     - pair up each number in each row with
            (*t)                         - a number from the first row
      x./:/:                             - index x with each of the above
   +/'                                   - find the sum of each row
 |/                                      - reduce by max

1
提示:prm可以直接应用于列表以生成其排列
ngn

@ngn谢谢!我想将主对角线与一起使用=,但结果更长。可以flatten吗?
Galen Ivanov '18

flatten 凭什么?
ngn

@ngn(1 2 3; 4 5 6; 7 8 9) -> (1 2 3 4 5 6 7 8 9)
Galen Ivanov

1
那只是 ,/或者如果您希望它进入更深层次的结构:,//
ngn

2

Haskell,65个字节

([]%)
p%(h:t)=maximum[x+(i:p)%t|(i,x)<-zip[0..]h,all(/=i)p]
p%_=0

在线尝试!


71个字节

f m=maximum[sum b|(a,b)<-unzip<$>mapM(zip[0..])m,[x|x<-a,y<-a,x==y]==a]

在线尝试!

[x|x<-a,y<-a,x==y]==a检查到的元素a是不同的。这用了惊人数量的字符,但是我没有看到更短的方法。


1

Pyth, 15 12字节

eSms@VQd.plh

在线尝试 在这里

eSms@VQd.plhQ   Implicit: Q=eval(input())
                Trailing Q inferred
          lhQ   Length of first element of Q
        .p      Generate all permutaions of 0 to the above
  m             Map the elements of the above, as d, using:
    @VQd          Vectorised index into Q using d
                    For i in [0-length(Q)), yield Q[i][d[i]]
   s              Take the sum of the above
 S              Sort the result of the map
e               Take the last element of the above, implicit print

编辑:保存了3个字节,由issacg提供


1
.PUlhQl可以替换为.plhV隐式忽略任何额外的条目。
isaacg

1

05AB1E18 13 字节

нgLœε‚øε`è]OZ

我有一种感觉是超长的,但我不知道怎么字节有效地完成矢量索引在05AB1E ..而我确实是正确的,这是太长.. -5字节感谢@Emigna

在线尝试验证所有测试用例

说明:

н                # Take the first inner list (of the implicit input list of lists)
 g               # Pop and take its length
  L              # Create a list in the range [1, inner-length]
   œ             # Create each possible permutation of this range-list
    ε            # Map each permutation to:
                #  Pair it with the (implicit) input
      ø          #  Transpose; swap rows/columns
       ε         #  Map each to:
        `        #   Push both to the stack
         è       #   Index the permutation-nr into the inner list of the input
    ]            # Close both maps
     O           # Take the sum of each inner list
      à          # Pop and push the maximum (and output implicitly)

示例运行:

  • 输入: [[1,4,2],[5,6,1]]
  • 在第1步之后(нgL)之后:[1,2,3]
  • 步骤2之后(œ)之后:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
  • 在步骤3(ε‚)之后:[[[[1,4,2],[5,6,1]],[1,2,3]],[[[1,4,2],[5,6,1]],[1,3,2]],[[[1,4,2],[5,6,1]],[2,1,3]],[[[1,4,2],[5,6,1]],[2,3,1]],[[[1,4,2],[5,6,1]],[3,1,2]],[[[1,4,2],[5,6,1]],[3,2,1]]]
  • 在第4步(ø)之后:[[[[1,4,2],1],[[5,6,1],2]],[[[1,4,2],1],[[5,6,1],3]],[[[1,4,2],2],[[5,6,1],1]],[[[1,4,2],2],[[5,6,1],3]],[[[1,4,2],3],[[5,6,1],1]],[[[1,4,2],3],[[5,6,1],2]]]
  • 在第5步(ε`è])之后:([[4,1],[4,5],[2,6],[2,5],[1,6],[1,1]]注意:05AB1E的索引为0(具有自动环绕),因此在。中索引3[5,6,1]结果5。)
  • 在步骤6(O)之后:[5,9,8,7,7,2]
  • 在步骤7(à)之后输出/9

1
我的нgLœε‚øεè] OZ`是13
Emigna

@Emigna谢谢!它与我看到的内容惊人地相似,除了我添加了一堆不必要的废话。; p
Kevin Cruijssen



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.