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:


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.


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.


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

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 à


@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

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>


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.


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

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.


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

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


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.


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.


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]

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.


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


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]

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}

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.


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)

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


Au lieu de compter jde 0 à n, compte à nrebours jusqu'à 0. Donne 97 octets par mon compte.
Jerry Coffin

@JerryCoffin Thanks ..
Zereges


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}

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


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.

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.