部分文字列合計セット


26

前書き

この配列を見てみましょう:[3, 2, 4, 1, 1, 5, 1, 2]

各要素には、合計する必要がある部分文字列の長さが表示されます。上記の配列の最初の要素を見てみましょう。

[3, 2, 4, 1, 1, 5, 1, 2]
 ^

最初のインデックスの要素は3なので、開始位置と同じインデックスを持つ長さ3の部分文字列を取得します。

[3, 2, 4]

合計すると、これは9になるため、部分文字列合計セットの最初の要素は9です。

配列内のすべての要素に対してこれを行います。

3 -> [3, 2, 4]
2 -> [2, 4]
4 -> [4, 1, 1, 5]
1 -> [1]
1 -> [1]
5 -> [5, 1, 2]
1 -> [1]
2 -> [2]

数字の5は少し奇妙なケースであることがわかります。その数は配列の長さを超えています。

[3, 2, 4, 1, 1, 5, 1, 2]
                ^  ^  ^  ^  ^

配列を超えるものはすべて無視するため、単にを使用します[5, 1, 2]

最後のステップは、すべてをまとめることです。

[3, 2, 4]     -> 9
[2, 4]        -> 6
[4, 1, 1, 5]  -> 11
[1]           -> 1
[1]           -> 1
[5, 1, 2]     -> 8
[1]           -> 1
[2]           -> 2

そして、それは出力する必要がある配列です:

[9, 6, 11, 1, 1, 8, 1, 2]

タスク

正の(ゼロ以外の)整数を持つ空でない配列を指定すると、部分文字列sum setを出力します。これはであるため、バイト数が最小の提出が勝ちです!

テストケース

[1, 2, 3, 4, 5] -> [1, 5, 12, 9, 5]
[3, 3, 3, 3, 3, 3, 3, 3] -> [9, 9, 9, 9, 9, 9, 6, 3]
[5, 1, 2, 4, 1] -> [13, 1, 6, 5, 1]
[1] -> [1]

「サブストリング」ではなく「サブリスト」を意味すると思います。文字列はありません。
mbomb007

4
@ mbomb007ここで、部分文字列は、最も長い一般的な部分文字列の問題、つまり要素が隣接する部分列と同じ意味を持つと思います。データ型はさておき、文字列はアルファベットセットの要素の有限シーケンス(この場合は正の整数)です。
デニス

回答:




11

Excel、21バイト

=SUM(OFFSET(A1,,,A1))

新しいスプレッドシートを開き、列Aにテスト値を入力します。B1に数式を入力し、セルハンドルをダブルクリックして範囲に移動します。


可能であれば、ダブルクリックのトリックについて教えてください。
ニール

動作しますが、実行には手動入力が必要なため、少しごまかします。
user3819867

3
@ user3819867は、ほとんどのプログラムの実行ほど大きくはない、と私は主張する。おそらく、B1の数式のみを含むスプレッドシートを保存し、それを開いて列Aにデータを追加し、B1のハンドルをダブルクリックして実行すると、さらに比較しやすくなります。もちろんYMMV。
ジョファン

7

Python 3、47バイト

lambda X:[sum(X[i:i+k])for i,k in enumerate(X)]

非常に簡単な実装。リストの最後を過ぎたスライスに対するPythonのデフォルトの動作は、ここでは非常に便利でした。



4

JavaScript ES6、50バイト

a=>a.map((e,i)=>a.slice(i,i+e).reduce((a,b)=>a+b))

かなり自明です。それmapは、配列の各要素の上にあり、インデックスsliceからそのindexからそのe要素の値を取得し、reduce追加することでingします。

f=
  a=>a.map((e,i)=>a.slice(i,i+e).reduce((a,b)=>a+b))

;[
  [3, 2, 4, 1, 1, 5, 1, 2],
  [1, 2, 3, 4, 5],
  [3, 3, 3, 3, 3, 3, 3, 3,],
  [5, 1, 2, 4, 1],
  [1]
].forEach(function(test){
  document.getElementById('p').textContent += test + ' => ' + f(test) + '\n';
});
<pre id="p"></pre>


4

J、11バイト

+/@{."_1]\.

使用法

   f =: +/@{."_1]\.
   f 3 2 4 1 1 5 1 2
9 6 11 1 1 8 1 2
   f 1 2 3 4 5
1 5 12 9 5

説明

+/@{."_1]\.  Input: A
        ]\.  Get each suffix of A from longest to shortest
   {."_1     For each value in A, take that many values from its corresponding suffix
+/@          Sum that group of values taken from that suffix
             Return the sums

4

JavaScript(ES6)、45

reduce 再びbeatられた!

a=>a.map((v,i)=>eval(a.slice(i,v+i).join`+`))

F=
a=>a.map((v,i)=>eval(a.slice(i,v+i).join`+`))

;[[3, 2, 4, 1, 1, 5, 1, 2],
  [1, 2, 3, 4, 5],
  [3, 3, 3, 3, 3, 3, 3, 3,],
  [5, 1, 2, 4, 1],
  [1]].forEach(t=>console.log(t+' -> '+F(t)))


1
私の知る限りf=この回答のようにを削除できます
-LarsW

@LarsW右、f=45バイトで既にカウントされていません
-edc65


3

Mathematica 60 55バイト

Tr@Take[#,UpTo@#&@@#]&/@Drop[#,t-1]~Table~{t,Length@#}&

例えば

f = %; f /@ {{1, 2, 3, 4, 5}, {3, 3, 3, 3, 3, 3, 3, 3}, {5, 1, 2, 4, 1}, {1}}

(*    {{1, 5, 12, 9, 5}, {9, 9, 9, 9, 9, 9, 6, 3}, {13, 1, 6, 5, 1}, {1}}    *)

5バイトを削ってくれてありがとう@MartinEnder :)


1
テーブルを回避するためのアイデアは次のとおりです#+Tr@Take[x=Rest@x,UpTo[#-1]]&/@(x=#)&。最適かどうかはまだわかりませんが、17バイト節約できます。
マーティンエンダー

3

05AB1E、11 8バイト

[D¬£Oˆ¦Ž

説明

[         # infinite loop
 D        # duplicate current list
  ¬       # get head of list
   £      # get that many elements from list
    O     # sum
     ˆ    # add to global array
      ¦   # remove first element of list
       Ž  # break if stack is empty
          # implicitly push and print global array

オンラインで試す



2

アーラン、69バイト

f(A)->put(1,1),L=lists,[L:sum(L:sublist(A,put(1,get(1)+1),X))||X<-A].

リストのためのErlangの高階関数は、現在の要素のインデックスを受け取りません。これは、プロセスディクショナリを使用して、現在の要素のインデックスを設定します。



2

VBA、160バイト

Function e(g())
Dim h()
k=LBound(g)
l=UBound(g)
ReDim h(k To l)
On Error Resume Next
For i=k To l
For j=i To i+g(i)-1
h(i)=h(i)+g(j)
Next
Next
e=h
End Function

2

Pyth、6バイト

ms<~tQ

テストスイート

これは、これまでの他のソリューションとは異なるソリューションです。入力をループし、初期値を合計してスライスし、保存された入力の最初の要素を削除して、繰り返します。

説明:

ms<~tQ
ms<~tQdQ    Implicit variable introduction
            Implicit: Q = eval(input())
m      Q    Map d over the input, Q
  <  Qd     Take the first d elements of Q
 s          Sum them
   ~tQ      Afterwards, set Q to the tail of Q, removing the first element.


1

F#、84 82バイト

let f(A:int[])=[for i in 0..A.Length-1->Seq.skip i A|>Seq.truncate A.[i]|>Seq.sum]

1

JavaScript(ES6)-79バイト

Arrayメソッドを使用しない再帰的なソリューション:

f=([a,...t],n)=>a&&n?a+f(t,n-1):0;g=([a,...t],r=[])=>a?g(t,[...r,a+f(t,a-1)]):r

テスト:

f=([a,...t],n)=>a&&n?a+f(t,n-1):0;
g=([a,...t],r=[])=>a?g(t,[...r,a+f(t,a-1)]):r;

[
  [3, 2, 4, 1, 1, 5, 1, 2],
  [1, 2, 3, 4, 5],
  [3, 3, 3, 3, 3, 3, 3, 3,],
  [5, 1, 2, 4, 1],
  [1]
].forEach(a=>console.log(''+g(a)));


1

C#、89バイト

int[]s(List<int>a)=>a.Select((n,i)=>a.GetRange(i,Math.Min(n,a.Count-i)).Sum()).ToArray();

かなり簡単

改善のアイデアに感謝


1

Brachylog、27バイト

.v|h~l(A:Tc?;A?)b:0&~b.h~+A

オンラインでお試しください!または、すべてのテストケースを確認します

説明

  .v           Input = Output = []
|            Or
  h~l          A is a list, its length is the value of the first element of the Input
  (
    A:Tc?        The concatenation of A with another list T results in the Input
  ;            Or
    A?           A = Input
  )
  b:0&         Call recursively on Input minus the first element
  ~b.          Output is the output of that call with an extra element at the beginning
  h~+A         That extra element is the sum of the elements of A


1

PHPプログラム、72バイト

<?foreach($a=$_GET[a]as$i=>$v)echo array_sum(array_slice($a,$i,$v)),"
";

で呼び出す php-cgi -f <filename> 'a[]=3&a[]=2&a[]=4...

関数として+11:

function f($a){foreach($a as$i=>$v)$r[]=array_sum(array_slice($a,$i,$v));return$r;}

組み込みなしの+9:

function p($a){foreach($c=$r=$a as$i=>$v)for($k=$i;$k--;)if(--$a[$k]>0)$r[$k]+=$v;return$r;}

($ cは元の値を保持し、$ aはインデックスごとにカウントダウンし、$ rは合計を取得します)

-3プログラムとして:

<?foreach($a=$r=$c=$_GET[a]as$i=>$v)for($k=$i;$k--;)if(--$c[$k]>0)$r[$k]+=$v;print_r($r);

1

q(37バイト)

{sum each(til[count x],'x)sublist\:x}

例:

q){sum each(til[count x],'x)sublist\:x}3 2 4 1 1 5 1 2
9 6 11 1 1 8 1 2

1

マトリックス、25バイト

いや、ついに私は新機能を必要としない挑戦です!

md{z:l-g:c;+c;q:c;};:1:l;

で実行: python matricks.py substring.txt [[<input>]] 0

説明:

m                  :1:l;   #loop over entire input
                           #set each value to...
 d{               }        #the sum of...
   z:l-g:c:+c;q:c;         #the input cropped to
                           #the length of the value in the cell

1

Javascript(外部ライブラリを使用)(66バイト)

n=>_.From(n).Select((v,i)=>_.From(n).Slice(i,i+v).Sum()).ToArray()

libへのリンク:https : //github.com/mvegh1/Enumerable

コードの説明:_.Fromは入力配列をライブラリにロードしています。これは基本的にLINQ for jsです。次に、配列内の各アイテムは、次の述語に従ってマッピングされます。入力を取得し、現在のアイテムインデックスからスライスし、そのインデックスと現在のアイテムの値を取得します。次に、そのサブシーケンスを合計します。結果をネイティブJS配列に変換して返します

ここに画像の説明を入力してください


var 変数からを削除します。ゴルフでは必要ありません。また、変更可能.forEach.mapどれが少ないバイトがかかります。
チャーレッドグラス

そうそう、あなたはvarについて正しいです。ありがとう!明日もこの回答をもう一度やります。ネイティブのJS(es6)が私のソリューションを殺すようですlol
applejacks01

varを削除することをお勧めします。私はまた、バイトが多くを数える減少させ、より直感的である別のソリューションが実現
applejacks01

1

Clojure、63バイト

(defn f[[b & r]](concat[(apply + b(take(dec b)r))](if r(f r))))

パターンマッチングを使用して、入力引数を最初の引数と残りの引数に分解します。


1

MATL17 14 13バイト

fGy+!-R0<G*!s

説明

オンラインでお試しください!または、すべてのテストケースを検証します(複数の入力を処理するようにコードを変更します)。

f     % Take input implicitly. Indices of nonzero elements: this gives [1 2 ... n]
      % where n is input size
G     % Push input again
y     % Push a copy of [1 2 ... n]
+     % Add. Gives [a+1 b+2...] where [a b...] is the input
!     % Transpose into a column vector
-     % Subtraction with broadcast. Gives 2D array
R     % Keep upper triangular part, making the rest of entries 0
0<    % True for negative entries. Each row corresponds to a substring sum.
      % For each row, this gives true for the entries of the input that make up
      % that substring sum. Each row is thus a mask to select entries of the input
G     % Push input again
*     % Multiply with broadcast. This multiplies the input times each row
!s    % Sum of each row. Implicitly display

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