隣接していないアイテムの最大合計サブシーケンス


23

前書き:

これら2つのSO質問(同じクラスからの疑いのない質問)に触発された:隣接要素なしの最大合計のサブ配列の要素javaおよび配列の非隣接要素の最大合計を印刷します。

チャレンジ:

整数のリストが与えられた場合、最高の合計を持つ非隣接要素で構成されるサブシーケンスを出力します。ここにいくつかの例があります:

  • [1,2,3,-1,-3,2,5]は、0から始まるインデックスで[1,3,5](合計で9)になります[0,2,6]
  • [4,5,4,3]いずれかをもたらすであろう[4,4](の和と80ベースのインデックスで)[0,2]又は[5,3](もの和と80ベースのインデックスで)[1,3]
  • [5,5,10,100,10,5]は、0ベースのインデックスまたはのいずれかで[5,100,5](合計で110)になります。[0,3,5][1,3,5]

上記のこれらの例で最も重要なのは、要素を含むインデックスが少なくとも2つ離れていることです。この例を[5,5,10,100,10,5]さらに詳しく見ると、非隣接アイテムを含む次の潜在的なサブシーケンスがあります。インデックスがその下にあります。以下の合計で:

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

最大合計はなので110[5,100,5]結果として出力します。

チャレンジルール:

  • インデックス+値のキーと値のペアを出力できます。だから、代わりに[5,100,5]あなたが出力できる[[0,5],[3,100],[5,5]][[1,5],[3,100],[5,5]](あるいはその結果[[1,5],[4,100],[6,5]]/ [[2,5],[4,100],[6,5]]1ベースのインデックスを使用代わりの0ベースされている場合)。
    • キーと値のペアを使用する場合、ペアのインデックスが原因でどの値が意図されているかが明確であるため、それらは逆順またはランダムな順序にすることもできます。
    • 値なしでインデックスのみを出力することは許可されていません。値、または値/インデックスをキーと値のペアとして出力する必要があります(または、選択した言語でキーと値のペアが使用できない場合は、同じサイズの「キー」と「値」の2つの分離リスト)。
  • 1つではなく、最大合計ですべての可能なサブシーケンスを出力できます。
  • 例からわかるように、input-listには負の値と重複した値を含めることもできます。あなたは、入力整数の範囲内にあると仮定することができ[999,999]
  • output-listを空にすることはできず、常に少なくとも1つの要素を含める必要があります(リストに負の値のみが含まれる場合、単一の最小の負の値を含むリストが結果として出力されます-最後の2つのテストケースを参照)。
  • 可能な出力が1つあるが、複数の異なるインデックスの場合、重複しているように見えても、両方を出力できます。(つまり、上記の例では[[5,100,5],[5,100,5]]、可能なインデックスの組み合わせの両方について出力することができます)。

テストケース:

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

複数の同一のセットがある場合(ただし、異なるインデックスから)、それらをすべてリストしても問題ありませんか?たとえば[5,100,5]、3番目の例では2回。
ニックケネディ

1
powersetサブセットのセットではありませんか?しかし、あなたは一連のサブシーケンスを返しているように見えますか?[4,5,4,3]は、[4,4]が明らかにセットではない[4,4]のいずれかになります
期限切れデータ

1
@Arnauldはい、値がインデックス付きのキーと値のペアである場合、入力でどのインデックス値が意図されているかが明確なので、任意の順序にすることができます。また、これをチャレンジの説明に編集します。
ケビンクルーッセン

2
念のため、インデックスの出力はオプションではありませんか?
シャギー

1
古典的な用語は"subsequence"です。しかし、これには、連続したサブシーケンスを考える人々の同じ問題があります。ここで実際にセットを操作している場合、「サブセット」と言いますが、これらは間違いなくシーケンスです-順序の問題と重複は許可されています。
user2357112は、Monica

回答:


6

、11バイト

►Σ†!¹mü≈tṖŀ

オンラインでお試しください!

説明

►Σ†!¹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バイト

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

オンラインでお試しください!

ヘルパー関数%は、最初の要素を含めて2番目の要素をドロップするか、最初の要素をスキップするかを選択すると、再帰的に分岐します。すべての結果の最大値を取ります。これは、最初の要素が合計であり、2番目の要素が出力用に抽出される対応するリストであるタプルです。

空のリストは最小のトリックであっても許可されないというルールを処理するためにsum r<$rsum r。ではなくかわいいトリックを作成します。これにより、すべての要素がsum rあり、長さがのリストが作成されrます。このようにして、最大値を選択すると、空のリストよりもリストの優先順位が高くなりますrが、それ以外の場合、比較はである最初の要素に依存しsum rます。


6

R136125バイト

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

オンラインでお試しください!

-6のおかげバイトdigEmAll偶然にも、私をoutgolfedを

最短のサブシーケンスをaとして返しますlist。最初に辞書順でインデックスを結び付けます。

ブルートフォースは、すべてのインデックスサブシーケンスを生成し、次にFiltersが隣接していないサブシーケンス、つまりのサブシーケンスを生成しますall(diff(x)>1)。次に、これらのインデックス[l使用してサブセットを作成し[[、合計が最大である最初のインデックスを選択します(which.max)。

これは私がこれまでに書いた最初のRの回答であると確信していますFilter悲しいです、Filter私はそれを使用したことがないのも不思議ではありません...



@digEmAllありがとう!
ジュゼッペ

5

05AB1E、14バイト

Kevin Cruijssenのおかげで1バイト節約

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

オンラインでお試しください! またはテストスイートとして

説明

ā<               # 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

あなたは幸せではないかもしれませんが、それでも私の最初の解決策よりも4バイト短いです。;)そして、あなたはより多くのゴルフ1を変更することが可能¤ªĆ
ケビンクルーッセン

@KevinCruijssen:そうそう!何らかの理由で、私は最後に繰り返し要素が必要だと確信していました。ありがとう!
エミグナ

5

Brachylog(v2)、14バイト

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

オンラインでお試しください!

関数の提出。通常どおり、左からの入力、右からの出力。非常に遅い; 5要素のリストは、おそらく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

プレフィックスから得られる結果は間違っていませんが、興味深いものでもありません。可能なすべての結果はサフィックス(リスト自体である可能性がありますが、空にはできません)を使用して生成されますが、「サフィックス」は「プレフィックスまたはサフィックス」よりもBrachylogでより冗長なので、私はより簡潔なバージョンを使用しました効率的ですが、まだ正しい)。基本的な考え方は、出力リストに必要な各要素について、連続したサブリストへのパーティションは、その要素とその前の要素を同じサブリストに配置する必要があるということです(要素は2番目であるためサブリストの要素)、したがって、2つの連続した要素を結果に表示することはできません。一方、2つの連続した要素のないリストが結果に表示される可能性があることはかなり明らかです。したがって、可能なすべての候補リストができたら、それらすべての合計を取得して、どれが最大かを確認できます。



3

JavaScriptの(ES6)、 138の132 130 129  126バイト

キーと値のペアを出力します。

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

オンラインでお試しください!

ステップ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()

ステップ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バイト

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

オンラインでお試しください!

f次の要素をスキップする(f(b:c))か、それを使用して次の要素をスキップする()ことにより、すべての有効なサブシーケンスを構築map(a:)(f c)し、残りを再帰的に処理します。結果を得るには、すべてのサブシーケンスを構築し(f)、空のサブシーケンスをドロップし(リストの最初に出現します:)、tailペアを作成し(<sum>,<subsequence>)map((,)=<<sum))、最大値を見つけます(ペアは辞書式順序で比較されます)-> maximum)、合計をドロップします(snd)。

編集:@Lynnのおかげで-1バイト。


1
map(:[])aは、(pure<$>a)^^ より短いバイトです
Lynn


3

T-SQL、122 119 118バイト

入力はテーブル変数です。

このクエリは、テーブル変数からすべての要素を選択し、これらをより高い位置値を持つすべての非隣接要素と組み合わせ、これらの値の最大合計に対して生成されたテキストを表示します。

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

オンラインで試してみる



2

Pyth、19バイト

esDm@LQdtf!q#1.+TyU

ここでオンライン試すか、ここですべてのテストケースを一度に確認してください

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

ガイア、24バイト

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

オンラインでお試しください!

うわ、E‡いくつかの奇妙なものがない...マニュアルに従って、それがなければならない「与えられた長さのような何かiリストの集合Xと長さjの指標のセットY、リターンX[i][Y[j]]」が、代わりに戻り[X[i][Y[j]] X[i][Y[-j]]、私たちがしなければならないので、負のインデックスは、補体を表しev2%へ必要なものだけを抽出します。

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

好奇心から、出力]]に1つではなく2つの末尾が付いているのはなぜですか?
ケビンクルーッセン

@KevinCruijssen通訳のちょっと変わった癖。すべてのリストがそのよう[[1] [2]]に出力さ[[1]] [2]]]]れるため、リスト出力の読み取り/デバッグが非常に難しくなります。
ジュゼッペ

私は考えて、それがために、式のだre.sub(" ?$","]",result)代わりにする必要がありますインタプリタでre.sub(" +$","]",result)はなく、私のpythonは超悪いです。
ジュゼッペ


2

Wolfram言語(Mathematica)70 63バイト

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

オンラインでお試しください!

高度な検索

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

,1誤って無効なセットを返さないようにする必要があります(そうしないと、たとえば、の入力は{1,1,1}の出力になります{{1,1},{1,1},{1,1}}


1

Haskell300 168バイト

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

オンラインでお試しください!

@nimiからのすべてのフィードバックに感謝-132バイト:)


元の

Ungolfed(オリジナル)

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
いくつかのヒント:によって返されたペア内の要素とそのインデックスを反転ff x=zip[0..length x]x、そうfなりましたf=zip[0..]gただg=map unzipです。in jでフィルタリングする関数はh.fst(<-flipped pairs!)です。j=filter(h.fst)。であるとpointfreeペア作りと。以下で置き換えることができます:。:あなたは一度だけ、すべての機能を使用している最後に、あなたは、単一のpointfree表現にそれらをインライン化することができますfoldl1+ksumk=map((,)=<<sum.snd)sortBy(...)sortOn fstl=snd.last.sortOn fstz=snd.last.sortOn fst.map((,)=<<sum.snd).filter(h.fst).map unzip.subsequences.zip[0..]
nimi


ああ、Data.Functionもうインポートする必要はありません。
nimi

それは素晴らしい、フィードバックのおかげで:)
バグ

次にh、非隣接要素を探しています。つまり、隣接するインデックスの差はでなければなりません>1zipWith(-)=<<tail違いのようにAリストを作成しますが、私たちは、追加を必要とするので、空のリストで失敗したtail上でsubsequences、それを取り除くために。再びインライン。オンラインでお試しください!
ニミ

1

、46バイト

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

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

≔⟦υ⟧η

変数uは空のリストで事前定義されています。これは割り当てられたリストに入れられますhます。これらの変数はアキュムレーターとして機能します。u入力の最新の要素qh含むサブリストが含まれますが、含まれないサブリストが含まれます(したがって、入力の次の要素を追加するのに適しています)。

Fθ«

入力の要素をループします。

≔υζ

前の要素を含むサブリストのリストを保存します。

≔Eη⁺κ⟦ι⟧υ

前の要素を含まないすべてのサブリストを取得し、現在の要素を追加し、現在の要素を含むサブリストのリストとして結果を保存します。(Pushリストを複製する必要があるため、ここでは使用しません。)

≔⁺ζηη»

以前の両方のサブリストを、現在の要素を含まないサブリストの新しいリストに連結します。

≔Φ⁺υηιη

サブリストを最後にもう一度連結し、元の空のリストを削除します(とにかくCharcoalは合計できません)。

≔EηΣιζ

すべてのサブリストの合計を計算します。

I§η⌕ζ⌈ζ

最大合計のインデックスを見つけて、対応するサブリストを出力します。



1

Japt -h、21バイト

ゴルフの仕方を完全に忘れてしまうような挑戦をしたことがありますか?!

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

それを試してみてください

ð¤à 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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.