25
\$\begingroup\$

I have a simple challenge for you this time. Given an array of positive integers A (or the equivalent in your language), replace each entry Ai with the sum of the next Ai elements of A, cycling back from the beginning if there are not enough items.

As usual, you can compete in any programming language and can take input and provide output through any standard method and in any reasonable format, while taking note that these loopholes are forbidden by default. You may optionally take the size of A as input too. This is , so the shortest submission (in bytes) for every language wins.

Examples / Test Cases

Given [1,3,4,5], your code should output [3,10,13,14], because 1 is replaced by 3, 3 is replaced by 4+5+1=10 (notice how it wrapped back from the start), 4 by 5+1+3+4=13 and 5 by 1+3+4+5+1=14.

Given [3,2,1,9], your program should produce [12,10,9,33], because we substitute 3 with 2+1+9=12, 2 with 1+9=10, 1 with 9 and 9 with 3+2+1+9+3+2+1+9+3=33 (notice how we wrapped back from the start more than once).

Some more test cases for you to choose from:

[4,3,2,1]                       -> [10,7,5,4]
[3,2,1,9]                       -> [12,10,9,33]
[1,3,4,5]                       -> [3,10,13,14]
[4,4,3,2,2]                     -> [11,11,8,6,8]
[3,5,3,2,1]                     -> [10,14,6,4,3]
[3,2,4,3,2,1,1]                 -> [9,7,7,4,2,1,3]
[7,8,6,5,4,3,2,1,5]             -> [29,33,20,15,11,8,6,5,30]
[28,2,4,2,3,2,3,4,5,3]          -> [137,6,10,5,9,7,12,38,39,34]
[1,2,3,4,5,4,3,2,1,2,3,4,3,2,1] -> [2,7,13,14,12,8,5,3,2,7,9,7,4,2,1]
\$\endgroup\$

29 Answers 29

8
\$\begingroup\$

MATL, 10 9 bytes

"G@:X@+)s

Try it online!

	% implicit input
"	% for loop, iterate over the input array 
G	% push input x
@	% push for loop index, x[i]
:	% range, push [1,...,x[i]]
X@	% push for loop index, i
+	% sum, so stack holds [i+1,...,i+x[i]]
)	% index, modularly, so gets the cyclic successors
s	% sum cyclic successors, leaving the sum on the stack
	% implicit end of for loop
	% implicit output of stack
\$\endgroup\$
6
\$\begingroup\$

Jelly, 6 bytes

ṙJṁS¥"

Try it online!

\$\endgroup\$
  • \$\begingroup\$ ...ah ninja'd :( \$\endgroup\$ – Jonathan Allan Jun 16 '18 at 18:22
  • \$\begingroup\$ @JonathanAllan TBF, I already sort of had this lying for a minute or two when you posted yours (I thought the integer itself had to be included as well, so with an extra + at the end). Also, eh, maybe you will ninja me next time. :) \$\endgroup\$ – Erik the Outgolfer Jun 16 '18 at 18:24
6
\$\begingroup\$

Python, 55 bytes

lambda a:[sum((-~v*a)[i:i+v])for i,v in enumerate(a,1)]

Try it online!

\$\endgroup\$
  • \$\begingroup\$ not too familiar with python can you explain the part in parens after sum? \$\endgroup\$ – Jonah Jun 16 '18 at 22:45
  • 2
    \$\begingroup\$ Firstly the ~ operator is a bitwise not, it's effectively shorthand for -1-v, so -~v is shorthand for -(-1-v) which is just 1+v (but avoids parentheses like (1+v)*a). Secondly in Python one may multiply a list by an integer to repeat it (e.g. ['a','b']*3 is ['a','b','a','b','a','b']). The -~v*a could be replaced by a+v*a for the same byte count. Lastly the [i:i+v] is a slice indexing, keeping elements i to i+v-1 (0-indexed) only. \$\endgroup\$ – Jonathan Allan Jun 16 '18 at 22:57
6
\$\begingroup\$

J, 33 bytes

[:({.+/@{.}.)"1 i.@#|."{($~>./*#)

ungolfed

[: ({. +/@{. }.)"1 i.@# |."0 _ ($~ (>./ * #))

explanation

enter image description here

Try it online!

\$\endgroup\$
  • \$\begingroup\$ fancy explanation :o \$\endgroup\$ – Conor O'Brien Jun 16 '18 at 21:15
  • 1
    \$\begingroup\$ Cool picture over there, but I recommend putting the explanation in text form too, since images might not last forever. ;) \$\endgroup\$ – Erik the Outgolfer Jun 16 '18 at 22:41
  • 7
    \$\begingroup\$ This looks like a roguelike game. \$\endgroup\$ – aschepler Jun 16 '18 at 22:56
  • \$\begingroup\$ What's the score if you rewrite my K solution in J? \$\endgroup\$ – streetster Jun 17 '18 at 8:12
6
\$\begingroup\$

C (gcc), 86 85 bytes

  • Saved a byte thanks to Jakob.
C(y,c,l,i,k)int*y;{for(l=~0;++l<c;printf("%d,",k))for(k=i=0;i++<y[l];k+=y[(l+i)%c]);}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ -1 byte: for(k=i=0;i++<y[l];)k+=y[(l+i)%c]; \$\endgroup\$ – Jakob Jun 17 '18 at 0:43
  • 1
    \$\begingroup\$ Have my upvote for C(y,c,l,i,k). \$\endgroup\$ – Jonas Schäfer Jun 17 '18 at 14:15
6
\$\begingroup\$

Haskell, 50 47 44 bytes

zipWith((sum.).take)<*>scanr(:)[].tail.cycle

Try it online!

                    -- <*> in function context is Haskell's S combinator, i.e.
                    --     (zipWith ... <*> scanr ...) arg
                    -- resovles to
                    --     zipWith ... arg (scanr ... arg)
zipWith             -- so we zip
                    --   the input list and
 scanr(:)[]         --   the tails (tails of [1,2,3] are [[1,2,3],[2,3],[3],[]])
      tail          --   of the tail of
          cycle     --   and infinite cycle of the input list
                    -- with the function
 (sum.).take        --   take that many elements given by the element
                    --   of the input list from the list given by the inits
                    --   and sum it   
\$\endgroup\$
  • \$\begingroup\$ Nice job! Actually, scanr(:)[] is tails \$\endgroup\$ – Damien Jun 18 '18 at 13:11
  • \$\begingroup\$ @Damien: tails. Right! Thanks! \$\endgroup\$ – nimi Jun 18 '18 at 14:33
4
\$\begingroup\$

05AB1E, 8 7 bytes

εL¾+èO¼

Try it online!

Explanation

ε        # apply to each element x of the input
 L       # push range [1 ... x]
  ¾+     # add counter to each (initially 0)
    è    # cyclically index into input with each
     O   # sum
      ¼  # increment counter
\$\endgroup\$
4
\$\begingroup\$

K4 / K (oK), 20 19 bytes

Solution:

+/'x#'1_(1+2##x)#x:

Try it online!

Examples:

q)k)+/'x#'1_(1+2##x)#x:1 3 4 5
3 10 13 14
q)k)+/'x#'1_(1+2##x)#x:4 3 2 1
10 7 5 4
q)k)+/'x#'1_(1+2##x)#x:3 2 4 3 2 1 1
9 7 7 4 2 1 3
q)k)+/'x#'1_(1+2##x)#x:1 2 3 4 5 4 3 2 1 2 3 4 3 2 1
2 7 13 14 12 8 5 3 2 7 9 7 4 2 1

Explanation:

Reshape input, drop first, take x length of each, sum up.

+/'x#'1_(1+2##x)#x: / the solution
                 x: / store input as x
                #   / reshape
        (      )    / do this together
             #x     / count x
           2#       / duplicate (2-take)
         1+         / add 1
      1_            / 1 drop (_), remove first element
   x#'              / x take each-both
+/'                 / sum (+/) each
\$\endgroup\$
3
\$\begingroup\$

Jelly, 7 bytes

R+"Jị⁸§

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Attache, 26 bytes

{Sum=>_[(_2+1:_)%#_]}#Iota

Try it online!

Explanation

This is a fork of two functions:

  • {Sum=>_[(_2+1:_)%#_]}
  • Iota

What this means is, the right tine Iota is applied to the argument x and is passed as the second argument to the center tine (the first function). So this becomes, for input x:

{Sum=>_[(_2+1:_)%#_]}[x, Iota[x]]

Replacing those in for _ and _2:

Sum => x[(Iota[x] + 1:x) % #x]

Iota[x] returns an array of the indices of x. It's equivalent to 0...#x. #x is a short way of saying the size of x, or Size[x]. In essence, this function is mapping the Sum function over the second expression:

x[(Iota[x] + 1:x) % #x]

The outer x[...] bit means that ... will generate a series of indices to be selected from x. The most important part of generating the indices is this:

Iota[x] + 1:x

This expression uses a bit of vectorization. To visualize this, let's suppose the input is x := [1, 3, 4, 5]. Then, this expression is equivalent to:

Iota[[1, 3, 4, 5]] + 1:[1, 3, 4, 5]
[0, 1, 2, 3] + [1:1, 1:3, 1:4, 1:5]
[0, 1, 2, 3] + [[1], [1, 2, 3], [1, 2, 3, 4], [1, 2, 3, 4, 5]]
[0 + [1], 1 + [1, 2, 3], 2 + [1, 2, 3, 4], 3 + [1, 2, 3, 4, 5]]
[[0 + 1], [1 + 1, 1 + 2, 1 + 3], [2 + 1, 2 + 2, 2 + 3, 2 + 4], [3 + 1, 3 + 2, 3 + 3, 3 + 4, 3 + 5]]
[[1], [2, 3, 4], [3, 4, 5, 6], [4, 5, 6, 7, 8]]

This is a list of indices which represent the indices next N elements in x mod #x. To make them safe for retrieval, we take this array mod #x:

(Iota[x] + 1:x) % #x

This gives us the proper indices, which are then obtained from x and each array is summed, giving the proper results.

Other attempts

36 bytes: {Sum@_&Get=>((_2+1.._2+_)%#_)}#Iota - I forgot x[...] fully vectorizes, so that becomes:

30 bytes: {Sum=>_[(_2+1.._2+_)%#_]}#Iota - but then I realized the _2+ in the inner range could be factored out, which means we could save parentheses by using : instead of .., giving us the current version.

\$\endgroup\$
3
\$\begingroup\$

R, 89 64 bytes

j=rep(x<-scan(),max(x));Map(function(u,v)sum(j[v+1:u]),x,seq(x))

Try it online!

Main idea to to generate a way-long-enough cycling index vector you can use to get the needed elements from the input vector.

Original version:

function(x,i=seq(x),j=rep(i,max(x))){for(k in i){T=c(T,sum(x[j[(k+1):(k+x[k])]]))};T[-1]}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Since it’s allowed to take the length as an additional argument...75 \$\endgroup\$ – JayCe Jun 17 '18 at 2:50
  • 1
    \$\begingroup\$ 69 funny I had started something similar but using cumsum and got lost in the process... nice solution! \$\endgroup\$ – JayCe Jun 17 '18 at 2:56
  • \$\begingroup\$ 66( using Map. The output is a bit ugly so the TIO link un lists it. I guess a full program would be even shorter ! \$\endgroup\$ – JayCe Jun 17 '18 at 3:16
  • \$\begingroup\$ it is \$\endgroup\$ – JayCe Jun 17 '18 at 3:21
  • \$\begingroup\$ 63 bytes \$\endgroup\$ – JayCe Jun 17 '18 at 3:31
3
\$\begingroup\$

R, 62 58 bytes

function(a,l)diag(diffinv(matrix(a,max(a)*l+1,l))[a+2,])-a

Try it online!

An alternative to the other R solution. In the comments JayCe made a mention of cumsum which triggered something in my brain to use diffinv and matrix recycling instead of rep.

Explanation:

Given input array a, let M=max(a) and l=length(a).

Observe that M+l is the maximum possible index we'd need to access, and that M+l<=M*l+1, since if M,l>1,M+l<=M*l (with equality only when M=l=2) and if l==1 or M==1, then M+l==M*l+1.

By way of example, let a=c(4,3,2,1). Then M=l=4.

We construct the M*l+1 x l matrix in R by matrix(a,max(a)*l+1,l). Because R recycles a in column-major order, we end up with a matrix repeating the elements of a as such:

      [,1] [,2] [,3] [,4]
 [1,]    4    3    2    1
 [2,]    3    2    1    4
 [3,]    2    1    4    3
 [4,]    1    4    3    2
 [5,]    4    3    2    1
 [6,]    3    2    1    4
 [7,]    2    1    4    3
 [8,]    1    4    3    2
 [9,]    4    3    2    1
[10,]    3    2    1    4
[11,]    2    1    4    3
[12,]    1    4    3    2
[13,]    4    3    2    1
[14,]    3    2    1    4
[15,]    2    1    4    3
[16,]    1    4    3    2
[17,]    4    3    2    1

Each column is the cyclic successors of each element of a, with a across the first row; this is due to the way that R recycles its arguments in a matrix.

Next, we take the inverse "derivative" with diffinv, essentially the cumulative sum of each column with an additional 0 as the first row, generating the matrix

      [,1] [,2] [,3] [,4]
 [1,]    0    0    0    0
 [2,]    4    3    2    1
 [3,]    7    5    3    5
 [4,]    9    6    7    8
 [5,]   10   10   10   10
 [6,]   14   13   12   11
 [7,]   17   15   13   15
 [8,]   19   16   17   18
 [9,]   20   20   20   20
[10,]   24   23   22   21
[11,]   27   25   23   25
[12,]   29   26   27   28
[13,]   30   30   30   30
[14,]   34   33   32   31
[15,]   37   35   33   35
[16,]   39   36   37   38
[17,]   40   40   40   40
[18,]   44   43   42   41

In the first column, entry 6=4+2 is equal to 14=4 + (3+2+1+4), which is the cyclic successor sum (CSS) plus a leading 4. Similarly, in the second column, entry 5=3+2 is equal to 10=3 + (4+1+2), and so forth.

So in column i, the a[i]+2nd entry is equal to CSS(i)+a[i]. Hence, we take rows indexed by a+2, yielding a square matrix:

     [,1] [,2] [,3] [,4]
[1,]   14   13   12   11
[2,]   10   10   10   10
[3,]    9    6    7    8
[4,]    7    5    3    5

The entries along the diagonal are equal to the cyclic successor sums plus a, so we extract the diagonal and subtract a, returning the result as the cyclic successor sums.

\$\endgroup\$
  • \$\begingroup\$ Can't wait for the explanation! \$\endgroup\$ – JayCe Jun 18 '18 at 16:57
  • \$\begingroup\$ @JayCe added! as so often happens, explaining it led to another golf; I always recommend adding an explanation so you or others following behind can find another approach, although I don't always have time to do that, haha. \$\endgroup\$ – Giuseppe Jun 18 '18 at 17:30
  • 1
    \$\begingroup\$ The common element to both solutions is the efficient generation of a long-enough recycling of either the index or the elements themselves, since 1-indexed languages can't gracefully use modular arithmetic to get back to the beginning of the array. \$\endgroup\$ – ngm Jun 18 '18 at 19:14
  • \$\begingroup\$ @ngm yeah, for sure. I do like your use of Map, and originally this was like 68 bytes before I figured out I could take l as an input! \$\endgroup\$ – Giuseppe Jun 18 '18 at 20:24
2
\$\begingroup\$

Pyth, 13 11 bytes

.esm@Q+dkSb

Saved 2 bytes thanks to Mr. Xcoder.
Try it here

Explanation

.esm@Q+dkSb
.e         Q   For each index k and value b in (implicit) input...
         Sb    ... get the list [1, ..., b]...
   m  +dk      ... add k to each...
    @Q         ... and index into the input...
  s            ... then take the sum.
\$\endgroup\$
2
\$\begingroup\$

Charcoal, 12 bytes

IEθΣEι§θ⊕⁺κλ

Try it online! Link is to verbose version of code. Explanation:

  θ             Input array
 E              Map over elements
     ι          Current element
    E           Map over implicit range
           λ    Inner index
          κ     Outer index
         ⁺      Sum
        ⊕       Increment
       θ        Input array
      §         Cyclically index
   Σ            Sum
I               Cast to string
                Implicitly print on separate lines
\$\endgroup\$
2
\$\begingroup\$

JavaScript ES6, 65 bytes

a=>a.map((x,y)=>{for(s=0,i=y;i<y+x;)s+=a[++i%a.length];return s})

Straightforward solution. Ungolfed:

a => a.map((x,y) => {
    var s = 0;
    for (i = y; i < y + x; i++) {
        s += a[i % a.length];
    }
    return s;
});

JavaScript's map() function is perfect for the job, it runs the given callback against each element and replaced it by the result of the callback. The callback receives two parameters, the first x is the value and the second y is the index. By taking the modulus i % a.length we can easily loop over the array, multiple times if needed.

Test snippet

(Put the input as JSON notation)

let f = a=>a.map((x,y)=>{for(s=0,i=y;i<y+x;)s+=a[++i%a.length];return s})
<input id=I type="text" size=70 value="[4,3,2,1]"><button onclick="console.log(f(JSON.parse(I.value)))">Run</button>

\$\endgroup\$
2
\$\begingroup\$

Java 8, 87 bytes

A curried void lambda taking an int[] list and int length.

l->s->{for(int i=-1,j,t;++i<s;System.out.println(t))for(j=t=0;j++<l[i];)t+=l[(i+j)%s];}

Try It Online. Note that I've shadowed System.out in this program in order to grab results for prettier printing.

\$\endgroup\$
2
\$\begingroup\$

Julia 0.6, 63 55 53 bytes

A->[sum(repmat(A,v+1)[i+1:i+v])for(i,v)=enumerate(A)]

Try it online!


Older solution:

Julia 0.6, 65 bytes

A->(l=length(A);[sum(A[mod1(j,l)]for j∈i+1:i+A[i])for i∈1:l])

Try it online!


Another solution. Not great by bytecount, but I like it, and it's probably more efficient than the other two, especially if the input has big numbers.

Julia 0.6, 69 bytes

A->(l=length(A);[sum([A;A][i+1:i+A[i]%l])+A[i]÷l*sum(A)for i∈1:l])

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Canvas, 10 bytes

²X{x+⁸@]∑]

Try it here!

Explanation:

{         ] map over the items in the input
 ²X           save this loops counter on X (because of a bad design choice..)
   {    ]     map over 1..current item
    x+          add to it X
      ⁸@        and index in the input using that
         ∑    sum the map
\$\endgroup\$
1
\$\begingroup\$

QBasic 1.1, 115 bytes

INPUT L
DIM A(L)
FOR I=0TO L-1
INPUT C
A(I)=C
NEXT
FOR I=0TO L-1
S=0
FOR C=I+1TO I+A(I)
S=S+A(C MOD L)
NEXT
?S
NEXT

First input is the length L, then L subsequent inputs are the elements in order. L outputs represent the resulting array, with the elements in the order they're presented.

\$\endgroup\$
1
\$\begingroup\$

Japt, 7 bytes

ËÆg°EÃx

Try it here

\$\endgroup\$
1
\$\begingroup\$

APL+WIN, 37 bytes

Prompts for input:

+/¨v↑¨⊂[2](⍳⍴v)⌽((⍴v),⍴n)⍴n←(+/v)⍴v←⎕

Try it online! Courtesy of Dyalog Classic

Explanation:

n←(+/v)⍴v←⎕ prompts for input and creates a repeating vector of length max v

((⍴v),⍴n)⍴n converts n to a matrix of length v x length n

(⍳⍴v)⌽ rotates each row of n by the size of each element of v

⊂[2] converts each row of m to an element in a nested vector

+/¨v↑¨ selects the number of elements from each element of the nested vector according to v and sums
\$\endgroup\$
1
\$\begingroup\$

Ruby, 38 bytes

->a{w=0;a.map{|x|(a*-~x)[w+=1,x].sum}}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

JavaScript, 65 bytes 3̶0̶0̶ ̶b̶y̶t̶e̶s̶

golfed

n=>n.map((z,x)=>{for(s=0,i=x;i<z+x;)s+=n[++i%n.length];return s})

ungolfed

     f = n=>n.map((z,x)=>{
            for(s=0,i=x;i<z+x;)s+=n[++i%n.length];
            return s
            }
        );
console.log(f(process.argv[2].slice(1, -1).split(", ").map(x=>+x)))

Try it online!

(ungolfed version above) I'm new to this codegolf thing!


*updated! thanks to the useful links provided in comments, I managed to reduce the size to 65 bytes!

\$\endgroup\$
  • \$\begingroup\$ Welcome to the site. There are a couple of ways this could be improved. You could use single character variable names, and you can remove extra-white space. (operators don't need to be surrounded by spaces.) \$\endgroup\$ – Sriotchilism O'Zaic Jun 17 '18 at 20:31
  • \$\begingroup\$ Beyond Cat Wizard's tips, we have a collection of Tips for golfing in JavaScript. As you say you are new to golfing, you may also find interesting the generic Tips for golfing in <all languages> too. \$\endgroup\$ – manatwork Jun 18 '18 at 6:31
  • \$\begingroup\$ You should add the golfed version before the ungolfed one \$\endgroup\$ – Sefa Jun 18 '18 at 14:10
  • \$\begingroup\$ You're assuming the array is assigned o a predefined variable (n), which we don't allow. Welcome to PPCG, though :) \$\endgroup\$ – Shaggy Jun 18 '18 at 15:16
  • \$\begingroup\$ Here's a 59 byte version. \$\endgroup\$ – Shaggy Jun 18 '18 at 15:16
1
\$\begingroup\$

Perl 5 with -M5.010, 42 bytes

say sum+((@F,@F)x$_)[++$-..($-+$_-1)]for@F

Try it online!

\$\endgroup\$
0
\$\begingroup\$

JavaScript, 46 bytes

a=>a.map(g=(x,y)=>x--&&a[++y%a.length]+g(x,y))

Try it online

\$\endgroup\$
0
\$\begingroup\$

Cjam, 23 bytes

_ee{~,\)f+1$f=:+\}/;]S*

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Pip -rn, 14 bytes

$+g@(_+\,B)MEg

Takes input numbers on successive lines of stdin; gives output numbers on successive lines of stdout. Try it online!

Explanation

             g  List of lines of stdin (from -r flag)
           ME   Enumerate and map this function to the (index, value) pairs:
       \,B       One-based range(value)
     _+          To each element, add the index of that value
  g@(     )      Use the resulting range to slice into the original list g
                 (cyclical indexing is built in)
$+               Sum the numbers in the slice
                Output the list of results one per line (from -n flag)

Or, using a worked example:

             g  [1 3 4 5]
           ME   
       \,B      [(1,2) (1,4) (1,5) (1,6)]
     _+         [(1,2) (2,5) (3,7) (4,9)]
  g@(     )     [[3] [4 5 1] [5 1 3 4] [1 3 4 5 1]]
$+              [3 10 13 14]
\$\endgroup\$
0
\$\begingroup\$

APL (Dyalog Classic), 12 bytes

+/¨⊢⍴¨⍳∘≢⌽¨⊂

Try it online!

uses ⎕io←1

\$\endgroup\$
0
\$\begingroup\$

Perl 6, 50 32 bytes

{$_>>.&{.[++$+ ^$^a X%+$_].sum}}

Try it online!

I'm new to golfing in Perl 6, so I'm sure this can be shorter. Not new anymore, and back to golf this!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.