反復部分和


23

整数のリスト[a 1、a 2、a 3、...、a n ] の部分和は次のとおりです。

s 1 = a 1
s 2 = a 1 + a 2
s 3 = a 1 + a 2 + a 3
...
s n = a 1 + a 2 + ... + a n

その後、部分和[s 1、s 2、s 3、...、s n ] のリストを取得し、その部分和を再度計算して新しいリストを作成できます。

関連:反復的な前方差分

入力:

  • 整数の空でないリスト
  • 正の反復回数、

出力:部分的な合計を何回も取得した結果の整数のリストを出力または返します。

少ないバイトが勝ちます。ビルトインは、問題を完全に解決しても問題ありません。

テストケース:

f([-3, 4, 7, -1, 15], 1) == [-3, 1, 8, 7, 22]
f([-3, 4, 7, -1, 15], 3) == [-3, -5, 1, 14, 49]

リーダーボード:


引数は同じ順序である必要がありますか、それとも繰り返しの数が数のリストのに来ることができますか?
kirbyfan64sos

@ kirbyfan64sosいずれかの順序。
XNOR

回答:


14

J、5バイト

+/\^:

J.jsでオンラインで試してください。

使い方

  • /\ 引数によって累積的に減少する副詞(左引数を取る関数)です。

  • したがって+/\累積和動詞です。

  • ^:ある電源連動は(f ^: n) yf合計n時間を適用しyます。

  • 動詞接続詞列+/\^:は、+/\その(左の)引数で指定された回数だけ繰り返す副詞を形成します。

    x (+/\^:) yはとして解析されます。(x (+/\^:)) yこれはの実行と同等(+/\^:x) yです。

説明に協力してくれた@Zgarbに感謝します。


13

Mathematica、19バイト

さて、組み込みが大丈夫なら...

Accumulate~Nest~##&

チャレンジの例と同じシグネチャを持つ関数を定義します。Accumulateしかし、これはゴルフの言語とAPLファミリーによって簡単に破られる長い名前のおかげです。:)

Mathematicaを使用しない人に対するLegionMammal978のコメントを詳しく説明するには、次のようにします。

##関数のパラメータのシーケンスを表します(選択した言語の用語に精通している場合、挿入された場所に自動的に「スプラット」するリストのようなものです)。~我々はパラメータで関数を呼び出すようにすれば、中置関数呼び出しのシンタックスシュガーあるlistn、私たちは取得し、すべてを展開します。

Accumulate~Nest~##
Nest[Accumulate, ##]
Nest[Accumulate, list, n]

これは、たまたまが期待する引数の順序とまったく同じNestです。


その使用して3つの引数に中置記法を使用しての興味深い、SlotSequence...
LegionMammal978

9

Haskell、26 23バイト

(!!).iterate(scanl1(+))

これは、次のように呼び出される匿名関数を定義します。

> let f = (!!).iterate(scanl1(+)) in f [-3,4,7,-1,15] 3
[-3,-5,1,14,49]

@nimiに3バイトの節約をありがとう。

説明

(!!).                    -- Index by second argument from
     iterate(         )  -- the infinite list obtained by iterating
             scanl1(+)   -- the partial sums function (left scan by +) to first argument

非常に素晴らしい!そして説明をありがとう!
ジェイク

2
pointfreeに進み、関数の名前を省略することもできます:(!!).iterate(scanl1(+))
nimi

@nimiありがとう!どういうわけか、私はここで作曲が私の利益にうまくいかないと推論しました
...-Zgarb

9

APL、9 8バイト

{+\⍣⍺⊢⍵}

これは、繰り返しとリストを左右の引数として受け入れるダイアディック関数を定義します。

1バイトのゴルフをしてくれた@NBZに感謝します!

TryAPLでオンラインで試してください。

使い方

  • and は、関数の左右の引数です。

  • +\ 合計による累積削減です。

  • ⍣⍺先行する演算子を繰り返します。

  • ⊢⍵に恒等関数を適用します。

    これは、の(+\⍣⍺)⍵代わりにコードを解析する短い方法です+\⍣(⍺⍵)

併せて、+\合計時間を


@AlexA .:それでは+\⍣⎕⊢⎕受け入れられないでしょうか?(Pythonに似ていますinput())。
マリヌス

1
@marinusそれは実際にREPLの外に印刷されますか?私が持っている唯一のデスクトップインタープリターは、後で割り当てる必要があります。
デニス

5

Matlab、41バイト

function f(l,n);for i=1:n;l=cumsum(l);end

とても簡単です。私はまだ、区分的に定義された匿名関数、または再帰のアンカーを作成する方法が組み込まれていないことは非常に迷惑だと思います。

ゴルフをしていない:

function f(l,n);
for i=1:n;
    l=cumsum(l);
end

5

JavaScript(ES6)38

.mapを再帰的に使用すると驚くほど小さい

f=(l,n,t=0)=>n?f(l.map(x=>t+=x),n-1):l

function test()
{
  var n, v, i = I.value
  v = i.match(/\-?\d+/g).map(x=>+x)
  n = v.pop()
  console.log(v,n)
  O.innerHTML = I.value + ' -> ' + f(v,n) + '\n' + O.innerHTML;
}

test()
<input id=I value='[-3, 4, 7, -1, 15], 3'><button onclick="test()">-></button>
<pre id=O></pre>


5

K、7 3バイト

{y+\/x}

Jソリューションに非常に似ています。+\部分和を正確に実行/し、単項動詞と整数左引数が指定されている場合、「for」ループのように、指定された回数だけ反復します。残りは、引数の順序に合うようにきちんとまとめています。

  {y+\/x}[-3 4 7 -1 15;1]
-3 1 8 7 22
  {y+\/x}[-3 4 7 -1 15;3]
-3 -5 1 14 49

コナとOKでテスト済み。

編集:

@ kirbyfan64sosが決定したように、引数を逆にすることが許可されている場合、関数のラッピングを完全に省くことができます。

+\/

次のように呼び出されます:

+\/[3;-3 4 7 -1 15]

これは、k2.8とk5の両方で適切に機能します。このインタープリターはカリー化された(別名「投影」)副詞をまだサポートしていないため、OKでは機能しません。

編集:数日前のように、+\/公式もOKで動作します。


1
引数は逆にすることができますので、数バイト削ることができるかもしれません。
kirbyfan64sos

3 +\/ -3 4 7 -1 15コナでは正常に機能しますが、関数に割り当てることはできません。奇妙な...
デニス・

うん、コナは明らかに3+\/-3 4 7 -1 15同じものを扱っていない+\/[3;-3 4 7 -1 15]-彼らは前者を特別な構文のケースとして扱うのだろうかと思う。
JohnE


4

ジュリア、29バイト

f(x,y)=y>0?f(cumsum(x),y-1):x

これは本当に多くの説明を必要としません。y==0xを出力するだけの場合、再帰関数です。それ以外の場合は、yを減分し、cumsumを実行し、再帰します。おそらく最もゴルフの可能性のあるジュリアのソリューションではない、私はまだそれに取り組んでいます。


4

ラビリンス、73バイト

;?
,"
;
#
#;}=
;  #
"#;(
_  ;={()"
#;; ( { "
  ; { !\(@
+=( =
" " "
":{:"

ラビリンスで何かに答えてからしばらく経ちましたが、これは実行可能に思えました。:)

入力形式は、最初に反復回数を含むフラットリストです(次に部分合計を適用するリスト)。最後の整数の後に文字がない限り、区切り文字はすべて重要ではありません。したがって、次のような読みやすいものを使用できます。

3 | -3, 4, 7, -1, 15

出力は改行で区切られます:

-3
-5
1
14
49

4

R、75バイト

それは長いですが、異なるテイク...累積合計の代わりに目的のシーケンスを直接計算する:

function(x,n)sapply(1:length(x),function(i)sum(x[1:i]*choose(i:1+n-2,n-1)))

cumsum ^ n(x)のxiの項の係数は、パスカルの三角形の対角線であることに注意してください。すなわち

cumsum^3(x) = choose(2,2) * x1, choose(3,2) * x1 + choose(2,2) *x2, choose(4,2) * x1 + choose(3,2) * x2 + choose(2,2) * x3, ....

編集:関数を作成する


4

Python 2、67

これは、Anthony Roitmanと同じ合計を使用し、Morgan Thrappと同じ再帰を使用します。

f=lambda l,n:f([sum(l[:i+1])for i in range(len(l))],n-1)if n else l

私は彼らのソリューションを見る前にこのソリューションを開発しました。そして、どちらかまたは両方へのコメントではなく、回答として投稿する方が簡単に思えました。


4

Python、113 93 89 76バイト

def f(l,n):
 for i in[0]*n:l=[sum(l[:j+1])for j in range(len(l))];
 print(l)

両方のテストケースで機能します。ステータス、Morgan Thrapp、およびRuth Franklinのおかげで、プログラムをそれぞれ93バイト、89バイト、76バイトにまで減らしてくれました。


1
2番目のループをリスト内包表記に変更することにより、バイト数を削減できます。つまり、k=[sum(l[:j+1])for j in range(len(l))]。その後;k=l、最後にタックを付けて、for iループを使用してこのすべてを1行にプッシュできます。
ステータス

1
k=[sum(l[:j+1])for j in range(len(l))];l=kforループと同じ行に移動して2バイトを節約し、fの引数間のスペースを削除して別のバイトを節約できます。
モーガンスラップ

あなたがの値を使用していないとしてi、あなたは置き換えることができfor i in range(n)for i in[0]*n(あなたが気にすべての長さではないリストの要素であるため)。そしてk、引数を変更するだけで、補助リストを使用せずに実行できると思いますl
ルースフランクリン

4

Gol> <> 0.3.10、22バイト

SI
C>rFlMF:}+
NRl<C}<;

最初の整数が反復数と見なされ、残りがリストを構成します。最終リストは改行区切りで出力されます。

言語はまだかなり若くて不安定ですが、これらの演算子にかなり慣れているので、大丈夫だと思いました。

説明

SI            Read integer, moving down on EOF (first line runs as loop)
r             Reverse stack, putting iteration number on top

[outer loop]
F             Do #(iterations) times

[inner loop]
lMF           Do #(length of stack - 1) times
:             Duplicate top of stack
}             Rotate stack rightward (top goes to bottom)
+             Add the top two elements of the stack
C             Continue inner loop, moving down from F when loop is over

}             Rotate once more
C             Continue outer loop, moving down from F when loop is over

lRN           Print stack as (num + newline)
;             Halt

これがなぜ機能するかを見るために、小さな例を試してみましょう[5 2 1]

[5 2 1] -- : --> [5 2 1 1] -- } -->  [1 5 2 1]  -- + --> [1 5 3]
[1 5 3] -- : --> [1 5 3 3] -- } -->  [3 1 5 3]  -- + --> [3 1 8]

-- } --> [8 3 1]

3

Python、52バイト

f=lambda l,n:n*l and f(f(l[:-1],1)+[sum(l)],n-1)or l

リストlと反復回数の両方で再帰する再帰関数n。分解しましょう。

最初に、g部分和を1回だけ反復する再帰関数を考えてみましょう。

g=lambda l:l and g(l[:-1])+[sum(l)]

空のリストのl場合、これは空のリストl自体を返します。それ以外の場合、の部分合計の最後のエントリlはの全体の合計でありl、の最後の要素を除くすべての再帰的な結果に追加されlます。

それでは、機能を見てみましょうf適用gのためnの反復。

f=lambda l,n:n and f(g(l),n-1)or l

ときn0、これはリストを返すl変わらず、それ以外の場合は、適用されg、その後呼び出して、一度f1回の少ない反復が残って再帰的に。

ここで、2つの再帰を1つの関数に結合する実際のコードをもう一度見てみましょう。アイデアはg(l)特別な場合として扱うことf(l,1)です。

f=lambda l,n:n*l and f(f(l[:-1],1)+[sum(l)],n-1)or l

我々は取っf(g(l),n-1)拡大し、以前の定義からg(l)g(l[:-1])+[sum(l)]して、交換しg(_)f(_,1)に限定再帰呼び出しにf

基本ケースでは、またはをl常に返します。どちらかが空のリストであることに注意して、これらを組み合わせます。これはFalsyです。そのため、空でないときはいつでも再帰し、戻りますn==0l==[]n*ln*llそうでない場合はます。

に2つの再帰呼び出しがありますがf、これはフィボナッチ数の再帰定義の指数関数的な爆発を引き起こしませんが、2次関数のままです。


3

C ++(61 + 17 = 78バイト)

#include<numeric>
void f(int*a,int*e,int n){for(;n--;)std::partial_sum(a,e,a);}

テストケース:

#include <iostream>
#include <iterator>

int main() {
    int a[] { -3, 4, 7, -1, 15 };
    f(a, std::end(a), 3);
    for (auto i : a)
        std::cout << i << " ";
}

これは仕様にわずかな自由度が必要です。Cスタイルの配列を使用し、配列の最初と最後にポインターを渡します。内部的には、ご覧のとおり、それは周りの非常に薄いラッパーですstd::partial_sum、標準ライブラリ内の。結果の値を実際に返すのではなく、渡された配列を変更するだけです。

物事の定義を限界まで(そして、ほぼ間違いなく)プッシュすることを気にしない場合は、ラムダ式で「関数」を定義できます。

#include<numeric>
#include <iostream>
#include <iterator>

int main() {
    int a[] { -3, 4, 7, -1, 15 };
    int *e = std::end(a);
    int n=3;

    auto f=[&]{for(;n--;)std::partial_sum(a,e,a);};

    f();
    for (auto i : a)
        std::cout << i << " ";
}

これにより、関数(-likeオブジェクト)の定義がこの部分に限定されます。

[&]{for(;n--;)std::partial_sum(a,e,a);};

... 40バイトの場合(+17の場合#include)。


ワウ、私はSTLが部分的な合計を数えるためのalgを持つことを期待していませんでした。
ゼレゲス

1
@Zereges:誰もスペイン語の審問を期待していません....ああ、待ってください、PythonではなくC ++をやっています。謝罪いたします。
ジェリー


2

Haskell、52 47バイト

初めてゴルフの「試み」をコーディングし、私はHaskellの初心者なので、コメントを歓迎します!関数呼び出しの必要な形式、またはプログラムへの引数で使用されるかどうかについての質問では明確ではなかったため、感嘆符を関数識別子として使用していくつかのスペースを節約しました。

0!a=a
i!a=(i-1)![sum$take j a|j<-[1..length a]]

使用法(GHCi):

$ ghci partialsums.hs
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main             ( partialsums.hs, interpreted )
Ok, modules loaded: Main.
*Main> 1![-3, 4 ,7 ,-1 ,15]
[-3,1,8,7,22]
*Main> 3![-3, 4 ,7 ,-1 ,15]
[-3,-5,1,14,49]

コードゴルフへようこそ!通常、ガードを使用するよりもパターンマッチの方が短い0!a=a i!a=...です。
xnor

ありがとう@xnor-私は以前に初期コードを構築するときに 'xs'を使用していましたが、投稿でコードを変更したときにそれを逃したに違いありません。編集済み。
ジェイク

のためにsum(take j a)sum$take j a優先度の高いものを使用することで、括弧を避けることができます$
xnor

ご協力ありがとうございました!何らかの理由で、$構文よりも優先されるという印象を受けました(そして、残りの行をそのまま評価しようとしました)。もちろん、それは意味がありません。
ジェイク


2

C#、52 + 85 = 148 137バイト

using E=System.Collections.Generic.IEnumerable<int>;

そして

E I(E s,int i){int t=0;return i<1?s:I(System.Linq.Enumerable.Select(s,v=>t+=v),i-1);}

非正統的な慣行(v=>t+=v)を使用していますが、これはPPCGです。スタックの深さの制約にも注意してください。


2

Python 3、73

おそらくもう少しゴルフダウンすることができます。

def f(n,i):
 p=0;c=[]
 for m in n:p+=m;c+=[p]
 f(c,i-1)if i else print(n)

このバージョンではnumpyを使用します。これは不正行為に少し似ていますが、ここでは次のようになっています。

Python 3(numpyを使用)、72

from numpy import*
def f(n,i):
 if i:c=cumsum(n);f(c,i-1)
 else:print(n)

2

C ++ 14、102 103 94 + 17(含む)= 111バイト

#include<vector>
auto f(std::vector<int>a,int n){for(;n--;)for(int i=0;i<a.size()-1;++i)a[i+1]+=a[i];return a;}

Ungolfed、テストケース付き

#include <vector>
#include <iostream>

auto f(std::vector<int> a, int n)
{
    for (; n--;)
        for (int i = 0; i < a.size() - 1; ++i)
            a[i + 1] += a[i];
    return a;
}


int main()
{
    auto t = f({-3, 4, 7, -1, 15}, 3);
    for (int i : t)
        std::cout << i << " ";
}

評価の順序に依存します。UBかどうかはわかりませんが、動作します。コンパイラに依存するため、変更しました。


j0からnまでカウントアップする代わりに、0にカウントダウンnします。カウントで97バイトを与えます。
ジェリーCo

@JerryCoffinありがとう
。.–ゼレゲス


1

バーレスク、10バイト

{q++pa}jE!

一般的にはあまり効率的ではありませんが、トリックを行います。

blsq ) {-3 4 7 -1 15} 1 {q++pa}jE!
{-3 1 8 7 22}
blsq ) {-3 4 7 -1 15} 3 {q++pa}jE!
{-3 -5 1 14 49}

1

C ++ 14、67バイト

入力を変更する名前のないラムダcとして、のようなランダムアクセスコンテナとして必要vector<int>です。

[](auto&c,int n){while(n--)for(int i=0;i++<c.size();c[i]+=c[i-1]);}


1

ゼリー、3バイト

SƤ¡

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

これは私の(Mr Xcoderの)メソッドです。

ゼリー、3バイト

+\¡

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

これは、caird coinheringaahingのソリューションです。

方法#1

SƤ¡-完全なプログラム、ダイアディック。

  ¡-繰り返し適用、N回。
 Ƥ-リストのプレフィックスに先行リンクをマッピングします。
S-合計。
     -暗黙的に出力

方法#2

+ \¡-完全なプログラム、ダイアディック。

  ¡-繰り返し適用、N回。
 \-累積削減:
+-追加。

0

公理213 47バイト

m(a,b)==(for i in 1..b repeat a:=scan(+,a,0);a)

ウンゴルフといくつかの例

 (3) -> [m([-3,4,7,-1,15],1), m([-3,4,7,-1,15],3)]
    Compiling function l with type List Integer -> List Integer
    Compiling function m with type (List Integer,Integer) -> List
       Integer

    (3)  [[- 3,1,8,7,22],[- 3,- 5,1,14,49]]
                                                       Type: List List Integer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.