Số tiền một phần lặp


23

Tổng một phần của danh sách các số nguyên [a 1 , a 2 , a 3 , ..., a n ] là

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

Sau đó, chúng ta có thể lấy danh sách các khoản tiền một phần [s 1 , s 2 , s 3 , ..., s n ] và tính lại một phần tổng của nó một lần nữa để tạo ra một danh sách mới, v.v.

Liên quan: Sự khác biệt về phía trước

Đầu vào:

  • Một danh sách các số nguyên không trống
  • Một số lần lặp tích cực,

Đầu ra: In hoặc trả về danh sách các số nguyên có kết quả từ việc lấy tổng một phần nhiều lần.

Ít byte nhất sẽ thắng. Được xây dựng là OK ngay cả khi họ hoàn toàn giải quyết vấn đề.

Các trường hợp thử nghiệm:

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

Bảng xếp hạng:


Các đối số có cần phải theo cùng một thứ tự không, hoặc số lần lặp có thể đến trước danh sách các số không?
kirbyfan64sos

@ kirbyfan64sos Hoặc là đặt hàng.
xnor

Câu trả lời:


14

J, 5 byte

+/\^:

Dùng thử trực tuyến trên J.js .

Làm thế nào nó hoạt động

  • /\ là một trạng từ (hàm lấy một đối số bên trái) làm giảm tích lũy bởi đối số của nó.

  • Như vậy +/\là động từ tổng tích lũy .

  • ^:là sự kết hợp sức mạnh ; (f ^: n) yáp dụng ftổng số nlần y.

  • Các động từ kết hợp động từ tạo +/\^:thành một trạng từ lặp lại +/\nhiều lần như được chỉ định trong đối số (trái) của nó.

    x (+/\^:) yđược phân tích cú pháp như (x (+/\^:)) y, tương đương với thực thi (+/\^:x) y.

Cảm ơn @Zgarb đã giúp đỡ giải thích.


13

Toán học, 19 byte

Chà, nếu được xây dựng thì không sao ...

Accumulate~Nest~##&

Xác định hàm có cùng chữ ký với các ví dụ trong thử thách. Tôi khá chắc chắn, nhờ cái tên dài Accumulatemà điều này sẽ dễ dàng bị đánh bại bởi các ngôn ngữ golf và gia đình APL. :)

Để giải thích về nhận xét của LegionMammal978 cho những người không sử dụng Mathicala:

##biểu thị một chuỗi các tham số của hàm (giống như một danh sách tự động "chia nhỏ" bất cứ nơi nào nó được chèn, nếu bạn quen thuộc hơn với thuật ngữ đó từ lựa chọn ngôn ngữ của bạn). Các ~là cú pháp đường cho chức năng ghi vào gọi, vì vậy nếu chúng ta gọi hàm với các tham số listnvà mở rộng tất cả mọi thứ, chúng ta nhận được:

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

Mà xảy ra chính xác là thứ tự đối số dự kiến Nest.


Điều đó thật thú vị, sử dụng ký hiệu infix cho 3 đối số bằng cách sử dụng SlotSequence...
LegionMammal978

9

Haskell, 26 23 byte

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

Điều này xác định một hàm ẩn danh, được gọi như sau:

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

Cảm ơn @nimi đã lưu 3 byte.

Giải trình

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

Rất đẹp! Và cảm ơn bạn đã giải thích!
Jake

2
Truy cập điểm, sau đó bạn thậm chí có thể bỏ qua tên cho hàm : (!!).iterate(scanl1(+)).
nimi

@nimi Cảm ơn! Bằng cách nào đó tôi đã lý giải rằng sáng tác sẽ không có lợi cho mình ở đây ...
Zgarb

9

APL, 9 8 byte

{+\⍣⍺⊢⍵}

Điều này xác định một hàm dyadic chấp nhận các lần lặp và liệt kê như các đối số trái và phải.

Cảm ơn @NBZ vì đã chơi golf 1 byte!

Dùng thử trực tuyến trên TryAPL .

Làm thế nào nó hoạt động

  • là các đối số trái và phải cho hàm.

  • +\ được tích lũy giảm theo tổng.

  • ⍣⍺lặp lại các lần vận hành trước .

  • ⊢⍵áp dụng chức năng nhận dạng cho .

    Đây là một cách ngắn hơn để phân tích mã (+\⍣⍺)⍵thay vì +\⍣(⍺⍵).

Kết hợp, chúng tôi áp dụng +\tổng số lần để


@AlexA.: Sau đó sẽ không +\⍣⎕⊢⎕được chấp nhận? ( giống như Python input()).
bến tàu

1
@marinus Điều đó có thực sự in bên ngoài REPL không? Các thông dịch viên máy tính để bàn duy nhất tôi có sẽ yêu cầu gán cho sau đó.
Dennis

5

Matlab, 41 byte

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

Khá đơn giản. Tôi vẫn nghĩ rằng sẽ khá khó chịu khi không được xây dựng để tạo ra các chức năng ẩn danh được xác định rõ ràng, hoặc các mỏ neo trong các cuộc thám hiểm.

Ung dung:

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

5

JavaScript (ES6) 38

Đáng ngạc nhiên là nhỏ sử dụng .map đệ quy

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 byte

{y+\/x}

Rất giống với giải pháp J. +\thực hiện chính xác một phần tổng và khi /được cung cấp một động từ đơn âm và một đối số trái số nguyên, nó lặp lại một số lần xác định, như vòng lặp "for". Phần còn lại chỉ là gói nó gọn gàng để phù hợp với thứ tự lập luận.

  {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

Đã thử nghiệm ở Kona và oK .

Chỉnh sửa:

Nếu tôi được phép đảo ngược các đối số, như @ kirbyfan64sos đã xác định, tôi có thể phân phối hoàn toàn với hàm gói:

+\/

Được gọi như:

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

Điều này hoạt động đúng trong cả k2.8 và k5. Nó không hoạt động trong oK vì trình thông dịch chưa hỗ trợ các trạng từ (hay còn gọi là "dự kiến"), và nó dường như không hoạt động chính xác trong Kona vì những lý do ít rõ ràng hơn.

chỉnh sửa : Kể từ vài ngày trước, +\/công thức cũng hoạt động trong oK.


1
Các đối số có thể được đảo ngược , vì vậy tôi nghĩ rằng bạn có thể cạo một vài byte.
kirbyfan64sos

3 +\/ -3 4 7 -1 15Kona chỉ hoạt động tốt, nhưng bạn không thể gán nó cho một chức năng. Thật kỳ lạ ...
Dennis

Vâng, Kona rõ ràng không đối xử 3+\/-3 4 7 -1 15giống như +\/[3;-3 4 7 -1 15]- khiến tôi tự hỏi liệu họ có xử lý trước đây như một trường hợp cú pháp đặc biệt hay không.
JohnE

4

Bình thường, 9 byte

usM._GvwQ

Dùng thử trực tuyến: Trình diễn hoặc Test Suite

Giải trình

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

Julia, 29 byte

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

Điều này thực sự không cần giải thích nhiều. Đây là một hàm đệ quy, nếu y==0sau đó chỉ xuất ra x. Nếu không thì giảm y, thực hiện cumsum và lặp lại. Có lẽ không phải là giải pháp Julia có thể chơi golf nhất, tôi vẫn đang nghiên cứu nó.


4

Mê cung , 73 byte

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

Đã được một thời gian kể từ khi tôi trả lời một cái gì đó trong Labyrinth, và điều này dường như có thể thực hiện được. :)

Định dạng đầu vào là một danh sách phẳng với số lần lặp đầu tiên (và sau đó là danh sách để áp dụng tổng một phần cho). Dấu phân cách không quan trọng tất cả, miễn là không có ký tự sau số nguyên cuối cùng, vì vậy bạn có thể sử dụng nội dung có thể đọc được như:

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

Đầu ra được phân tách bằng dòng mới:

-3
-5
1
14
49

4

R, 75 byte

Nó dài nhưng khác nhau ... tính toán chuỗi mong muốn trực tiếp thay vì tổng tích lũy:

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

Lưu ý rằng các hệ số của các điều khoản của xi cho cumsum ^ n (x) là các đường chéo của tam giác Pascal. I E

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

chỉnh sửa: để thực hiện một chức năng


4

Con trăn 2, 67

Điều này sử dụng tổng kết giống như Anthony Roitman , và đệ quy tương tự như Morgan Thrapp .

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

Tôi đã phát triển giải pháp này trước khi tôi thấy chúng, và sau đó có vẻ dễ dàng hơn để đăng nó dưới dạng một câu trả lời thay vì bình luận cho một hoặc cả hai.


4

Python, 113 93 89 76 byte

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

Nó hoạt động cho cả hai trường hợp thử nghiệm. Cảm ơn Status, Morgan Thrapp và Ruth Franklin đã giúp tôi đánh golf chương trình xuống còn 93, 89 và 76 byte tương ứng.


1
Bạn có thể cắt ra một số byte bằng cách thay đổi vòng lặp thứ hai thành một sự hiểu biết danh sách. Đó là, k=[sum(l[:j+1])for j in range(len(l))]. Sau đó, với ;k=lphần cuối được xử lý, bạn có thể đẩy tất cả lên một dòng bằng for ivòng lặp.
Trạng thái

1
Bạn có thể di chuyển k=[sum(l[:j+1])for j in range(len(l))];l=klên cùng một dòng với vòng lặp for để lưu 2 byte và xóa khoảng trống giữa các đối số của f để lưu một byte khác.
Morgan Thrapp

Khi bạn không sử dụng giá trị của i, bạn có thể thay thế for i in range(n)bằng for i in[0]*n(vì tất cả những gì bạn quan tâm là độ dài không phải là các yếu tố của danh sách). Và tôi nghĩ bạn có thể làm điều đó mà không cần sử dụng danh sách phụ trợ k, chỉ cần sửa đổi đối số l.
Ruth Franklin

4

Gol> <> 0,3.10 , 22 byte

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

Số nguyên đầu tiên được lấy là số lần lặp và phần còn lại tạo thành danh sách. Danh sách cuối cùng được xuất ra tách dòng mới.

Ngôn ngữ vẫn còn khá trẻ và không ổn định, nhưng vì tôi khá tập trung vào các toán tử này nên tôi nghĩ nó sẽ ổn.

Giải trình

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

Để xem tại sao điều này hoạt động, hãy thử một ví dụ nhỏ [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 byte

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

Hàm đệ quy đệ quy cả trong danh sách lvà số lần lặp n. Hãy phá vỡ nó.

Trước tiên, hãy xem xét một hàm đệ quy glặp lại tổng một phần.

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

Đối với một danh sách trống l, cái này trả về lchính nó, danh sách trống. Mặt khác, mục cuối cùng của tổng một phần llà tổng của l, được thêm vào kết quả đệ quy cho tất cả trừ phần tử cuối cùng của l.

Bây giờ, hãy xem xét một chức năng fáp dụng gcho các nlần lặp.

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

Khi n0, này trả về danh sách lkhông thay đổi, và nếu không, áp dụng gmột lần, sau đó gọi fđệ quy với một ít lặp còn lại.

Bây giờ, chúng ta hãy nhìn lại mã thực tế, kết hợp hai lần truy cập thành một hàm duy nhất. Ý tưởng là coi g(l)trường hợp đặc biệt f(l,1).

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

Chúng tôi lấy f(g(l),n-1)từ định nghĩa trước đó, mở rộng g(l)thành g(l[:-1])+[sum(l)]và sau đó thay thế g(_)bằng f(_,1)để giới hạn các cuộc gọi đệ quy đến f.

Đối với trường hợp cơ sở, chúng tôi muốn trả lại lbất cứ khi nào n==0hoặc l==[]. Chúng tôi kết hợp những thứ này bằng cách lưu ý rằng một trong hai n*lsẽ là danh sách trống, đó là Falsy. Vì vậy, chúng tôi tái diễn bất cứ khi nào n*llà không trống, và trở lại lkhác.

Mặc dù có hai lệnh gọi đệ quy đến f, nhưng điều này không gây ra sự bùng nổ theo cấp số nhân định nghĩa đệ quy của các số Fibonacci, nhưng vẫn là bậc hai.


3

C ++ (61 + 17 = 78 byte)

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

Trường hợp thử nghiệm:

#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 << " ";
}

Điều này có một chút tự do với đặc tả: nó sử dụng một mảng kiểu C, chuyển các con trỏ đến đầu và cuối của mảng. Trong nội bộ, như bạn có thể thấy, nó chỉ là một trình bao bọc cực kỳ mỏng xung quanh std::partial_sumtrong thư viện tiêu chuẩn. Thay vì thực sự trả về giá trị kết quả, nó chỉ sửa đổi mảng được truyền vào.

Nếu chúng ta không ngại đẩy các định nghĩa về mọi thứ đến giới hạn (và, có thể nói là vượt xa một chút), chúng ta có thể định nghĩa một "hàm" trong biểu thức lambda:

#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 << " ";
}

Điều này làm giảm định nghĩa của hàm (đối tượng giống như) đối với phần này:

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

... cho 40 byte (+17 cho #include).


Wau, tôi không mong đợi STL có alg để tính tổng một phần.
Zereges

1
@Zereges: Không ai mong đợi Tòa án dị giáo Tây Ban Nha .... oh, chờ đã, chúng tôi đang làm C ++, không phải Python. Lời xin lỗi của tôi.
Jerry Coffin


2

Haskell, 52 47 byte

Lần đầu tiên mã golf 'cố gắng', và tôi rất nhiều người mới bắt đầu Haskell, vì vậy các ý kiến ​​rất vui mừng! Trong câu hỏi không rõ ràng về bất kỳ định dạng cần thiết nào của lệnh gọi hàm, hoặc liệu nó có được đưa ra bởi một đối số cho chương trình hay không, vì vậy tôi đã sử dụng dấu chấm than làm định danh hàm để lưu một vài khoảng trắng.

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

Cách sử dụng (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]

Chào mừng bạn đến với mã golf! Nó thường ngắn hơn để khớp mẫu hơn là sử dụng lính canh, như thế 0!a=a i!a=....
xnor

Cảm ơn @xnor - Trước đây tôi đã sử dụng 'xs' khi xây dựng mã ban đầu và phải bỏ lỡ nó khi tôi sửa đổi mã trong bài đăng. Đã chỉnh sửa.
Jake

Đối với sum(take j a), bạn có thể tránh parens bằng cách làm sum$take j a, sử dụng ưu tiên cao $.
xnor

Cảm ơn sự giúp đỡ của bạn! Tôi, vì một số lý do, dưới ấn tượng $sẽ được ưu tiên hơn cú pháp (và cố gắng đánh giá phần còn lại của dòng khi nó đứng). Tất nhiên, điều đó thậm chí sẽ không có ý nghĩa.
Jake

2

R, 41 byte

function(x,n){for(i in 1:n)x=cumsum(x);x}

2

C #, 52 + 85 = 148 137 byte

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);}

Nó sử dụng các thực tiễn không chính thống ( v=>t+=v), nhưng đây là PPCG. Cũng lưu ý các ràng buộc độ sâu ngăn xếp.


2

Con trăn 3, 73

Có lẽ có thể được đánh golf xuống một chút nữa.

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

Phiên bản này sử dụng numpy, cảm giác hơi giống như gian lận, nhưng đây là:

Python 3 (với 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 (bao gồm) = 111 byte

#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, với trường hợp thử nghiệm

#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 << " ";
}

Dựa vào thứ tự đánh giá. Không chắc nó có phải là UB hay không, nhưng nó hoạt động phụ thuộc vào trình biên dịch, vì vậy tôi đã thay đổi nó.


Thay vì đếm jtừ 0 đến n, hãy đếm nngược xuống 0. Cung cấp 97 byte cho số đếm của tôi.
Jerry Coffin

@JerryCoffin Cảm ơn ..
Zereges


1

Burlesque, 10 byte

{q++pa}jE!

Nói chung nó không hiệu quả lắm nhưng nó thực sự là mánh khóe.

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 byte

Như lambda chưa được đặt tên sửa đổi đầu vào của nó, yêu cầu cnhư một thùng chứa truy cập ngẫu nhiên như thế nào vector<int>.

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


1

Thạch , 3 byte

SƤ¡

Hãy thử trực tuyến!

Đây là phương pháp của tôi ( Mr Xcoder ).

Thạch , 3 byte

+\¡

Hãy thử trực tuyến!

Đây là giải pháp của caird coinheringaahing .

Phương pháp số 1

SƤ¡ - Chương trình đầy đủ, dyadic.

  - Áp dụng nhiều lần, N lần.
 - Ánh xạ liên kết trước qua các tiền tố của danh sách.
S - Tổng.
     - Đầu ra ngầm

Phương pháp # 2

+ \ ¡- Chương trình đầy đủ, dyadic.

  - Áp dụng nhiều lần, N lần.
 \ - Giảm tích lũy theo:
+ - Bổ sung.

0

Tiên đề 213 47 byte

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

ungolf và một số ví dụ

 (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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.