Maximum summed subsequences with non-adjacent items
Husk, 11 bytes
►Σ†!¹mü≈tṖŀ
Try it online!
Explanation
►Σ†!¹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]
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))]
Try it online!
-6 bytes thanks to digEmAll, who incidentally also outgolfed me.
Returns the shortest subsequence as a list
, breaking ties on lexicographically first by indices.
Brute-force generates all index subsequences, then Filter
s for those that are non-adjacent, i.e., where all(diff(x)>1)
. Then subsets [
into l
using these indices, selecting [[
the first one where the sum is the max (which.max
).
I'm pretty sure this is the first R answer I've ever written that uses sad, Filter
!Filter
is ungolfy, no wonder I've never used it...
Haskell, 60 bytes
snd.([]%)
r%(h:t)=max(r%t)$(r++[h])%drop 1t
r%_=(sum r<$r,r)
Try it online!
The helper function %
recursively branches on choosing whether the include the first element and drop the second, or to skip the first element. It takes the maximum of all outcomes, which are tuples whose first element is the sum, and whose second element is the corresponding list which is extracted for the output.
To handle the rule that the empty list is disallowed even if it would have the smallest trick, we do a cute trick of writing sum r<$r
rather than sum r
.This makes a list whose elements all are sum r
and whose length is that of r
. That way, when we choose the maximum, we prioritize any list over an empty r
, but otherwise comparisons depend on the first element which is sum r
.