Сума матриць, що не перекриваються


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
Факт веселощів математики: Для квадратних масивів це матриця, постійна над тропічним семіруванням, яка використовує операції (max, +) замість (+, *).
xnor

Відповіді:


9

Желе , 10 6 байт

ZŒ!ÆṭṀ

Спробуйте в Інтернеті!

(4 байти врятував @Dennis, який вказав, що у Джеллі була вбудована "сума основної діагоналі". Я не був очікував, що він буде одним із таких; попереднє рішення реалізувало операцію, не використовуючи вбудований. Операція, про яку йдеться, Æṭ, визначається як "слід", але слід визначається лише для квадратних матриць; Jelly реалізує узагальнення і для прямокутних матриць.)

Удосконалення порівняно з іншими відповідями здебільшого відбувається з більш простого (таким чином, більш вираженого) алгоритму; ця програма спочатку була написана на Brachylog v2 ({\p\iᶠ∋₎ᵐ+}ᶠot ), але в Jelly є деякі вбудовані частини програми, які потрібно прописати в Брахілозі, тому ця програма вийшла коротшою.

Пояснення

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
Квінтек

Цікаво, чи збудувався той вбудований раніше?
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, який застосовується uдо послідовних "переходів", yотриманих шляхом придушення послідовних інфіксів довжини xелементів у y; тут ми хочемо придушити послідовні стовпчики, щоб отримати "неповнолітніх", тому ми переносимо |:нижні ряди (або хвіст }.) y, а потім повторюємо перенесення їхніх інфікси.


2
Привіт і ласкаво просимо до PPCG! Я додав посилання " Спробуйте в Інтернеті " для вашого рішення, щоб інші могли його перевірити.
Гален Іванов

7

Python 3 , 94 90 89 84 80 байт

-4 байти завдяки xnor (використовуючи набори замість списків)!

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ŀ

Спробуйте в Інтернеті!

Я не зміг скласти тестовий набір, оскільки в цій відповіді явно використовується команда аргументу першого командного рядка . Але 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.

Приклад

(142561)

One must pick exactly one index from each such that no two indices correspond. So, we generate the length ranges of the rows and only keep those without duplicates, yielding the following combinations (each combination is a column instead of a row to save space):

(121323213132)

Then, the program indexes in the input lists with each element of the combination, returning:

(141242651516)

Summing all those results (here, each column, for the aforementioned reason), one obtains all possible valid sums according to the criteria, in this case 9.


5

JavaScript (ES6),  74  71 bytes

Thanks to @tsh for identifying 2 useless bytes that were used to fix a bug
Saved 3 bytes thanks to @tsh

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

Try it online!


@Shaggy but it is impossible to compose 0 from input array, -1+(-1) is -2 and it is correct answer.
val says Reinstate Monica

1
f=([a,...r],k,i=1)=>a?Math.max(...a.map(c=>k&(i+=i)?-1/0:c+f(r,k|i))):0 It's strange, but Math.max saves bytes...
tsh

4

Jelly, 13 12 bytes

ẈŒpQƑƇị"€¹§Ṁ

Try it online!

Alternate version, 11 bytes

ZLœ!Lị"€¹§Ṁ

This uses the newly added œ! built-in, which generates all permutations of a given length.

Try it online!

How it works

ẈŒ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.
Ерік Аутгольфер

4

Haskell , 65 байт

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

Спробуйте в Інтернеті!

Explanation & Ungolfed

Функція take i<>drop(i+1)бере список і видаляє елемент у позиціїi.

Функція fотримує кожен можливий елемент eв положенні i, видаляє елементи в положенні iз решти елементів і додає eдо рекурсивно обчисленого оптимуму:

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

І базовий випадок для порожнього списку просто 0:

f _=0

2

Брахілог , 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 call. This is an anonymous code block that takes a list of lists and returns a number.

Пояснення:

{                                               } # 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

К (оК) , 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в ОК?
Гален Іванов

flattenв якому сенсі?
ngn

@ngn(1 2 3; 4 5 6; 7 8 9) -> (1 2 3 4 5 6 7 8 9)
Гален Іванов

1
що просто , ,/або якщо ви хочете, щоб перейти в більш глибокі структури:,//
СПП

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можна замінити на .plh. Vнеявно ігнорує будь-які додаткові записи.
isaacg

1

05AB1E , 18 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 Дякую! Це дивно схоже на те, що я мав бачити, за винятком того, що я додав купу непотрібних, які були непотрібні. ; p
Кевін Круїссен



0

05AB1E , 7 байт

øœ€Å\Oà

Порт відповіді Jelly CW @ @ ais523 , тому обов'язково підтримайте його!

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

ø          # 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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.