# Non-overlapping Matrix Sum

Given k arrays of length n, output the maximum sum possible using one element from each array such that no two elements are from the same index. It is guaranteed that k<=n.

# Input

A nonempty list of nonempty arrays of integers.

# Output

An integer that represents the maximum sum.

# Examples

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
• Math fun fact: For square arrays, this is the matrix permanent over the tropical semiring which uses the operations (max, +) in place of (+, *). – xnor Dec 18 '18 at 22:00

# Jelly, 10 6 bytes

ZŒ!ÆṭṀ

Try it online!

(4 bytes saved by @Dennis, who pointed out that Jelly had a "sum of main diagonal" builtin. I was not expecting it to have one of those; the previous solution implemented the operation without using the builtin. The operation in question, Æṭ, is defined as "trace", but the trace is only defined for square matrices; Jelly implements a generalisation to rectangular matrices too.)

The improvement over the other answers is mostly from a simpler (thus terser to express) algorithm; this program was originally written in Brachylog v2 ({\p\iᶠ∋₎ᵐ+}ᶠot), but Jelly has some builtins for parts of the program that have to be spelled out in Brachylog, so this came out shorter.

## Explanation

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

It should be clear that for any solution to the problem, we can permute the columns of the original matrix to put that solution onto the main diagonal. So this solution simply reverses that, finding all possible main diagonals of permutations.

Note that the "permute the columns" operation is done as "transpose, permute the rows" without bothering to transpose back; the rest of the algorithm happens to be symmetrical about the main diagonal, so we don't need to undo the transpose and thus can save a byte.

• ZŒ!ÆṭṀ saves four bytes. Try it online! – Dennis Dec 18 '18 at 0:09
• Well it looks like Dennis got the last word in :P – Quintec Dec 18 '18 at 1:09
• I wonder if that builtin's ever come up before? – ais523 Dec 18 '18 at 2:42
• Not sure, but probably not. I actually suggested ZŒ!ŒD§ṀḢ before remembering that Æṭ was a thing. – Dennis Dec 18 '18 at 2:44

# J, 28 bytes

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

f _=0

Try it online!

## Explanation & Ungolfed

The function take i<>drop(i+1) takes a list and removes the element at position i.

The function f gets each possible element e at position i, removes the elements at position i from the remaining elements and adds e to the recursively computed optimum:

f(u:v)=maximum[e+f(removeElementAt i<$>v)|(i,e)<-zip[0..]u] And the base case for the empty list is just 0: f _=0 # Brachylog, 18 bytes {hl⟦kp;?z₀∋₍ᵐ+}ᶠot Try it online! ### Explanation 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 # Perl 6, 50 49 bytes {max map *.map({.[$++]}).sum,permutations [Z] $_} Try it online! Decently short, even despite the long permutations call. This is an anonymous code block that takes a list of lists and returns a number. ### Explanation: { } # 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 # K (oK), 40, 32, 28, 19 bytes -13 bytes thanks to ngn! {|/+/(prm'x)@''!#x} Try it online! ## Initial solution: {|/+/'x./:/:(*t),'/:t:{x~?x}#+!(#x)##*x} Try it online! Note: Doesn't work for the first test case [[1]] ## Explanation: { } - function with argument 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 • hint: prm can be applied directly to a list to generate its permutations – ngn Dec 18 '18 at 7:30 • @ngn Thanks! I wanted to use the main diagonal with =, but the result was longer. Is there flatten in oK? – Galen Ivanov Dec 18 '18 at 9:32 • flatten in what sense? – ngn Dec 18 '18 at 9:33 • @ngn (1 2 3; 4 5 6; 7 8 9) -> (1 2 3 4 5 6 7 8 9) – Galen Ivanov Dec 18 '18 at 9:38 • that's just ,/ or if you want it to go into deeper structures: ,// – ngn Dec 18 '18 at 9:42 # Haskell, 65 bytes ([]%) p%(h:t)=maximum[x+(i:p)%t|(i,x)<-zip[0..]h,all(/=i)p] p%_=0 Try it online! 71 bytes f m=maximum[sum b|(a,b)<-unzip<$>mapM(zip[0..])m,[x|x<-a,y<-a,x==y]==a]

Try it online!

The [x|x<-a,y<-a,x==y]==a checks that the elements of a are distinct. This uses up a surprising number of characters, but I didn't see a shorter way.

# Pyth, 15 12 bytes

eSms@VQd.plh

Try it online here.

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

Edit: saved 3 bytes courtesy of issacg

• .PUlhQl can be replaced by .plh. V implicitly ignores any extra entries. – isaacg Dec 18 '18 at 1:06

# 05AB1E, 18 13 bytes

нgLœε‚øεè]OZ

I have the feeling it's overly long, but I'm not sure how to do vectorized indexing byte-efficiently in 05AB1E.. And I was indeed right that it was too long.. -5 bytes thanks to @Emigna.

Explanation:

н                # 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)

Example run:

• Input: [[1,4,2],[5,6,1]]
• After step 1 (нgL): [1,2,3]
• After step 2 (œ): [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
• After step 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]]]
• After step 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]]]
• After step 5 (εè]): [[4,1],[4,5],[2,6],[2,5],[1,6],[1,1]] (NOTE: 05AB1E is 0-indexed (with automatic wraparound), so indexing 3 into [5,6,1] results in 5.)
• After step 6 (O): [5,9,8,7,7,2]
• Output / after step 7 (à): 9
• I had нgLœε‚øεè]OZ for 13. – Emigna Dec 18 '18 at 8:32
• @Emigna Thanks! It's surprisingly similar to what I had I see, except that I added a bunch of crap that was unnecessary. ;p – Kevin Cruijssen Dec 18 '18 at 8:43

## Haskell, 84 bytes

import Data.List
h l=maximum[sum$snd<$>r|r<-mapM id$zip[1..]<$>l,(==)=<<nub$fst<$>r]

Try it online!

# Ruby, 7472 69 bytes

->a{[*0...a[0].size].permutation.map{|x|a.zip(x).sum{|y,z|y[z]}}.max}

Try it online!

# 05AB1E, 7 bytes

øœ€Å\Oà

Port of @ais523's Jelly CW answer, so make sure to upvote it as well!

Explanation:

ø          # Transpose the (implicit) input; swapping row/columns
œ         # Get all permutations
€Å\      # Take the main diagonal of each
O     # Sum each
à    # Pop and push the maximum (which is output implicitly)