Maximale aufsummierte Teilfolgen mit nicht benachbarten Elementen


23

Einführung:

Inspiriert von diesen beiden SO-Fragen (ohne Zweifel aus derselben Klasse): Drucken Sie die Elemente in der Unteranordnung mit der maximalen Summe ohne benachbarte Elemente, Java, und der maximalen Summe nicht benachbarter Elemente einer Anordnung, die gedruckt werden sollen .

Herausforderung:

Bei einer Liste von Ganzzahlen wird eine Teilsequenz ausgegeben, die aus nicht benachbarten Elementen mit der höchsten Summe besteht. Hier einige Beispiele:

  • [1,2,3,-1,-3,2,5]würde [1,3,5](mit einer Summe von 9) zu den 0-basierten Indizes führen [0,2,6].
  • [4,5,4,3]würde entweder [4,4](mit einer Summe von 8) bei den 0-basierten Indizes [0,2]oder [5,3](auch mit einer Summe von 8) bei den 0-basierten Indizes ergeben [1,3].
  • [5,5,10,100,10,5]würde [5,100,5](mit einer Summe von 110) entweder zu den 0-basierten Indizes [0,3,5]oder führen [1,3,5].

Was an diesen Beispielen oben am wichtigsten ist, sind die Indizes, die die Elemente enthalten, mindestens 2 voneinander entfernt. Wenn wir uns das Beispiel [5,5,10,100,10,5]genauer ansehen, haben wir die folgende mögliche Folge, die nicht benachbarte Elemente enthält. mit ihren Indizes darunter; mit ihren Summen darunter:

[[5],[10],[100],[10],[5],[5],[100,5],[10,5],[10,10],[5,5],[5,10],[5,100],[5,5],[5,10],[5,100],[5,10],[5,100,5],[5,100,5],[5,10,5],[5,10,10]]   // non-adjacent subsequences
[[5],[ 4],[  3],[ 2],[1],[0],[  3,5],[ 2,5],[ 2, 4],[1,5],[1, 4],[1,  3],[0,5],[0, 4],[0,  3],[0, 2],[1,  3,5],[0,  3,5],[0, 2,5],[0, 2, 4]]   // at these 0-based indices
[  5,  10,  100,  10,  5,  5,    105,    15,     20,   10,    15,    105,   10,    15,    105,    15,      110,      110,      20,       25]   // with these sums
                                                                                                            ^         ^                        // and these two maximums

Da die maximalen Summen sind 110, geben wir [5,100,5]als Ergebnis aus.

Herausforderungsregeln:

  • Sie dürfen Schlüssel-Wert-Paare aus Index + Wert ausgeben. Stattdessen [5,100,5]können Sie also [[0,5],[3,100],[5,5]]oder [[1,5],[3,100],[5,5]]als Ergebnis ausgeben (oder [[1,5],[4,100],[6,5]]/ [[2,5],[4,100],[6,5]]wenn 1-basierte Indexierung anstelle von 0-basierten verwendet wird).
    • Wenn Sie Schlüssel-Wert-Paare verwenden, können diese auch in umgekehrter oder zufälliger Reihenfolge vorliegen, da klar ist, welche Werte aufgrund des gepaarten Index gemeint sind.
    • Die Ausgabe nur der Indizes ohne Werte ist nicht zulässig. Es sollte entweder die Werte oder die Werte / Indizes als Schlüssel-Wert-Paare ausgeben (oder zwei getrennte Listen für 'Schlüssel' und 'Werte' derselben Größe, wenn Schlüssel-Wert-Paare in der Sprache Ihrer Wahl nicht möglich sind).
  • Sie dürfen statt nur einer alle möglichen Teilfolgen mit der maximalen Summe ausgeben.
  • Wie Sie den Beispielen entnehmen können, kann die Eingabeliste auch negative und doppelte Werte enthalten. Sie können davon ausgehen, dass die Eingabe-Ganzzahlen im Bereich .[999,999]
  • Die Ausgabeliste darf nicht leer sein und muss immer mindestens ein Element enthalten (wenn eine Liste nur negative Werte enthalten würde, würde eine Liste mit dem niedrigsten negativen Wert als Ergebnis ausgegeben - siehe die letzten beiden Testfälle).
  • Wenn es eine mögliche Ausgabe gibt, jedoch für mehrere verschiedene Indizes, ist es zulässig, beide auszugeben, obwohl sie möglicherweise doppelt aussehen. (dh das obige Beispiel kann [[5,100,5],[5,100,5]]für beide möglichen Indexkombinationen ausgegeben werden ).

Testfälle:

Input:                   Possible outputs:       At 0-based indices:     With sum:

[1,2,3,-1,-3,2,5]        [1,3,5]                 [0,2,6]                 9
[4,5,4,3]                [4,4]/[5,3]             [0,2]/[1,3]             8
[5,5,10,100,10,5]        [5,100,5]               [0,3,5]/[1,3,5]         110
[10]                     [10]                    [0]                     10
[1,1,1]                  [1,1]                   [0,2]                   2
[-3,7,4,-2,4]            [7,4]                   [1,4]                   11
[1,7,4,-2]               [7]                     [1]                     7
[1,2,-3,-4,5,6,-7]       [2,6]                   [1,5]                   8
[800,-31,0,0,421,726]    [800,726]/[800,0,726]   [0,5]/[0,3,5]/[0,2,5]   1526
[-1,7,8,-5,40,40]        [8,40]                  [2,4]/[2,5]             48
[-5,-18,-3,-1,-10]       [-1]                    [3]                     -1
[0,-3,-41,0,-99,-2,0]    [0]/[0,0]/[0,0,0]       [0]/[3]/[6]/[0,3]/
                                                  [0,6],[3,6]/[0,3,6]    0

Wenn es mehr als eine identische Menge gibt (aber aus verschiedenen Indizes), ist es in Ordnung, alle aufzulisten? zB [5,100,5]zweimal für dein drittes Beispiel.
Nick Kennedy

1
powersetist eine Menge von Teilmengen, nicht wahr? aber es sieht so aus, als würden Sie eine Reihe von Teilsequenzen zurückgeben? [4,5,4,3] würde entweder [4,4] ergeben, wobei [4,4] eindeutig keine Menge ist.
Abgelaufene Daten

1
@Arnauld Ja, wenn die Werte Schlüssel-Wert-Paare mit ihrem Index sind, ist klar, welche indizierten Werte in der Eingabe gemeint sind, sodass sie in beliebiger Reihenfolge vorliegen können. Wird dies auch in der Herausforderungsbeschreibung bearbeiten.
Kevin Cruijssen

2
Nur um sicherzugehen: Die Ausgabe der Indizes ist keine Option, oder?
Shaggy

1
Der klassische Begriff ist "Subsequenz" . Dies hat jedoch das gleiche Problem, wenn Menschen an zusammenhängende Teilsequenzen denken. Ich würde "Teilmenge" sagen, wenn wir hier tatsächlich mit Mengen arbeiten würden, aber dies sind definitiv Sequenzen - Ordnungsangelegenheiten und Duplikate sind zulässig.
user2357112 unterstützt Monica

Antworten:


6

Schale , 11 Bytes

►Σ†!¹mü≈tṖŀ

Probieren Sie es online!

Erläuterung

►Σ†!¹mü≈tṖŀ  Implicit input, say L=[4,5,3,4].
          ŀ  Indices: [1,2,3,4]
         Ṗ   Powerset: [[],[1],[2],[1,2],..,[1,2,3,4]]
        t    Tail (remove the empty list): [[1],[2],[1,2],..,[1,2,3,4]]
     m       For each,
      ü      de-duplicate by
       ≈     differing by at most 1.
             For example, [1,2,4] becomes [1,4].
  †          Deep map
   !¹        indexing into L: [[4],[5],[4],..,[5,4],[4,3]]
►            Maximum by
 Σ           sum: [5,4]

6

Haskell , 60 Bytes

snd.([]%)
r%(h:t)=max(r%t)$(r++[h])%drop 1t
r%_=(sum r<$r,r)

Probieren Sie es online!

Die %Hilfsfunktion verzweigt rekursiv bei der Auswahl, ob das erste Element eingeschlossen und das zweite gelöscht werden soll oder ob das erste Element übersprungen werden soll. Es wird das Maximum aller Ergebnisse verwendet. Hierbei handelt es sich um Tupel, deren erstes Element die Summe und deren zweites Element die entsprechende Liste ist, die für die Ausgabe extrahiert wird.

Um mit der Regel umzugehen, dass die leere Liste auch dann sum r<$rnicht sum rzulässig ist, wenn sie den kleinsten Trick hätte, führen wir einen niedlichen Trick des Schreibens durch, anstatt. Dadurch wird eine Liste erstellt, deren Elemente alle sind sum rund deren Länge die von ist r. Auf diese Weise priorisieren wir bei der Auswahl des Maximums eine Liste gegenüber einer leeren r, ansonsten hängen Vergleiche vom ersten Element ab sum r.


6

R , 136 125 Bytes

function(l,G=unlist(Map(combn,list(y<-seq(a=l)),y,c(function(x)'if'(all(diff(x)>1),l[x],-Inf)),F),F))G[which.max(Map(sum,G))]

Probieren Sie es online!

-6 Bytes dank digEmAll , der mich übrigens auch überrumpelt hat .

Gibt die kürzeste Subsequenz als zurück list, wobei die lexikografischen Bindungen zuerst durch Indizes unterbrochen werden.

Brute-Force generiert alle Index-Teilsequenzen, dann Filters für diejenigen, die nicht benachbart sind, dh wo all(diff(x)>1). Dann Untergruppen [in ldiese Indizes verwendet, die Auswahl [[des ersten , wobei die Summe der max ( which.max).

Ich bin mir ziemlich sicher, dass dies die erste R-Antwort ist, die ich je geschrieben habe und die verwendet Filter! traurig, Filterist ungolfisch, kein Wunder, dass ich es nie benutzt habe ...



@digEmAll danke!
Giuseppe

5

05AB1E , 14 Bytes

Dank Kevin Cruijssen 1 Byte gespeichert

ā<æʒĆ¥≠W}èΣO}θ

Probieren Sie es online! oder als Test Suite

Erläuterung

ā<               # push [0 ... len(input)-1]
  æ              # compute powerset
   ʒ    }        # filter, keep lists where:
      ≠W         # no element is 1 in the
     ¥           # deltas
    Ć            # of the list with the head appended
         è       # index into the input with each
          ΣO}    # sort by sum
             θ   # take the last element

Sie können nicht glücklich sein, aber es ist immer noch 4 Bytes kürzer als meine ursprüngliche Lösung. ;) Und du kannst 1 mehr golfen um ¤ªzu wechseln Ć.
Kevin Cruijssen

@ KevinCruijssen: Oh ja! Aus irgendeinem Grund hatte ich mich selbst überzeugt, dass ich am Ende ein Wiederholungselement brauchte. Vielen Dank!
Emigna

5

Brachylog (v2), 14 Bytes

{~ba~c∋₁ᵐ}ᶠ+ᵒt

Probieren Sie es online!

Funktionsübermittlung; Eingabe von links, Ausgabe von rechts wie gewohnt. Sehr langsam; Eine Liste mit fünf Elementen ist wahrscheinlich das Maximum für Tests mit TIO.

{~ba~c∋₁ᵐ}ᶠ+ᵒt
 ~b              Prepend an arbitrary element to the input
   a             Take a prefix or suffix of the resulting list
    ~c           Ordered partition into contiguous sublists
      ∋₁         Take the second element
        ᵐ          of each sublist
{        }ᶠ      Find all possible ways to do this
           +ᵒ    Sort by sum
             t   Take the greatest

Die Ergebnisse, die wir mit Präfixen erhalten, sind nicht falsch, aber auch nicht interessant. Alle möglichen Ergebnisse werden über ein Suffix generiert (das möglicherweise die Liste selbst ist, aber nicht leer sein darf), aber "Suffix" ist in Brachylog ausführlicher als "Präfix oder Suffix" effizient aber immer noch korrekt). Die Grundidee ist, dass für jedes Element, das in der Ausgabeliste enthalten sein soll, die Partition in zusammenhängende Unterlisten dieses Element und das Element davor in dieselbe Unterliste einfügen muss (da das Element das zweite ist)Element der Unterliste), so dass zwei aufeinanderfolgende Elemente nicht im Ergebnis erscheinen können. Andererseits ist es ziemlich klar, dass jede Liste ohne zwei aufeinanderfolgende Elemente im Ergebnis erscheinen kann. Wenn wir also alle möglichen Kandidatenlisten haben, können wir einfach die Summen von allen nehmen und sehen, welche die größte ist.



3

JavaScript (ES6),  138 132 130 129  126 Bytes

Gibt Schlüssel-Wert-Paare aus.

a=>a.reduce((a,x,i)=>[...a,...a.map(y=>[[x,i],...y])],[[]]).map(m=a=>a.some(s=p=([v,i])=>p-(s=~~s+v,p=i)<2)|s<m||(r=a,m=s))&&r

Probieren Sie es online!

Schritt 1

[veinlue,ichndex]

a.reduce((a, x, i) => // for each value x at position i:
  [                   //   update a[] to a new array consisting of:
    ...a,             //     all previous entries
    ...a.map(y =>     //     for each value y in a[]:
      [[x, i], ...y]  //       append [x, i], followed by all original entries
    )                 //     end of map()
  ],                  //   end of new array
  [[]]                //   start with a = [[]]
)                     // end of reduce()

Schritt 2

mr

.map(m =              // initialize m to a non-numeric value
  a =>                // for each entry a[] in the powerset:
  a.some(s = p =      //   initialize s and p to non numeric values
    ([v, i]) =>       //   for each value v and each index i in a[]:
    p - (             //     compute p - i
      s = ~~s + v,    //     add v to s
      p = i           //     update p to i
    ) < 2             //     if p - i is less than 2, yield true
  ) |                 //   end of some()
  s < m ||            //   unless some() was truthy or s is less than m,
  (r = a, m = s)      //   save a[] in r[] and update m to s
) && r                // end of map(); return r[]

3

Haskell, 81-80 Bytes

snd.maximum.map((,)=<<sum).tail.f
f(a:b:c)=f(b:c)++map(a:)(f c)
f a=[]:map(:[])a

Probieren Sie es online!

fErstellt alle gültigen Teilsequenzen, indem entweder das nächste Element übersprungen ( f(b:c)) oder es verwendet und das nächste übersprungen ( map(a:)(f c)) und der Rest rekursiv bearbeitet wird. Erstellen Sie für das Ergebnis alle Untersequenzen ( f), löschen Sie die leere Untersequenz (die zuerst in der Liste vorkommt:) tail, bilden Sie Paare (<sum>,<subsequence>)( map((,)=<<sum)), ermitteln Sie das Maximum (Paare werden in lexikografischer Reihenfolge verglichen) -> maximum) und löschen Sie die Summe ( snd).

Bearbeiten: -1 Byte dank @Lynn.


1
map(:[])aist ein Byte kürzer als (pure<$>a)^^
Lynn


3

T-SQL, 122 119 118 Bytes

Die Eingabe ist eine Tabellenvariable.

Diese Abfrage wählt alle Elemente aus der Tabellenvariablen aus, kombiniert diese mit allen nicht benachbarten Elementen mit höheren Positionswerten und zeigt den Text an, der für die höchste Summe dieser Werte generiert wurde.

WITH C(y,j,v)as(SELECT*,x*1FROM @
UNION ALL
SELECT y+','+x,i,v+x
FROM @ JOIN C ON~-i>j)SELECT
TOP 1y FROM C ORDER BY-v

Probieren Sie es online ungolfed



2

Pyth, 19 Bytes

esDm@LQdtf!q#1.+TyU

Versuchen Sie es online hier oder überprüfen alle Testfälle auf einmal hier .

esDm@LQdtf!q#1.+TyUQ   Implicit: Q=eval(input())
                       Trailing Q inferred
                  UQ   Generate range [0-len(Q))
                 y     Take the powerset of the above
         f             Filter keep elements of the above, as T, using:
              .+T        Take differences of consecutive elements of T
           q#1           Keep those differences equal to 1
          !              Logical NOT - empty lists evaluate to true, populated ones to false
                       Result of the filter is those sets without consecutive numbers
        t              Drop the first element (empty set)
   m                   Map the remaining sets, as d, using:
     L d                 For each element of d...
    @ Q                  ... get the element in Q with that index
 sD                    Order the sets by their sum
e                      Take the last element, implicit print

2

Gaia , 24 Bytes

e:w;ċz⟨ọ1>¦ẏ⟩⁇‼⁇E‡ev2%Σ⌠

Probieren Sie es online!

Ugh, E‡hat einige seltsame Dinge ... nach der Dokumentation, es sollte so etwas wie „gegebene Länge tun iMenge von Listen Xund Länge jReihe von Indizes Y, Return X[i][Y[j]]“, sondern kehrt [X[i][Y[j]] X[i][Y[-j]]in Negativ Indizierung das Komplement darstellt, so dass wir tun müssen , ev2%um extrahiere nur die, die wir wollen.

e				| eval as a list l
 :				| dup
  w				| wrap as a list
   ;				| push l again
    ċ				| push [1..len(l)]
     z				| push all subsets of [1..len(l)] -- index powerset.
      ⟨      ⟩⁇			| filter this for:
       ọ			| deltas
        1>¦			| are greater than 1
           ẏ			| all (all deltas greater than 1)
	       ‼⁇		| filter for non-empty lists
		 E‡		| table extract elements. Given l and index set i, this pushes
				| [l[i] l[setdiff(1..l,i)]] for some reason
		   ev2%		| get the l[i] only by unlisting, reversing, and taking every other element
		       Σ⌠	| Get the one with the maximum sum

Warum hat die Ausgabe aus Neugier zwei nachgestellte ]]anstelle von einem?
Kevin Cruijssen

@ KevinCruijssen Nur eine weitere lustige Eigenart des Dolmetschers; Alle Listen werden so ausgedruckt, sodass sie [[1] [2]]gedruckt werden, [[1]] [2]]]]was das Lesen und Debuggen der Listenausgabe extrem erschwert.
Giuseppe

Ich denke, es liegt am Ausdruck re.sub(" ?$","]",result)im Interpreter, der stattdessen sein sollte, re.sub(" +$","]",result)aber meine Python ist super schlecht.
Giuseppe


2

Wolfram Sprache (Mathematica) , 70 63 Bytes

MaximalBy[Select[q=Rest@Subsets@#,!FreeQ[q,#~Riffle~_]&],Tr,1]&

Probieren Sie es online!

High-Level-Suche

          Select[q=Rest@Subsets@#,                     ]        (*choose nonempty subsets of the input such that*)
                                  !FreeQ[q,          ]&         (*there exists a subset of the input which matches*)
                                           #~Riffle~_           (*this list, with an item inserted between adjacent elements*)
MaximalBy[                                              ,Tr,1]& (*and return one with the greatest total*)

,1ist erforderlich, um nicht versehentlich ungültige Mengen zurückzugeben (andernfalls würde z. B. eine Eingabe von {1,1,1}zu einer Ausgabe von führen {{1,1},{1,1},{1,1}}).


1

Haskell , 300 168 Bytes

import Data.List
h[]=1>2
h(x:y)=fst$foldl(\a c->((fst a)&&(c-snd a>1),c))(1<2,x)y
z=snd.last.sortOn fst.map((,)=<<sum.snd).filter(h.fst).map unzip.subsequences.zip[0..]

Probieren Sie es online!

-132 Bytes danke an alle Rückmeldungen von @nimi :)


Original

Ungolfed (original)

import Data.List
import Data.Function

f :: [Int] -> [(Int, Int)] -- attach indices for later use
f [] = []
f xs = zip xs [0..length xs]

g :: [[(Int, Int)]] -> [([Int], [Int])] -- rearrange into list of tuples
g [] = []
g (x:xs) = (map fst x, map snd x) : g xs

h :: [Int] -> Bool -- predicate that checks if the indices are at least 2 apart from each other
h [] = False
h (x:xs) = fst $ foldl (\acc curr -> ((fst acc) && (curr - snd acc > 1), curr)) (True, x) xs
j :: [([Int], [Int])] -> [([Int], [Int])] -- remove sets that don't satisfy the condition
j xs = filter (\(elements, indices) -> h indices) xs

k :: [([Int], [Int])] -> [(Int, ([Int], [Int]))] -- calculate some of elements
k xs = map (\(elements, indices) -> (foldl1 (+) elements, (elements, indices))) xs

l :: [(Int, ([Int], [Int]))] -> ([Int], [Int]) -- grab max
l xs = snd $ last $ sortBy (compare `on` fst) xs

z -- put things together
```

1
Einige Tipps: Klappen Sie das Element und seinen Index innerhalb der von f: zurückgegebenen Paare um f x=zip[0..length x]x, so fwird f=zip[0..]. gist einfach g=map unzip. Die Funktion, mit der gefiltert werden soll, jist h.fst(<- gespiegelte Paare!). j=filter(h.fst). Das foldl1+aus kist sumund mit einem pointfree Paar machen k=map((,)=<<sum.snd). sortBy(...)kann ersetzt werden durch sortOn fst: l=snd.last.sortOn fst. Da Sie alle Funktionen nur einmal verwenden, können Sie sie schließlich in einen einzelnen punktfreien Ausdruck einbetten:z=snd.last.sortOn fst.map((,)=<<sum.snd).filter(h.fst).map unzip.subsequences.zip[0..]
nimi


oh, und kein import Data.Functionmehr nötig .
Nimi

Das ist toll, danke für das Feedback :)
Bugs

Als nächstes hsuchen wir nach nicht benachbarten Elementen, dh die Differenz benachbarter Indizes muss sein >1. zipWith(-)=<<tailbaut eine solche Liste der Unterschiede auf, scheitert aber an der leeren Liste, also brauchen wir eine zusätzliche tailauf dersubsequences , um sie loszuwerden. Wieder inline. Probieren Sie es online!
nimi

1

Kohle , 46 Bytes

≔⟦υ⟧ηFθ«≔υζ≔Eη⁺κ⟦ι⟧υ≔⁺ζηη»≔Φ⁺υηιη≔EηΣιζI§η⌕ζ⌈ζ

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

≔⟦υ⟧η

Die Variable uist mit einer leeren Liste vordefiniert. Dies wird in eine Liste eingetragen, die zugeordnet ist h. Diese Variablen wirken als Akkumulatoren. uEnthält die Unterlisten, die das neueste Element der Eingabe enthalten, qwährend hdie Unterlisten, die dies nicht tun, enthalten sind (und daher zum Anhängen des nächsten Elements der Eingabe geeignet sind).

Fθ«

Schleife über die Elemente der Eingabe.

≔υζ

Speichern Sie die Liste der Unterlisten, die das vorherige Element enthalten.

≔Eη⁺κ⟦ι⟧υ

Nehmen Sie alle Unterlisten, die das vorherige Element nicht enthalten, hängen Sie das aktuelle Element an und speichern Sie das Ergebnis als Liste der Unterlisten, die das aktuelle Element enthalten. (Ich benutze Pushhier nicht , da ich die Liste klonen muss.)

≔⁺ζηη»

Verketten Sie die beiden vorherigen Unterlisten mit der neuen Liste der Unterlisten, die das aktuelle Element nicht enthalten.

≔Φ⁺υηιη

Verketten Sie die Unterlisten ein letztes Mal und entfernen Sie die ursprüngliche leere Liste (die Charcoal sowieso nicht summieren kann).

≔EηΣιζ

Berechnen Sie die Summen aller Unterlisten.

I§η⌕ζ⌈ζ

Suchen Sie einen Index der größten Summe und geben Sie die entsprechende Unterliste aus.



1

Japt -h , 21 Bytes

Haben Sie jemals eine dieser Herausforderungen erlebt, bei denen Sie das Golfen völlig vergessen haben ?!

ð¤à fÊk_än ø1îmgUÃñx

Versuch es

ð¤à fÊk_än ø1îmgUÃñx     :Implicit input of array U
ð                         :Indices of elements that return true when
 ¤                        :  Converted to a base-2 string (to account for 0s)
  à                       :Combinations
    f                     :Filter by
     Ê                    :  Length (to remove the empty combination)
      k_                  :Remove elements that return true
        än                :  Deltas
           ø1             :  Contains 1
             Ã            :End remove
              ®           :Map
               m          :  Map
                gU        :    Index into U
                  Ã       :End map
                   ñ      :Sort by
                    x     :  Sum
                          :Implicit output of last element

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.