Somma matrice non sovrapposta


25

Somma matrice non sovrapposta

Dati k array di lunghezza n , genera la somma massima possibile usando un elemento da ciascun array in modo tale che non vi siano due elementi dello stesso indice. È garantito che k <= n.

Ingresso

Un elenco non vuoto di matrici non vuote di numeri interi.

Produzione

Un numero intero che rappresenta la somma massima.

Esempi

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
Curiosità matematica: per le matrici quadrate, questa è la matrice permanente sul semiring tropicale che utilizza le operazioni (max, +) al posto di (+, *).
xnor

Risposte:


9

Gelatina , 10 6 byte

ZŒ!ÆṭṀ

Provalo online!

(4 byte salvati da @Dennis, che ha sottolineato che Jelly aveva una "somma della diagonale principale" incorporata. Non mi aspettavo che avesse una di quelle; la soluzione precedente implementava l'operazione senza usare la funzione incorporata. L'operazione in questione, Æṭ, è definito come "traccia", ma la traccia è definita solo per matrici quadrate; Jelly implementa una generalizzazione anche per matrici rettangolari.)

Il miglioramento rispetto alle altre risposte deriva principalmente da un algoritmo più semplice (quindi più rapido da esprimere); questo programma è stato originariamente scritto in Brachylog v2 ( {\p\iᶠ∋₎ᵐ+}ᶠot), ma Jelly ha alcuni builtin per parti del programma che devono essere spiegate in Brachylog, quindi questo è risultato più breve.

Spiegazione

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

Dovrebbe essere chiaro che per qualsiasi soluzione al problema, possiamo consentire alle colonne della matrice originale di mettere quella soluzione sulla diagonale principale. Quindi questa soluzione semplicemente la inverte, trovando tutte le possibili diagonali principali delle permutazioni.

Si noti che l'operazione "permuta le colonne" viene eseguita come "trasponi, permuta le righe" senza preoccuparsi di trasporre indietro; il resto dell'algoritmo sembra essere simmetrico rispetto alla diagonale principale, quindi non abbiamo bisogno di annullare la trasposizione e quindi possiamo salvare un byte.


ZŒ!ÆṭṀsalva quattro byte. Provalo online!
Dennis,

Beh, sembra che Dennis abbia ottenuto l'ultima parola in: P
Quintec, il

Mi chiedo se quell'edilizia sia mai venuta prima?
ais523

Non sono sicuro, ma probabilmente no. In realtà ho suggerito ZŒ!ŒD§ṀḢprima di ricordare che Æṭera una cosa.
Dennis,

8

J , 28 byte

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

Provalo online!

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

Qui viene effettuata la chiamata ricorsiva $:che rappresenta la più grande funzione anonima che la contiene. Siamo fortunati in J ad avere la primitiva x u\. y, che si applica ualle successive "correzioni" diy ottenute sopprimendo le successive correzioni della lunghezza xdegli oggetti y; qui vogliamo sorprendere le colonne successive per ottenere "minori", quindi trasponiamo |:le file inferiori (o coda }.) di y, e quindi ricontattiamo sul recepimento dei loro outfix.


2
Ciao e benvenuto in PPCG! Ho aggiunto un link Provalo online per la tua soluzione, in modo che altri possano verificarlo.
Galen Ivanov,

7

Python 3 , 94 90 89 84 80 byte

-4 byte grazie a xnor (usando set invece di liste)!

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

Provalo online!


Bel metodo! È possibile effettuare yuna serie di accorciare il controllo di appartenenza: 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: Questo -1trucco è davvero intelligente :) Grazie mille!
ბიმო

7

Husk , 12 11 9 byte

▲mȯΣ►L∂PT

Provalo online!

Grazie a BMO per aver suggerito un porto di risposta ais523 e un salvataggio di 2 byte, che sono riuscito a migliorare ulteriormente, e a sua volta BMO ha eliminato altri 2 byte.


Soluzione precedente (14 byte)

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

Provalo online!

Non sono stato in grado di creare una suite di test perché questa risposta utilizza il primo argomento della riga di comando esplicitamente comando. Ma Husk non usa affatto STDIN, quindi ho incluso tutti i casi di test lì, quindi puoi semplicemente copiare e incollare nel campo dell'argomento per verificarlo. Si noti inoltre che le matrici in Husk potrebbero non contenere spazi tra gli elementi durante l'immissione.

Come funziona?

Analisi del codice

▲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.

Esempio

Facciamo un esempio:

(142561)

Uno deve scegliere esattamente un indice da ciascuno in modo tale che non vi siano due indici corrispondenti. Quindi, generiamo gli intervalli di lunghezza delle righe e manteniamo solo quelli senza duplicati, producendo le seguenti combinazioni (ogni combinazione è una colonna anziché una riga per risparmiare spazio):

(121323213132)

Quindi, il programma indicizza negli elenchi di input con ciascun elemento della combinazione, restituendo:

(141242651516)

9


5

JavaScript (ES6),  74  71 byte

Grazie a @tsh per l'identificazione di 2 byte inutili che sono stati utilizzati per correggere un bug
Salvati 3 byte grazie a @tsh

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

Provalo online!


@Shaggy ma è impossibile comporre 0dall'array di input, -1+(-1)è -2ed è la risposta corretta.
dice Val Ripristina Monica il

1
f=([a,...r],k,i=1)=>a?Math.max(...a.map(c=>k&(i+=i)?-1/0:c+f(r,k|i))):0E 'strano, ma Math.maxconsente di risparmiare byte ...
TSH

4

Gelatina , 13 12 byte

ẈŒpQƑƇị"€¹§Ṁ

Provalo online!

Versione alternativa, 11 byte

ZLœ!Lị"€¹§Ṁ

Questo utilizza il nuovo aggiunto œ! built-in incorporato, che genera tutte le permutazioni di una determinata lunghezza.

Provalo online!

Come funziona

ẈŒ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.

Ah ... ho quasi pubblicato la stessa risposta con XLṗLinvece di J€Œp.
Erik the Outgolfer,

4

Haskell , 65 byte

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

Provalo online!

Spiegazione e Ungolfed

La funzione take i<>drop(i+1)prende un elenco e rimuove l'elemento in posizionei .

La funzione fottiene ogni possibile elemento ein posizione i, rimuove gli elementi in posizione idagli elementi rimanenti e aggiunge eall'ottimale calcolato ricorsivamente:

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

E il caso base per l'elenco vuoto è solo 0:

f _=0

2

Brachylog , 18 byte

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

Provalo online!

Spiegazione

                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 byte

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

Provalo online!

Abbastanza corto, anche se lungo permutations chiamata. Questo è un blocco di codice anonimo che accetta un elenco di elenchi e restituisce un numero.

Spiegazione:

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

-13 byte grazie a ngn!

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

Provalo online!

Soluzione iniziale:

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

Provalo online!

Nota: non funziona per il primo caso di test [[1]]

Spiegazione:

{ } - funzione con argomento 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
suggerimento: prmpuò essere applicato direttamente a un elenco per generare le sue permutazioni
ngn

@ngn Grazie! Volevo usare la diagonale principale con =, ma il risultato è stato più lungo. C'è flattenin oK?
Galen Ivanov,

flattenin che senso?
ngn,

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

1
è giusto ,/o se vuoi che entri in strutture più profonde:,//
ngn

2

Haskell , 65 byte

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

Provalo online!


71 byte

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

Provalo online!

I [x|x<-a,y<-a,x==y]==acontrolli che gli elementi di asono distinti. Questo utilizza un numero sorprendente di personaggi, ma non ho visto un modo più breve.


1

Pyth, 15 12 byte

eSms@VQd.plh

Provalo online qui .

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

Modifica: salvato 3 byte per gentile concessione di issacg


1
.PUlhQlpuò essere sostituito da .plh. Vignora implicitamente qualsiasi voce aggiuntiva.
isaacg,

1

05AB1E , 18 13 byte

нgLœε‚øε`è]OZ

Ho la sensazione che sia eccessivamente lungo, ma non sono sicuro di come eseguire l'indicizzazione vettorizzata in modo efficiente byte in 05AB1E .. Ed avevo davvero ragione sul fatto che fosse troppo lungo .. -5 byte grazie a @Emigna .

Provalo online o verifica tutti i casi di test .

Spiegazione:

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

Esempio di esecuzione:

  • Ingresso: [[1,4,2],[5,6,1]]
  • Dopo il passaggio 1 (нgL ):[1,2,3]
  • Dopo il passaggio 2 (œ ):[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
  • Dopo il passaggio 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]]]
  • Dopo il passaggio 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]]]
  • Dopo il passaggio 5 ( ε`è]): [[4,1],[4,5],[2,6],[2,5],[1,6],[1,1]](NOTA: 05AB1E è indicizzato 0 (con avvolgimento automatico), quindi indicizza 3in[5,6,1] risultati in5 .)
  • Dopo il passaggio 6 (O ):[5,9,8,7,7,2]
  • Uscita / dopo il passaggio 7 ( à):9

1
Ho avuto нgLœε‚øεè] OZ` per 13 .
Emigna,

@Emigna Grazie! È sorprendentemente simile a quello che ho visto, tranne per il fatto che ho aggiunto un mucchio di schifezze inutili. ; p
Kevin Cruijssen il



Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.