Sommes partielles itérées

23

Les sommes partielles d'une liste d'entiers [a 1 , a 2 , a 3 , ..., a n ] sont

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

On peut alors prendre la liste des sommes partielles [s 1 , s 2 , s 3 , ..., s n ] et recalculer ses sommes partielles pour produire une nouvelle liste, etc.

Connexes: Différences à terme itérées

Contribution:

  • Une liste non vide d'entiers
  • Un nombre d'itérations positif,

Sortie: affiche ou retourne la liste des entiers résultant de la prise de sommes partielles autant de fois.

Le moins d'octets gagne. Les intégrés sont OK même s'ils résolvent carrément le problème.

Cas de test:

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

Classement:

xnor
la source
Ne les arguments doivent être dans le même ordre, ou peut le nombre d'itérations viennent avant la liste des numéros?
kirbyfan64sos
@ kirbyfan64sos Soit commande.
2015 à 5h08

Réponses:

14

J, 5 octets

+/\^:

Essayez en ligne sur J.js .

Comment ça marche

  • /\ est un adverbe (fonction qui prend un argument de gauche) qui se réduit cumulativement par son argument.

  • Ainsi +/\est le verbe de somme cumulative .

  • ^:est la conjonction de pouvoir ; (f ^: n) ys'applique fun total de nfois à y.

  • Le train de conjonction verbale +/\^:forme un adverbe qui se répète +/\autant de fois que spécifié dans son argument (gauche).

    x (+/\^:) yest analysé en tant que (x (+/\^:)) y, ce qui équivaut à l'exécution (+/\^:x) y.

Merci à @Zgarb pour son aide avec l'explication.

Dennis
la source
13

Mathematica, 19 octets

Eh bien, si les fonctions intégrées sont correctes ...

Accumulate~Nest~##&

Définit une fonction avec la même signature que les exemples du défi. Je suis à peu près sûr, grâce au nom long, Accumulateque cela sera facilement battu par les langues de golf et la famille APL. :)

Pour développer le commentaire de LegionMammal978 pour ceux qui ne connaissent pas Mathematica:

##représente une séquence des paramètres de la fonction (qui est comme une liste qui se "répartit" automatiquement là où elle est insérée, si vous connaissez mieux ce terme dans la langue de votre choix). Il ~s'agit de sucre syntaxique pour l'invocation de la fonction infixe, donc si nous appelons la fonction avec des paramètres listet nque nous développons tout, nous obtenons:

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

Ce qui se trouve être exactement l'ordre des arguments attendu par Nest.

Martin Ender
la source
C'est intéressant, en utilisant la notation infixe pour 3 arguments en utilisant SlotSequence...
LegionMammal978
9

Haskell, 26 23 octets

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

Ceci définit une fonction anonyme, appelée comme suit:

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

Merci à @nimi d'avoir économisé 3 octets.

Explication

(!!).                    -- Index by second argument from
     iterate(         )  -- the infinite list obtained by iterating
             scanl1(+)   -- the partial sums function (left scan by +) to first argument
Zgarb
la source
Très agréable! Et merci pour l'explication!
Jake
2
Go Pointfree, alors vous pouvez même omettre le nom de la fonction: (!!).iterate(scanl1(+)).
nimi
@nimi Merci! D'une certaine manière, j'ai pensé que la composition ne fonctionnerait pas à mon avantage ici ...
Zgarb
9

APL, 9 8 octets

{+\⍣⍺⊢⍵}

Ceci définit une fonction dyadique qui accepte les itérations et la liste comme arguments gauche et droit.

Merci à @NBZ d'avoir joué sur 1 octet!

Essayez-le en ligne sur TryAPL .

Comment ça marche

  • et sont les arguments gauche et droit de la fonction.

  • +\ est cumulativement réduit de somme.

  • ⍣⍺répète les temps opérateur précédents .

  • ⊢⍵applique la fonction d'identité à .

    Il s'agit d'une façon plus courte d'analyser le code au (+\⍣⍺)⍵lieu de +\⍣(⍺⍵).

En conjonction, nous appliquons +\un total de fois à

Dennis
la source
@AlexA .: Alors ce ne serait pas +\⍣⎕⊢⎕acceptable? ( c'est comme Python input()).
marinus
1
@marinus Est-ce que cela s'imprime réellement en dehors d'un REPL? Les seuls interprètes de bureau dont j'ai besoin nécessiteraient une affectation par la suite.
Dennis
5

Matlab, 41 octets

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

Assez simple. Je pense toujours qu'il est assez ennuyeux de ne pas avoir une manière intégrée de créer des fonctions anonymes définies par morceaux ou des ancres dans les récursions.

Non golfé:

function f(l,n);
for i=1:n;
    l=cumsum(l);
end
flawr
la source
5

JavaScript (ES6) 38

Étonnamment petit en utilisant récursivement .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>

edc65
la source
5

K, 7 3 octets

{y+\/x}

Très similaire à la solution J. +\effectue avec précision une somme partielle, et lorsqu'il /est fourni avec un verbe monadique et un argument de gauche entier, il itère un nombre spécifié de fois, comme une boucle "for". Le reste est juste en train de l'envelopper soigneusement pour l'adapter à l'ordre des arguments.

  {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

Testé à Kona et oK .

Modifier:

Si je suis autorisé à inverser les arguments, comme l'a déterminé @ kirbyfan64sos, je peux me passer entièrement de la fonction wrapping:

+\/

Appelé comme:

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

Cela fonctionne correctement en k2.8 et en k5. Cela ne fonctionne pas en ok car cet interprète ne prend pas encore en charge les adverbes au curry (aka "projetés"), et il ne semble pas fonctionner correctement dans Kona pour des raisons moins claires.

edit : Il y a quelques jours, la +\/formulation fonctionne également en oK.

JohnE
la source
1
Les arguments peuvent être inversés , donc je pense que vous pourrez peut-être raser quelques octets.
kirbyfan64sos
3 +\/ -3 4 7 -1 15fonctionne très bien dans Kona, mais vous ne pouvez pas l'affecter à une fonction. Bizarre ...
Dennis
Ouais, Kona ne traite clairement pas 3+\/-3 4 7 -1 15la même chose que +\/[3;-3 4 7 -1 15]- me fait me demander s'ils traitent les premiers comme un cas syntaxique spécial.
JohnE
4

Pyth, 9 octets

usM._GvwQ

Essayez-le en ligne: démonstration ou suite de tests

Explication

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
Jakube
la source
4

Julia, 29 octets

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

Cela n'a vraiment pas besoin de beaucoup d'explications. C'est une fonction récursive, si y==0alors il suffit de sortir x. Sinon, décrémentez y, effectuez un cumsum et recommencez. Probablement pas la solution Julia la plus golfée possible, je travaille toujours dessus.

Glen O
la source
4

Labyrinthe , 73 octets

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

Cela fait un moment que je n'ai pas répondu à quelque chose dans Labyrinth, et cela semblait faisable. :)

Le format d'entrée est une liste plate avec le nombre d'itérations en premier (puis la liste à laquelle appliquer les sommes partielles). Les délimiteurs ne comptent pas tous, tant qu'il n'y a pas de caractère après le dernier entier, vous pouvez donc utiliser quelque chose de lisible comme:

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

La sortie est séparée par des sauts de ligne:

-3
-5
1
14
49
Martin Ender
la source
4

R, 75 octets

C'est long mais une prise différente ... calculer directement la séquence souhaitée au lieu des sommes cumulées:

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

Notant que les coefficients des termes de xi pour cumsum ^ n (x) sont des diagonales du triangle de Pascal. c'est à dire

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

modifier: pour créer une fonction

njnnja
la source
4

Python 2, 67

Cela utilise la même somme qu'Anthony Roitman et la même récursivité que Morgan Thrapp .

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

J'ai développé cette solution avant de voir la leur, puis il m'a semblé plus facile de la poster comme réponse plutôt que comme commentaire à l'un d'eux ou aux deux.

mathmandan
la source
4

Python, 113 93 89 76 octets

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

Cela fonctionne pour les deux cas de test. Merci à Status, Morgan Thrapp et Ruth Franklin de m'avoir aidé à jouer le programme à 93, 89 et 76 octets respectivement.

Anthony Roitman
la source
1
Vous pouvez couper un certain nombre d'octets en changeant la deuxième boucle en une compréhension de liste. C'est k=[sum(l[:j+1])for j in range(len(l))]. Ensuite, avec ;k=lclouée à la fin de cela, vous pouvez pousser tout cela sur une seule ligne avec la for iboucle.
Statut
1
Vous pouvez déplacer le k=[sum(l[:j+1])for j in range(len(l))];l=ksur la même ligne que la boucle for pour enregistrer 2 octets et supprimer l'espace entre les arguments de f pour enregistrer un autre octet.
Morgan Thrapp
Comme vous n'utilisez pas la valeur de i, vous pouvez remplacer for i in range(n)par for i in[0]*n(car vous ne vous souciez que de la longueur et non des éléments de la liste). Et je pense que vous pouvez le faire sans utiliser la liste auxiliaire k, en modifiant simplement l'argument l.
Ruth Franklin
4

Gol> <> 0.3.10 , 22 octets

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

Le premier entier est considéré comme le numéro d'itération et les autres constituent la liste. La liste finale est sortie séparée par des sauts de ligne.

La langue est encore assez jeune et instable, mais comme je suis assez attaché à ces opérateurs, j'ai pensé que ça allait.

Explication

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

Pour voir pourquoi cela fonctionne, essayons un petit exemple [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]
Sp3000
la source
3

Python, 52 octets

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

Une fonction récursive qui récursive à la fois sur la liste let le nombre d'itérations n. Décomposons-le.

Tout d'abord, considérons une fonction récursive gqui a répété la somme partielle une seule fois.

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

Pour une liste vide l, cela renvoie llui-même, la liste vide. Sinon, la dernière entrée des sommes partielles de lest la somme globale de l, qui est ajoutée au résultat récursif pour tous sauf le dernier élément de l.

Maintenant, regardons une fonction fqui s'applique gaux nitérations.

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

Quand nest 0, cela renvoie la liste linchangée, et sinon, s'applique gune fois, puis appelle frécursivement avec une itération de moins restante.

Maintenant, regardons à nouveau le code réel, qui combine les deux récursions en une seule fonction. L'idée est de traiter g(l)comme le cas particulier f(l,1).

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

Nous avons repris f(g(l),n-1)de la définition précédente, développé g(l)en g(l[:-1])+[sum(l)], puis remplacé g(_)par f(_,1)pour limiter les appels récursifs à f.

Pour le cas de base, nous voulons revenir lchaque fois que n==0ou l==[]. Nous les combinons en notant que l'un ou l'autre fait n*lêtre la liste vide, qui est Falsy. Ainsi, nous récursions chaque fois qu'il n*ln'est pas vide et revenons lautrement.

Même s'il y a deux appels récursifs à f, cela ne provoque pas une explosion exponentielle de la définition récursive des nombres de Fibonacci, mais reste quadratique.

xnor
la source
3

C ++ (61 + 17 = 78 octets)

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

Cas de test:

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

Cela prend une légère liberté avec la spécification: il utilise un tableau de style C, en passant des pointeurs vers le début et la fin du tableau. En interne, comme vous pouvez le voir, ce n'est qu'un wrapper extrêmement fin autour std::partial_sumde la bibliothèque standard. Plutôt que de renvoyer réellement la valeur résultante, il modifie simplement le tableau transmis.

Si cela ne nous dérange pas de pousser les définitions des choses à la limite (et, sans doute, un peu au-delà), nous pouvons définir une "fonction" dans une expression 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 << " ";
}

Cela réduit la définition de la fonction (objet semblable à) à cette pièce:

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

... pour 40 octets (+17 pour le #include).

Jerry Coffin
la source
Wau, je ne m'attendais pas à ce que STL ait alg pour compter les sommes partielles.
Zereges
1
@Zereges: Personne ne s'attend à l'inquisit espagnol .... oh, attendez, nous faisons du C ++, pas du Python. Mes excuses.
Jerry Coffin
2

Haskell, 52 47 octets

Première tentative de golf de code, et je suis vraiment un débutant Haskell, donc les commentaires sont les bienvenus! Il n'était pas clair dans la question quant au format nécessaire de l'appel de fonction, ou s'il était pris par un argument dans le programme, j'ai donc utilisé le point d'exclamation comme identificateur de fonction pour économiser quelques espaces.

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

Utilisation (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]
Jake
la source
Bienvenue au code golf! C'est généralement plus court pour faire correspondre les motifs que pour utiliser des gardes, comme 0!a=a i!a=....
xnor
Merci @xnor - J'avais déjà utilisé 'xs' lors de la construction du code initial et j'ai dû le manquer lorsque j'ai modifié le code dans le message. Édité.
Jake
Pour sum(take j a), vous pouvez éviter les parens en faisant sum$take j a, en utilisant la haute priorité de $.
xnor
Merci de votre aide! J'étais, pour une raison quelconque, sous l'impression que $cela prendrait le pas sur la syntaxe (et que j'essayais d'évaluer le reste de la ligne en l'état). Bien sûr, cela n'aurait même aucun sens.
Jake
2

R, 41 octets

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

C #, 52 + 85 = 148 137 octets

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

et

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

Il utilise des pratiques peu orthodoxes ( v=>t+=v), mais c'est PPCG. Notez également la contrainte de profondeur de pile.

LegionMammal978
la source
2

Python 3, 73

Pourrait probablement être joué un peu plus loin.

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

Cette version utilise numpy, qui ressemble un peu à de la triche, mais la voici:

Python 3 (avec numpy), 72

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

C ++ 14 102 103 94 + 17 (inclus) = 111 octets

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

Non golfé, avec cas de test

#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épend de l'ordre d'évaluation. Je ne sais pas si c'est UB ou non, mais ça marche Cela dépend du compilateur, donc je l'ai changé.

Zereges
la source
Au lieu de compter jde 0 à n, compte à nrebours jusqu'à 0. Donne 97 octets par mon compte.
Jerry Coffin
@JerryCoffin Thanks ..
Zereges
1

Octave, 24 octets

@(l,n)l*triu(0*l'*l+1)^n
alephalpha
la source
1

Burlesque, 10 octets

{q++pa}jE!

ce n'est pas très efficace en général mais ça fait l'affaire.

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}
mroman
la source
1

C ++ 14, 67 octets

Comme lambda sans nom modifiant son entrée, nécessitant ccomme un conteneur à accès aléatoire comme vector<int>.

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

05AB1E , 4 octets (probablement non concurrents)

F.pO

F    # Implicitly take first input and loop n times.
 .p  # Generate prefixes of input.
   O # Sum all prefixes (implicitly vectorized).

Essayez-le en ligne!

Urne de poulpe magique
la source
1

Gelée , 3 octets

SƤ¡

Essayez-le en ligne!

C'est ma méthode (celle de M. Xcoder ).

Gelée , 3 octets

+\¡

Essayez-le en ligne!

C'est la solution de caird coinheringaahing .

Méthode n ° 1

SƤ¡ - Programme complet, dyadique.

  ¡- Appliquer plusieurs fois, N fois.
 Ƥ - Mappez le lien précédent sur les préfixes de la liste.
S - Somme.
     - Sortie implicite

Méthode n ° 2

+ \ ¡- Programme complet, dyadique.

  ¡- Appliquer plusieurs fois, N fois.
 \ - Réduction cumulative de:
+ - Addition.
M. Xcoder
la source
0

Axiome 213 47 octets

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

ungolf et un exemple

 (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
RosLuP
la source