Tekrarlanan kısmi toplamlar


23

Bir tamsayı listesinin kısmi toplamları [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

Daha sonra kısmi toplamların listesini alabiliriz [s 1 , s 2 , s 3 , ..., s n ] ve kısmi toplamları yeni bir liste üretmek için tekrar hesaplayabiliriz, vb.

İlgili: Yinelenen ileri farklar

Giriş:

  • Boş olmayan bir tamsayı listesi
  • Olumlu sayıda yineleme,

Çıktı: Kısmi toplamları almanın sonucu olan tam sayıların listesini yazdırın veya döndürün.

En az bayt kazanır. Yapılışı sorunu tamamen düzeltseler bile sorun yok.

Test durumları:

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

Liderler Sıralaması:


Argümanların aynı sırada olması mı gerekiyor yoksa yineleme sayısı sayı listesinden önce gelebilir mi?
kirbyfan64sos

@ kirbyfan64sos Ya sipariş.
xnor

Yanıtlar:


14

J, 5 bayt

+/\^:

J.Js'de çevrimiçi olarak deneyin .

Nasıl çalışır

  • /\ argümanı ile kümülatif olarak azaltan bir zarf (sol argüman alan bir işlevdir).

  • Bu nedenle +/\bir birikimli toplam fiil.

  • ^:bir güç birlikte ; toplam kez (f ^: n) yuygulanır .fny

  • Fiil-birleşim treni , (sol) argümanında belirtildiği kadar +/\^:tekrar eden bir zarf oluşturur +/\.

    x (+/\^:) y(x (+/\^:)) yyürütmeye eşdeğer olarak ayrıştırılır (+/\^:x) y.

Açıklamadaki yardımları için @ Zgarb'a teşekkür ederiz.


13

Mathematica, 19 bayt

Peki, eğer inşa tamamsa ...

Accumulate~Nest~##&

Görevdeki örneklerle aynı imzayla bir işlevi tanımlar. Eminim ki, Accumulatebunun golf oyuncuları ve APL ailesi tarafından kolayca yenileceği uzun adı sayesinde . :)

LegionMammal978'in Mathematica bilmeyenler için yaptığı yorumları incelemek için:

##işlevin parametrelerinin bir sırasını temsil eder (bu, dilediğiniz dilde o terime daha aşina iseniz, eklenen her yere otomatik olarak "uyarılan" bir liste gibidir). ~Biz parametrelerle işlevini çağırmak eğer öyleyse, infix fonksiyonu çağırma sözdizimsel şeker listve nbiz almak ve her şeyi genişletin:

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

Beklenilen argüman sırası tam olarak bu olur Nest.


Bu ilginç, 3 argüman için infix notasyonu kullanarak SlotSequence...
LegionMammal978

9

Haskell, 26 23 bayt

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

Bu, aşağıdaki şekilde çağrılan isimsiz bir işlevi tanımlar:

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

3 byte tasarruf için @ nimi teşekkürler.

açıklama

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

Çok hoş! Ve açıklama için teşekkür ederim!
Jake,

2
Git pointfree, o zaman bile işlev için adını atlayabilirsiniz: (!!).iterate(scanl1(+)).
nimi

@ nimi Teşekkürler! Her nasılsa, kompozisyonun buradaki avantajım için işe yaramayacağına karar verdim ...
Zgarb

9

APL, 9 8 bayt

{+\⍣⍺⊢⍵}

Bu, yinelemeleri kabul eden ve listeyi sol ve sağ argümanlar olarak kabul eden ikili bir işlevi tanımlar.

1 byte kapalı golf için @NBZ teşekkürler!

TryAPL'de çevrimiçi olarak deneyin .

Nasıl çalışır

  • ve fonksiyonun sol ve sağ argümanlarıdır.

  • +\ birikimli toplam olarak azaltma.

  • ⍣⍺önceki operatör zamanlarını tekrarlar .

  • ⊢⍵kimlik işlevini uygular .

    Bu şekilde kod ayrıştırma daha kısa bir yoldur (+\⍣⍺)⍵yerine +\⍣(⍺⍵).

Bununla birlikte, +\toplam kez


@AlexA .: O +\⍣⎕⊢⎕zaman kabul edilemez mi? ( Python gibi input()).
marinus

1
@ marinus Bu aslında bir REPL'in dışına yazdırıyor mu? Sahip olduğum tek masaüstü tercümanları sonradan atamam gerekiyor .
Dennis,

5

Matlab, 41 bayt

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

Oldukça açık. Ben hala parçalara ayrılmış anonim işlevler ya da özyinelemelerde çapa yapmak için inşa edilmiş bir şekilde yapmamayı oldukça can sıkıcı olduğunu düşünüyorum.

Ungolfed:

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

5

JavaScript (ES6) 38

Tekrarlayan .map kullanarak şaşırtıcı derecede küçük

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 bayt

{y+\/x}

J çözümüne çok benzer. +\tam olarak kısmi bir toplam gerçekleştirir ve /bir monadik fiil ve bir tamsayı sol argümanı ile sağlandığında, bir "for" döngüsünde olduğu gibi, belirtilen sayıda yinelenir. Gerisi sadece argümanların sırasına uyacak şekilde düzgünce sarılıyor.

  {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 ve OK'de test edilmiştir .

Düzenle:

Argümanları tersine çevirebilirsem, @ kirbyfan64sos belirlenirse, tamamen fonksiyon sarma işlevinden vazgeçebilirim:

+\/

Gibi çağrıldı:

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

Bu hem k2.8 hem de k5'te düzgün çalışır. Tercüman henüz kavrulmuş (diğer adıyla "öngörülen") zarfları desteklemediğinden ve daha az net nedenlerle Kona'da düzgün çalıştığı görülmediğinden, OK'de çalışmaz.

düzenleme : Birkaç gün önce, +\/formülasyon da OK'de çalışır.


1
Argümanlar tersine çevrilebilir , bu yüzden birkaç bayt tıraş edebileceğinizi düşünüyorum.
kirbyfan64sos

3 +\/ -3 4 7 -1 15Kona'da gayet iyi çalışıyor ancak bir işleve atayamazsınız. Garip ...
Dennis,

Evet, Kona açıkça 3+\/-3 4 7 -1 15aynı şekilde davranmıyor +\/[3;-3 4 7 -1 15]- eskiyi özel bir sözdizimsel durum olarak ele alıp almadıklarını merak ediyor.
JohnE

4

Pyth, 9 bayt

usM._GvwQ

Çevrimiçi deneyin: Gösteri veya Test Paketi

açıklama

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 bayt

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

Bunun gerçekten fazla bir açıklamaya ihtiyacı yok. Özyinelemeli bir işlev, eğer y==0o zaman sadece x çıktı. Aksi takdirde y azaltın, bir cumsum yapın ve tekrarlayın. Muhtemelen en golf mümkün Julia çözüm değil, ben hala üzerinde çalışıyorum.


4

Labirent , 73 bayt

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

Bir süredir Labirent'te bir şeyi cevapladım ve bu mümkün gözüküyordu. :)

Girdi biçimi, önce yineleme sayısını gösteren düz bir listedir (ve sonra kısmi toplamları uygulayacağınız liste). Sınırlayıcılar, son tamsayıdan sonra hiçbir karakter olmadıkça, önemli değil, bu nedenle şöyle bir şey kullanabilirsiniz:

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

Çıktı newline ayrılmış:

-3
-5
1
14
49

4

R, 75 bayt

Uzun ama farklı bir toplama ... kümülatif toplamlar yerine doğrudan istenen sekansı hesaplama:

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

Cumsum ^ n (x) için xi terimlerinin katsayılarının Pascal üçgeninin köşegenleri olduğuna dikkat edin. yani

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

düzenleme: bir işlev yapmak için


4

Python 2, 67

Bu, Anthony Roitman ile aynı toplamı ve Morgan Thrapp ile aynı özyinelemeyi kullanır .

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

Onların çözümlerini görmeden önce bu çözümü geliştirdim ve daha sonra ikisine de ya da ikisine de yorum yapmak yerine yanıt olarak göndermek daha kolay görünüyordu.


4

Python, 113 93 89 76 bayt

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

Her iki test durumu için de işe yarar. Status sayesinde, Morgan Thrapp ve Ruth Franklin, programı sırasıyla 93, 89 ve 76 bayta düşürmeme yardım etti.


1
İkinci döngüyü liste kavramasına dönüştürerek birkaç baytı kesebilirsiniz. Bu k=[sum(l[:j+1])for j in range(len(l))],. Sonra bunun üzerine ;k=lçivilenmiş durumdayken, bunların hepsini for iloop ile bir satıra itebilirsiniz .
Durum

1
k=[sum(l[:j+1])for j in range(len(l))];l=k2 bayt kaydetmek için for döngüsünün aynısını satırın üzerine getirebilir ve başka bir bayt kaydetmek için f'nin argümanları arasındaki boşluğu kaldırabilirsiniz.
Morgan Thrapp

Eğer değerini kullanmayın gibi i, sen yerine for i in range(n)sahip for i in[0]*n(önemsediğiniz tüm uzunluğu değil listenin elemanları olduğu için). Ve yardımcı listeyi kullanmadan yapabileceğinizi k, sadece tartışmayı değiştirebileceğinizi düşünüyorum l.
Ruth Franklin

4

Gol> <> 0.3.10 , 22 bayt

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

İlk tamsayı yineleme numarası olarak alınır ve geri kalanı listeyi oluşturur. Son liste yeni satır ayrılmış olarak verilir.

Dil hala oldukça genç ve kararsız, ancak bu operatörleri kullanmaya başladığımdan beri, bunun iyi olacağını düşündüm.

açıklama

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

Bunun neden işe yaradığını görmek için, küçük bir örnek deneyelim [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 bayt

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

Listede hem recurses bir özyinelemeli fonksiyon lve adım sayısı n. Yıkalım.

İlk gönce kısmi toplamı sadece bir kez yineleyen özyinelemeli bir fonksiyon düşünelim .

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

Boş bir liste için l, bu boş listeyi lkendisi döndürür . Aksi takdirde, kısmi toplamların son girişi, toplamın son ltoplamı ldışındaki özyinelemeli sonuçlara eklenen toplam toplamıdır l.

Şimdi, yinelemeler için fgeçerli bir işleve bakalım .gn

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

Ne zaman nolduğunu 0, bu liste döndürür ldeğişmeden, aksi takdirde geçerlidir garanmamanızı kez fbir az yineleme kalan yinelemeli.

Şimdi, iki özyinelemeyi tek bir işlevde birleştiren gerçek koda tekrar bakalım. Fikir, g(l)özel durum olarak ele almaktır f(l,1).

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

Biz sürdü f(g(l),n-1)önceki tanım, genişletilmiş dan g(l)içine g(l[:-1])+[sum(l)]ve daha sonra değiştirilen g(_)ile f(_,1)karşı tekrarlanan aramalara sınırlı için f.

Baz durumda, biz dönmek istiyorum lzaman n==0ya l==[]. Bunlardan herhangi birinin n*l, Falsy olan boş liste olduğunu belirterek birleştiriyoruz . Öyleyse, ne zaman n*lboş değilsek tekrar eder ve geri ldöneriz.

İki özyinelemeli çağrı olmasına rağmen f, bu Fibonacci sayılarının özyinelemeli tanımını üstel bir patlamaya yol açmaz, ancak ikinci dereceden kalır.


3

C ++ (61 + 17 = 78 bayt)

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

Test durumu:

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

Bu, şartnamede hafif bir özgürlük gerektirir: işaretçileri dizinin başına ve sonuna götüren C tarzı bir dizi kullanır. Dahili olarak, gördüğünüz gibi, standart kütüphanede sadece çok ince bir ambalaj var std::partial_sum. Sonuçta ortaya çıkan değeri döndürmek yerine, sadece iletilen diziyi değiştirir.

Nesnelerin tanımlarını sınıra itmeyi (ve tartışmalı, biraz ötesinde) sakıncası yoksa, bir lambda ifadesinde bir "işlev" tanımlayabiliriz:

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

Bu, fonksiyonun (- like object) tanımını bu parçaya indirger:

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

... 40 bayt için (+17 için #include).


Wau, STL'den kısmi miktarları saymak için alg olmasını beklemiyordum.
Zereges

1
@Zereges: Kimse İspanyol Engizisyonunu beklemiyor .... ah, bekle, C ++ yapıyoruz, Python değil. Özür dilerim.
Jerry Coffin


2

Haskell, 52 47 bayt

İlk önce golf 'girişimini' kodlayın ve ben çok Haskell acemi oldum, bu yüzden yorumlarınızı memnuniyetle bekliyoruz! İşlev çağrısının gerekli herhangi bir formatı veya programın bir argümanı tarafından alınıp alınmadığı sorusu açık değildi, bu nedenle ünlem işaretini birkaç boşluk kazanmak için işlev tanımlayıcısı olarak kullandım.

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

Kullanım (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]

Golf koduna hoş geldiniz! Desen eşleşmesi genellikle koruyucuları kullanmaktan daha kısadır 0!a=a i!a=....
xnor

Thanks @xnor - İlk kodu oluştururken daha önce 'xs' kullanmıştım ve yazıdaki kodu değiştirdiğimde kaçırmış olmalıydım. Düzenlenen.
Jake

Çünkü sum(take j a), sum$take j ayüksek önceliğini kullanarak parenleri önleyebilirsiniz $.
xnor

Yardımın için teşekkürler! Bazı nedenlerden dolayı, $sözdiziminden öncelikli izlenim altındaydım (ve çizginin kalanını olduğu gibi değerlendirmeye çalışıyorum). Tabii ki, bu mantıklı bile olmaz.
Jake

2

R, 41 bayt

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

2

C #, 52 + 85 = 148 137 bayt

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

ve

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

Ortodoks olmayan uygulamaları kullanır ( v=>t+=v), ama bu PPCG. Ayrıca yığın derinliği kısıtına da dikkat edin.


2

Python 3, 73

Muhtemelen biraz daha aşağı golf olabilir.

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

Bu sürüm biraz hile gibi hissediyor, ancak burada:

Python 3 (numpy ile), 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 (dahil) = 111 bayt

#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, test durumu ile

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

Değerlendirme sırasına güvenir. UB olup olmadığından emin değilim, ancak çalışıyor .


Bunun yerine sayma jn 0'dan kadar saymak n0. saatime göre 97 bayt verir aşağı.
Jerry Coffin

@JerryCoffin Thanks ..
Zereges 23:15


1

Burlesque, 10 bayt

{q++pa}jE!

Genel olarak çok verimli değil ama hile yapar.

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 bayt

Adsız bir lambda girişini değiştirir cgibi, rastgele bir erişim-konteyner gibi gerektiren vector<int>.

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



0

Aksiyom 213 47 bayt

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

ungolf ve bazı örnekler

 (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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.