반복 부분 합


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에서 온라인으로 사용해보십시오 .

작동 원리

  • /\ 부사 (왼쪽 인수를 취하는 함수)는 인수에 의해 누적 감소합니다.

  • 따라서 +/\는 IS 누적 합 동사.

  • ^:는 IS 전력 결합은 ; 에 총 횟수를 (f ^: n) y적용 f합니다 .ny

  • 동사-접합 열 은 (왼쪽) 인수에 지정된 횟수만큼 +/\^:반복되는 부사를 형성합니다 +/\.

    x (+/\^:) y로 구문 분석되며 (x (+/\^:)) y이는 실행과 같습니다 (+/\^:x) y.

설명에 도움을 주신 @Zgarb에게 감사드립니다.


13

매스 매 티카, 19 바이트

글쎄, 내장이 괜찮다면 ...

Accumulate~Nest~##&

챌린지의 예제와 동일한 서명으로 함수를 정의합니다. Accumulate골프 언어와 APL 가족이 쉽게 극복 할 수 있다는 긴 이름 덕분에 확신 합니다. :)

Mathematica를 사용하지 않는 사람들에 대한 LegionMammal978의 의견을 자세히 설명하려면 :

##는 함수의 매개 변수 시퀀스 를 나타냅니다 (선택한 언어에서 해당 용어에 익숙한 경우 삽입 된 위치에 자동으로 "스 플래그"되는 목록과 같습니다). 은 ~우리가 매개 변수로 함수를 호출 그렇다면, 중위 함수 호출에 대한 문법 설탕 있습니다 list그리고 n, 우리가 얻을 모든 확장 :

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

어느 것이 예상 정확히 인수 순서로 발생 Nest.


흥미로운 점은 SlotSequence...를 사용하여 3 개의 인수에 대해 중위 표기법을 사용하는 것입니다 .
LegionMammal978

9

하스켈, 26 23 바이트

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

다음과 같이 호출되는 익명 함수를 정의합니다.

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

3 바이트를 저장해 준 @nimi에게 감사합니다.

설명

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

아주 좋아요! 설명 감사합니다!
Jake

2
포인트 프리로 이동하면 함수의 이름을 생략 할 수도 있습니다 (!!).iterate(scanl1(+)).
nimi

@nimi 감사합니다! 어떻게 든 나는 구성이 여기에 나의 이점으로 작동하지 않을 것이라고 추론했다 ...
Zgarb

9

APL, 9 8 바이트

{+\⍣⍺⊢⍵}

반복을 받아들이고 왼쪽과 오른쪽 인수로 나열하는 2 차원 함수를 정의합니다.

1 바이트의 골프 오프를위한 @NBZ에 감사합니다!

TryAPL에서 온라인으로 사용해보십시오 .

작동 원리

  • 그리고 함수의 왼쪽과 오른쪽 인수는.

  • +\ 합계로 누적 감소입니다.

  • ⍣⍺이전 연산자 시간을 반복합니다 .

  • ⊢⍵identity 함수를에 적용합니다 .

    (+\⍣⍺)⍵대신 코드를 파싱하는 더 짧은 방법 입니다 +\⍣(⍺⍵).

함께, 우리 +\는 총 시간을 적용


@AlexA. 그렇다면 +\⍣⎕⊢⎕허용 되지 않을까요? ( 파이썬과 같다 input()).
marinus

1
@marinus 실제로 REPL 외부에서 인쇄됩니까? 내가 가지고있는 유일한 데스크탑 통역사는 나중에 할당해야 합니다.
Dennis

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

자바 스크립트 (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

Kona 및 oK 에서 테스트되었습니다 .

편집하다:

@ kirbyfan64sos가 결정한 것처럼 인수를 되돌릴 수 있다면 함수 줄 바꿈을 완전히 생략 할 수 있습니다.

+\/

다음과 같이 호출됩니다.

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

이것은 k2.8과 k5에서 올바르게 작동합니다. 통역사가 카레 (일명 "예상") 부사를 아직 지원하지 않기 때문에 ok에서는 작동하지 않으며 덜 명확한 이유로 코나에서 제대로 작동하지 않는 것으로 보입니다.

편집 : 며칠 전부터 +\/공식은 ok에서도 작동합니다.


1
인수 는 반대로 할 수 있으므로 몇 바이트를 면도 할 수 있다고 생각합니다.
kirbyfan64sos

3 +\/ -3 4 7 -1 15Kona에서는 잘 작동하지만 기능에 할당 할 수는 없습니다. 이상한 ...
데니스

그래, Kona는 분명히 그것을 3+\/-3 4 7 -1 15동일 하게 취급하지 않습니다. +\/[3;-3 4 7 -1 15]그들이 전자를 특별한 구문 적 사건으로 취급하는지 궁금합니다.
JohnE

4

Pyth, 9 바이트

usM._GvwQ

온라인으로 사용해보십시오 : 데모 또는 테스트 스위트

설명

usM._GvwQ  implicit: Q = input list
      vw   input number
u       Q  repeat the following instruction ^ times to G = Q
   ._G        sequence of prefixes of G
 sM           sum them up

4

줄리아, 29 바이트

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

이것은 실제로 많은 설명이 필요하지 않습니다. y==0x를 출력 하면 재귀 함수 입니다. 그렇지 않으면 y를 줄이고 누적을 수행 한 후 재귀하십시오. 아마도 가장 골프 가능한 Julia 솔루션이 아닐 수도 있습니다.


4

미로 , 73 바이트

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

Labyrinth에서 무언가 대답 한 지 오래되었습니다. 이것은 가능해 보였습니다. :)

입력 형식은 반복 횟수가 먼저 포함 된 일반 목록이며 부분 합계를 적용 할 목록입니다. 마지막 정수 뒤에 문자가없는 한 구분 기호는 모두 중요하지 않으므로 다음과 같이 읽을 수있는 것을 사용할 수 있습니다.

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

파이썬 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

파이썬, 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)

두 테스트 사례 모두에서 작동합니다. 프로그램을 각각 93, 89 및 76 바이트로 낮추는 데 도움을 준 Status, Morgan Thrapp 및 Ruth Franklin에게 감사드립니다.


1
두 번째 루프를 목록 이해로 변경하여 여러 바이트를 잘라낼 수 있습니다. 즉 k=[sum(l[:j+1])for j in range(len(l))]. 그런 다음 그 ;k=l끝에 붙인 상태에서 for i루프 로이 모든 것을 한 줄로 밀어 넣을 수 있습니다 .
상태

1
k=[sum(l[:j+1])for j in range(len(l))];l=kfor 루프와 동일한 행으로를 이동하여 2 바이트를 저장하고 f의 인수 사이의 공백을 제거하여 다른 바이트를 저장할 수 있습니다.
Morgan Thrapp

당신의 값을 사용하지 않기 때문에 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

파이썬, 52 바이트

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

목록 l과 반복 횟수를 모두 반복하는 재귀 함수입니다 n. 그것을 분해하자.

먼저 g부분 합을 한 번만 반복 하는 재귀 함수 를 생각해 봅시다 .

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

n이다 0,이 목록이 반환 l변경하고, 그렇지 않은 경우, 적용 g후 통화 한 번 f한 적은 반복 남은 재귀.

이제 두 개의 재귀를 단일 함수로 결합한 실제 코드를 다시 살펴 보겠습니다. 아이디어는 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때마다 n==0l==[]. 우리는 둘 중 하나가 n*l빈 목록, 즉 Falsy 임을 지적함으로써 이들을 결합합니다 . 따라서 n*l비어 있지 않을 때마다 재귀 하고 l그렇지 않으면 반환 합니다.

에 대한 재귀 호출이 두 번 있더라도 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 << " ";
}

이것은 함수 (같은 객체)의 정의를이 부분으로 줄입니다.

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

... 40 바이트 (+는 17 #include).


와우, 나는 STL이 부분 합계를 계산하기 위해 alg를 가질 것으로 기대하지 않았습니다.
Zereges

1
@ Zeereges : 아무도 스페인어 Inquisit을 기대하지 않습니다 ... 오, 잠깐, 우리는 Python이 아닌 C ++을하고 있습니다. 사과드립니다.
Jerry Coffin


2

하스켈, 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'를 사용했으며 게시물에서 코드를 수정할 때 놓 쳤어 야합니다. 편집했습니다.
Jake

의 경우 우선 순위가 높은을 사용하여 sum(take j a)괄호를 피할 수 있습니다 . sum$take j a$
xnor

도와 주셔서 감사합니다! 나는 어떤 이유로 $구문보다 우선 하는 인상 을 받았다 (그리고 나머지 줄을 평가하려고 노력한다). 물론 이해가되지 않습니다.
Jake


2

C #, 52 + 85 = 148137 바이트

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

파이썬 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를 사용하는데, 이는 속임수와 비슷하지만 여기에 있습니다 :

파이썬 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;}

테스트 케이스와 함께 언 골프

#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 바이트를 제공합니다.
Jerry Coffin

@JerryCoffin 감사합니다 ..
Zereges


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)

ungolf와 몇 가지 예

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