Nombre maximum de sous-séquences additionnées avec des éléments non adjacents

23

Introduction:

Inspiré de ces deux questions SO (sans doute de la même classe): imprimer les éléments dans le sous-tableau de la somme maximale sans éléments adjacents java et de la somme maximale des éléments non adjacents d'un tableau, à imprimer .

Défi:

Étant donné une liste d'entiers, sortez une sous-séquence composée d'éléments non adjacents qui ont la somme la plus élevée. Voici quelques exemples:

  • [1,2,3,-1,-3,2,5]entraînerait [1,3,5](avec une somme de 9) aux indices de base 0 [0,2,6].
  • [4,5,4,3]entraînerait soit [4,4](avec une somme de 8) aux indices de base 0 [0,2]ou [5,3](également avec une somme de 8) aux indices de base 0 [1,3].
  • [5,5,10,100,10,5]se traduirait par [5,100,5](avec une somme de 110) aux indices basés sur 0 [0,3,5]ou [1,3,5].

Ce qui est le plus important dans ces exemples ci-dessus, les indices contenant les éléments sont au moins 2 séparés les uns des autres. Si nous regardons l'exemple [5,5,10,100,10,5]plus en profondeur: nous avons la sous-séquence potentielle suivante contenant des éléments non adjacents; avec leurs indices en dessous; avec leurs sommes en dessous:

[[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

Puisque les sommes maximales sont 110, nous sortons [5,100,5]comme résultat.

Règles du défi:

  • Vous êtes autorisé à générer des paires clé-valeur de la valeur index +. Ainsi, au lieu de [5,100,5]vous, vous pouvez générer [[0,5],[3,100],[5,5]]ou [[1,5],[3,100],[5,5]]comme résultat (ou [[1,5],[4,100],[6,5]]/ [[2,5],[4,100],[6,5]]lorsque l'indexation basée sur 1 est utilisée au lieu de basée sur 0).
    • Si vous utilisez des paires clé-valeur, elles peuvent également être dans un ordre inverse ou aléatoire, car il est clair quelles valeurs sont signifiées en raison de l'index apparié.
    • La sortie uniquement des index sans valeurs n'est pas autorisée. Il doit soit afficher les valeurs, soit les valeurs / indices sous forme de paires clé-valeur (ou deux listes séparées pour les `` clés '' et les `` valeurs '' de la même taille si les paires clé-valeur ne sont pas possibles dans la langue de votre choix).
  • Vous êtes autorisé à sortir toutes les sous-séquences possibles avec la somme maximale au lieu d'une seule.
  • Comme vous pouvez le voir dans les exemples, la liste d'entrée peut également contenir des valeurs négatives et dupliquées. Vous pouvez supposer que les entiers d'entrée sont dans la plage [999,999] .
  • La liste de sortie ne peut pas être vide et doit toujours contenir au moins un élément (si une liste ne contiendrait que des valeurs négatives, une liste contenant la valeur négative la plus basse unique serait alors sortie en résultat - voir les deux derniers cas de test).
  • S'il existe une sortie possible mais pour plusieurs indices différents, il est autorisé de les sortir tous les deux, même s'ils peuvent sembler en double. (c.-à-d. l'exemple ci-dessus, peut sortir [[5,100,5],[5,100,5]]pour les deux combinaisons d'index possibles).

Cas de test:

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
Kevin Cruijssen
la source
S'il y a plus d'un ensemble identique (mais à partir d'indices différents), est-il acceptable de tous les énumérer? par exemple [5,100,5]deux fois pour votre troisième exemple.
Nick Kennedy
1
powersetest un ensemble de sous-ensembles n'est-ce pas? mais il semble que vous retourniez un ensemble de sous-séquences? [4,5,4,3] entraînerait soit [4,4] où [4,4] n'est clairement pas un ensemble.
Données expirées le
1
@Arnauld Oui, si les valeurs sont des paires clé-valeur avec leur index, il est clair quelles valeurs indexées sont destinées à l'entrée, afin qu'elles puissent être dans n'importe quel ordre. Modifie également cela dans la description du défi.
Kevin Cruijssen
2
Juste pour être sûr: la sortie des indices n'est pas une option, n'est-ce pas?
Shaggy
1
Le terme classique est "sous-séquence" . Cela a le même problème de personnes qui pensent aux sous-séquences contiguës, cependant. Je dirais "sous-ensemble" si nous travaillions réellement avec des ensembles ici, mais ce sont certainement des séquences - les questions d'ordre et les doublons sont autorisés.
user2357112 prend en charge Monica

Réponses:

6

Husk , 11 octets

►Σ†!¹mü≈tṖŀ

Essayez-le en ligne!

Explication

►Σ†!¹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]
Zgarb
la source
6

Haskell , 60 octets

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

Essayez-le en ligne!

La fonction d'assistance se %ramifie récursivement en choisissant si le premier élément doit être inclus et le deuxième supprimé, ou si le premier élément est ignoré. Il prend le maximum de tous les résultats, qui sont des tuples dont le premier élément est la somme, et dont le deuxième élément est la liste correspondante qui est extraite pour la sortie.

Pour gérer la règle selon laquelle la liste vide est interdite même si elle aurait la plus petite astuce, nous faisons une astuce d'écriture sum r<$rplutôt que sum r. Cela crée une liste dont tous les éléments sont sum ret dont la longueur est celle de r. De cette façon, lorsque nous choisissons le maximum, nous priorisons n'importe quelle liste sur une liste vide r, mais sinon les comparaisons dépendent du premier élément qui est sum r.

xnor
la source
6

R , 136 125 octets

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))]

Essayez-le en ligne!

-6 octets grâce à digEmAll , qui d'ailleurs m'a également surpassé .

Renvoie la sous-séquence la plus courte sous la forme d'un list, rompant les liens lexicographiquement en premier par les indices.

La force brute génère toutes les sous-séquences d'index, puis Filters pour celles qui ne sont pas adjacentes, c'est-à-dire où all(diff(x)>1). Sous-ensembles ensuite [en lutilisant ces indices, en sélectionnant [[le premier où la somme est le max ( which.max).

Je suis presque sûr que c'est la première réponse R que j'aie jamais écrite qui utilise Filter! triste, Filtern'est pas golfique, pas étonnant que je ne l'ai jamais utilisé ...

Giuseppe
la source
130
digEmAll
@digEmAll merci!
Giuseppe
5

05AB1E , 14 octets

1 octet enregistré grâce à Kevin Cruijssen

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

Essayez-le en ligne! ou comme suite de tests

Explication

ā<               # 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
Emigna
la source
Vous n'êtes peut-être pas satisfait, mais c'est toujours 4 octets de moins que ma solution initiale. ;) Et vous pouvez jouer au golf 1 de plus ¤ªen Ć.
Kevin Cruijssen
@KevinCruijssen: Oh ouais! Pour une raison quelconque, je m'étais convaincu que j'avais besoin d'un élément de répétition à la fin. Merci!
Emigna
5

Brachylog (v2), 14 octets

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

Essayez-le en ligne!

Soumission de fonction; entrée par la gauche, sortie par la droite, comme d'habitude. Très lent; une liste de cinq éléments est probablement le maximum pour les tests sur 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

Les résultats que nous obtenons des préfixes ne sont pas incorrects, mais ne sont pas non plus intéressants; tous les résultats possibles sont générés en prenant un suffixe (qui est peut-être la liste elle-même, mais ne peut pas être vide), mais "suffixe" est plus verbeux dans Brachylog que "préfixe ou suffixe", donc je suis allé avec la version qui est terser (et moins efficace mais toujours correct). L'idée de base est que pour chaque élément que nous voulons dans la liste de sortie, la partition en sous-listes contiguës doit placer cet élément et l'élément avant dans la même sous-liste (car l'élément est le deuxièmeélément de la sous-liste), donc deux éléments consécutifs ne peuvent pas apparaître dans le résultat. En revanche, il est assez clair que toute liste sans deux éléments consécutifs peut apparaître dans le résultat. Donc, une fois que nous avons toutes les listes de candidats possibles, nous pouvons simplement prendre la somme de toutes et voir laquelle est la plus grande.

ais523
la source
3

Gelée , 16 14 octets

JŒPḊf’$ÐḟịµSÞṪ

Essayez-le en ligne!

Merci à @EriktheOutgolfer pour avoir économisé 2 octets!

Nick Kennedy
la source
14 octets .
Erik the Outgolfer
3

JavaScript (ES6),  138 132 130 130 129  126 octets

Génère des paires clé-valeur.

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

Essayez-le en ligne!

Étape 1

[value,index]

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()

Étape 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[]
Arnauld
la source
3

Haskell, 81 80 octets

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

Essayez-le en ligne!

fconstruit toutes les sous-séquences valides soit en sautant l'élément suivant ( f(b:c)), soit en l'utilisant et en sautant le suivant ( map(a:)(f c)) et en travaillant récursivement sur le reste. Pour le résultat, créez toutes les sous-séquences ( f), supprimez la sous-séquence vide (qui apparaît en premier dans la liste:) tail, créez des paires (<sum>,<subsequence>)( map((,)=<<sum)), trouvez le maximum (les paires sont comparées dans l'ordre lexicographique) -> maximum) et supprimez la somme ( snd).

Edit: -1 octet grâce à @Lynn.

nimi
la source
1
map(:[])aest un octet plus court que (pure<$>a)^^
Lynn
3

T-SQL, 122 119 118 octets

L'entrée est une variable de table.

Cette requête sélectionne tous les éléments de la variable de table, en les combinant avec tous les éléments non adjacents avec des valeurs de position plus élevées et affiche le texte généré pour la somme la plus élevée de ces valeurs.

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

Essayez-le en ligne sans golf

t-clausen.dk
la source
2

Pyth, 19 octets

esDm@LQdtf!q#1.+TyU

Essayez-le en ligne ici ou vérifiez tous les cas de test en même temps ici .

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
Sok
la source
2

Gaia , 24 octets

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

Essayez-le en ligne!

Ugh, E‡fait des trucs bizarres ... selon la documentation, il devrait faire quelque chose comme "un iensemble de longueur donné de listes Xet un jensemble d'indices de longueur Y, return X[i][Y[j]]", mais renvoie à la place [X[i][Y[j]] X[i][Y[-j]]où l'indexation négative représente le complément, donc nous devons faire ev2%pour extraire uniquement ceux que nous voulons.

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
Giuseppe
la source
Par curiosité, pourquoi la sortie a-t-elle deux suiveurs ]]au lieu d'un?
Kevin Cruijssen
@KevinCruijssen Juste une autre bizarrerie amusante de l'interprète; toutes les listes sont imprimées comme ça, donc elles [[1] [2]]sont imprimées, [[1]] [2]]]]ce qui rend la lecture / débogage de la sortie de liste très difficile.
Giuseppe
Je pense que c'est à cause de l'expression re.sub(" ?$","]",result)dans l'interpréteur qui devrait plutôt l'être re.sub(" +$","]",result)mais mon python est super mauvais.
Giuseppe
2

R , 108 107 octets

function(v,M=-Inf){for(j in J<-seq(a=v))for(i in combn(J,j,,F))if(all(diff(i)>1)&sum(v[i])>sum(M))M=v[i]
M}

Essayez-le en ligne!

-1 grâce à @Giuseppe

digEmAll
la source
2

Wolfram Language (Mathematica) , 70 63 octets

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

Essayez-le en ligne!

Recherche de haut niveau

          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*)

,1est requis pour ne pas renvoyer par inadvertance des ensembles invalides (sinon, par exemple, une entrée de {1,1,1}entraînerait une sortie de {{1,1},{1,1},{1,1}})

attinat
la source
1

Haskell , 300 168 octets

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

Essayez-le en ligne!

-132 octets grâce à tous les retours de @nimi :)


Original

Non golfé (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
```
bogues
la source
1
Quelques conseils: renversent l'élément et son index dans les paires retournées par f: f x=zip[0..length x]x, donc fdevient f=zip[0..]. gest juste g=map unzip. La fonction à filtrer avec in jest h.fst(<- paires inversées!). j=filter(h.fst). Le foldl1+from kest sumet avec une paire sans point k=map((,)=<<sum.snd). sortBy(...)peut être remplacé par sortOn fst: l=snd.last.sortOn fst. Enfin, comme vous n'utilisez toutes les fonctions qu'une seule fois, vous pouvez les intégrer en une seule expression sans point:z=snd.last.sortOn fst.map((,)=<<sum.snd).filter(h.fst).map unzip.subsequences.zip[0..]
nimi
oh, et plus besoin d'importer Data.Function.
nimi
C'est super, merci pour les commentaires :)
bugs
Ensuite h: nous recherchons des éléments non adjacents, c'est-à-dire que la différence des indices adjacents doit être >1. zipWith(-)=<<tailconstruit une telle liste de différences, mais échoue pour la liste vide, nous avons donc besoin d'un supplément tailsur le subsequencespour s'en débarrasser. À nouveau en ligne. Essayez-le en ligne!
nimi
1

Fusain , 46 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

≔⟦υ⟧η

La variable uest prédéfinie avec une liste vide. Ceci est mis dans une liste qui est affectée à h. Ces variables agissent comme des accumulateurs. ucontient les sous-listes qui incluent le dernier élément de l'entrée qtandis que hcontient les sous-listes qui ne le font pas (et sont donc adaptées pour ajouter l'élément suivant de l'entrée).

Fθ«

Faites une boucle sur les éléments de l'entrée.

≔υζ

Enregistrez la liste des sous-listes qui contiennent l'élément précédent.

≔Eη⁺κ⟦ι⟧υ

Prenez toutes les sous-listes qui ne contiennent pas l'élément précédent, ajoutez l'élément actuel et enregistrez le résultat en tant que liste de sous-listes qui contiennent l'élément actuel. (Je ne l'utilise pas Pushici car j'ai besoin de cloner la liste.)

≔⁺ζηη»

Concatène les deux sous-listes précédentes dans la nouvelle liste de sous-listes qui ne contiennent pas l'élément actuel.

≔Φ⁺υηιη

Concaténez les sous-listes une dernière fois et supprimez la liste vide d'origine (que Charcoal ne peut pas additionner de toute façon).

≔EηΣιζ

Calculez les sommes de toutes les sous-listes.

I§η⌕ζ⌈ζ

Trouvez un indice de la plus grande somme et sortez la sous-liste correspondante.

Neil
la source
1

Japt -h , 22 octets

Êo à k_mÄ øZÃm!gU
fÊñx

Essayez-le

Incarnation de l'ignorance
la source
1

Japt -h , 21 octets

Avez-vous déjà eu un de ces défis où vous oubliez complètement comment jouer au golf?!

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

Essayez-le

ð¤à 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
Hirsute
la source
1

Python 2 , 63 70 65 octets

f=lambda a:a and max([a[:1],a[:1]+f(a[2:]),f(a[1:])],key=sum)or a

Essayez-le en ligne!

5 octets de thx à ArBo

Chas Brown
la source
Votre scénario de test [1, 7, 4, -2] [1, 4] 5 7obtient la mauvaise réponse.
xnor
@xnor: corrigé maintenant.
Chas Brown
65 octets
ArBo