# Apply a wave to an array

Your task today is to apply a wave to an array of numbers. A wave looks like this: [1, 0, -1, 0, 1, 0, -1, 0, 1...] Applying it to a given array means adding together the first elements, the second elements, etc.

More precisely:

Your program or function will receive an array of integers. It must print or return an equally sized array with 1 added to the 1st, 5th, 9th, etc. element of the original array, -1 added to the 3rd, 7th, 11th, etc. element of the original array, and the rest of the elements should be left untouched.

The input array is guaranteed to have at least one element.

Test cases:

Input                               | Output
                                 | 
[-1]                                | 
[-4, 3, 0, 1, 7, 9, 8, -2, 11, -88] | [-3, 3, -1, 1, 8, 9, 7, -2, 12, -88]
[0, 0, 0, 0, 0]                     | [1 ,0 ,-1 ,0 ,1]
[1, 1]                              | [2, 1]


This is , shortest code wins!

• Somewhat unexepectedly, many solutions are using imaginary number magic... – Pavel Jul 23 '17 at 2:50
• It makes a good deal of sense why imaginary numbers would be useful, this is a wave problem and the imaginary numbers have a well documented history of polar properties. Imaginary numbers can be pretty golfy way of calculating sines and cosines especially for these types of integer quarter rotations. Math is cool ... – Ad Hoc Garf Hunter Jul 23 '17 at 4:00
• @WheatWizard It's a pretty big proportion given most languages don't have support for imaginary numbers. – Pavel Jul 23 '17 at 4:10

# Jelly, 5 bytes

Jı*Ċ+


Try it online!

### How it works

Jı*Ċ+  Main link. Argument: A (array)

J      Indices; yield [1, ..., len(A)].
ı*    Elevate the imaginary unit to the power 1, ..., len(A), yielding
[0+1i, -1+0i, 0-1i, 1+0i, ...].
Ċ   Take the imaginary part of each result.
+  Add the results to the corresponding elements of A.

• Same as what Leaky Nun got: chat.stackexchange.com/transcript/message/38868472#38868472 – Pavel Jul 23 '17 at 3:32
• Any explanation? – Pureferret Jul 24 '17 at 12:05
• @Pureferret the imaginary part of the successive powers of imaginary number i are added to each element – Cœur Jul 24 '17 at 17:22
• @Cœur is that 1, 2, 3 ... or 1, 0, -1, 0 ...? – Pureferret Jul 25 '17 at 7:06
• @Pureferret the same explanation as the answer in MATL or Math.JS or Mathematica or R or ... – Cœur Jul 25 '17 at 7:32

# LOGO, 18 bytes

[map[?+sin 90*#]?]


There is no "Try it online!" link because all online LOGO interpreter does not support template-list.

That is a template-list (equivalent of lambda function in other languages).

Usage:

pr invoke [map[?+sin 90*#]?] [-4 3 0 1 7 9 8 -2 11 -88]


(invoke calls the function, pr prints the result)

prints [-3 3 -1 1 8 9 7 -2 12 -88].

 map[?+sin 90*#]?       map a function over all the items of the input
#         the 1-based index of the element in the input
sin 90*#         equal to the required wave
?                  looping variable
?+sin 90*#         add the wave to the input

• Hah, I knew someone would come up with a sine-based answer. – ETHproductions Jul 23 '17 at 2:39
• @ETHproductions the very first answer, in Mathematica, was based on Sine until it was golfed down. The second answer, in R, is stil using sine. – Pavel Jul 23 '17 at 2:42
• @Phoenix I'm shocked that I didn't notice... – ETHproductions Jul 23 '17 at 2:44
• @ETHproductions and.... Sine has been golfed out of the R answer too. I think it's doing the same thing as the Mathematica answer. – Pavel Jul 23 '17 at 2:46

zipWith(+)$cycle[1,0,-1,0]  Try it online! (runs all test cases) Explanation: zipWith(+)$cycle[1,0,-1,0]  -- anonymous tacit function
zipWith(+)                  -- pairwise addition between input list
$cycle[1,0,-1,0] -- and an infinitely-cycling "wave" list  ## JavaScript (ES6), 28 bytes a=>a.map((x,i)=>x-(i%4-1)%2)  The calculation goes like this: i%4 -1 %2 0 -1 -1 1 0 0 2 1 1 3 2 0  The last bit taking advantage of the fact that in JS, a negative number when modulated will retain its negative sign (i.e. -5 % 3 -> -2, instead of 1 as it would be in Python). # Mathematica, 2623 22 bytes Im[I^Range@Tr[1^#]]+#&  Try it online! (Mathics) Note: The TIO link is for the 23-byte version, the 22-byte version is not Mathics-compatible. • There is a 19-byte Mathematica solution below (with 4 bytes of initialization) – user202729 Jul 25 '17 at 1:28 # Python 2, 40 bytes i=2 for x in input():print~-x+i%5%3;i*=2  Try it online! # MATL, 11 8 bytes Jyn:^Yj+  Try it at MATL Online! ### Explanation J % Push 1j (imaginary unit) % STACK; 1j y % Implicit input. Duplicate from below % STACK: [-4 3 0 1 7 9 8 -2 11 -88], 1j, [-4 3 0 1 7 9 8 -2 11 -88] n % Number of elements % STACK: [-4 3 0 1 7 9 8 -2 11 -88], 1j, 10 : % Range % STACK: [-4 3 0 1 7 9 8 -2 11 -88], 1j, [1 2 3 4 5 6 7 8 9 10] ^ % Power, element-wise % STACK: [-4 3 0 1 7 9 8 -2 11 -88], [1j -1 -1j 1 1j -1 -1j 1 1j -1] Yj % Imaginary part % STACK: [-4 3 0 1 7 9 8 -2 11 -88], [1 0 -1 0 1 0 -1 0 1 0] + % Add, element-wise. Implicit display % STACK: [-3 3 -1 1 8 9 7 -2 12 -88]  • Um, you forgot to add the + in the explanation – caird coinheringaahing Jul 23 '17 at 14:08 • @cairdcoinheringaahing Thanks, edited – Luis Mendo Jul 23 '17 at 14:54 # Jelly, 16 bytes -1Jm2$$¦+2Jm4$$¦  Try it online! heh I'm sure this is too long # Edit I know a 5 byte solution is possible but my wifi appears to be starting to cut me off so I'll golf this tomorrow. If someone posts the short Jelly solution before I can golf this, that's fine with me; I'll just keep this here for reference as to how bad I am at Jelly lol another way of doing it. I mean, I could just look at the link Phoenix posted in the comments, but since I'm still learning, I don't want to look at the solution until I've figured it out myself. This might cost me reputation but the learning is what I'm here for :))) # R, 29 24 bytes (l=scan())+Im(1i^seq(l))  Try it online! # Python 2, 50 42 bytes Saved 8 bytes thanks to @Sisyphus! lambda l:map(sum,zip(l,[1,0,-1,0]*len(l)))  Try it online! ### 53 bytes lambda l:[int(x+(1j**i).real)for i,x in enumerate(l)]  Try it online! • lambda l:map(sum,zip(l,[1,0,-1,0]*len(l))) for Python 2 – Sisyphus Jul 23 '17 at 2:57 • Nice, that saves 5 bytes in Python 3 and then 3 more in Python 2. Thanks! – musicman523 Jul 23 '17 at 3:01 # Haskell, 26 bytes @Mego beat me to this solution zipWith(+)$cycle[1,0,-1,0]


Try it online!

This is what Haskell is great at. This declares a point-free function that zips the input with an infinite list.

Here's a solution that uses complex numbers. Not very competitive because of the import but never the less pretty cool.

import Data.Complex
zipWith((+).realPart.((0:+1)^))[0..]


Try it online!

• Eek! You ninja'd me by 20 seconds! – Mego Jul 23 '17 at 3:33
• There's no point in having two identical solutions. Since you took my improvement without attribution and made our answers identical, would you delete yours? – Mego Jul 23 '17 at 3:36

# Mathematica, 19 bytes

i=1;#+Im[i*=I]&/@#&


### Explanation

i=1;#+Im[i*=I]&/@#&
i=1;                 (* set variable i to 1 *)
/@#   (* iterate through the input: *)
#+Im[i   ]&      (* add the imaginary component of i... *)
*=I        (* multiplying i by the imaginary unit each iteration *)


Note: i=1 appears outside of the function, which is okay per this meta consensus.

• But then the function is not necessarily reusable (if after one call of the function i has value different from 1) – user202729 Jul 25 '17 at 1:32
• @user202729 the meta consensus I linked specifically deals with that issue. It is okay to declare a global variable outside of a function. – JungHwan Min Jul 25 '17 at 3:20

# J, 12 bytes

+1 0 _1 0$~#  Try it online! Because J's shape operator $ fills cyclically, when we shape it to the length # of the input, it does exactly what we want, and we can just add it to the input ]

• You can save a byte by dropping the first ] (ie use a hook) – Tikkanz Jul 24 '17 at 17:30
• @Tikkanz nice catch. i've updated the post. – Jonah Jul 24 '17 at 17:35

## C++, 938583 63 bytes

auto w=[](auto&i){for(int j=0;j<i.size();j+=2)i[j]+=j%4?-1:1;};


-8 bytes, thanks to this answer, i discovered that lambda parameters can be auto and you can pass with the correct parameter, it will work

-2 bytes thanks to Nevay

-2 bytes thanks to Zacharý

I removed the vector include. You will need to pass as argument to w a container that respect the following conditions :

• Have a method called size with no arguments
• Have overloaded the subscript operator

STL Containers that respect the following conditions are array, vector, string, map, unordered_map, and maybe others

If outputting by modifying arguments arguments is not allowed, then :

## C++, 112 110 bytes

#include<vector>
std::vector<int>w(std::vector<int>i){for(int j=0;j<i.size();j+=2)i[j]+=(j%4)?-1:1;return i;}

• Your first one is valid i/o. – Pavel Jul 23 '17 at 22:56
• You can use j%4 to save 2 bytes. – Nevay Jul 23 '17 at 23:34
• I don't think you need parens around j%4. – Zacharý Sep 4 '17 at 16:37

# Pari/GP, 30 bytes

a->[a[x]+imag(I^x)|x<-[1..#a]]


Try it online!

# Dyalog APL, 13 bytes

⊢+1 0 ¯1 0⍴⍨≢


Try it online!

How?

1 0 ¯1 0 - the array [1, 0, -1, 0]

⍴⍨≢ - reshape to the length of the input, cyclic

⊢+ - vectorized sum with the input

# Perl 6, 28 bytes

{((1+0i,*×i...*)Z+$_)».re}  Try it online! 1+0i, * × i ... * produces an infinite list of the numbers 1, i, -1, -i repeateded in a cycle. Those numbers are zipped with addition (Z+) with the input list ($_), and then the real components of the resulting complex numbers are extracted (».re).

# D, 56 bytes

void w(T)(T[]i){for(T j;j<i.length;j+=2)i[j]+=j%4?-1:1;}


Try it online!

This is a port of HatsuPointerKun's C++ answer, so don't forget about them!

# Japt, 11 10 bytes

Takes advantage of Japt's index wrapping.

Ë+[1TJT]gE


Test it

## Explanation

Implicit input of array U.

Ë


Map over the array.

+


gE


The element at the current index (E)...

[1TJT]


In the array [1,0,-1,0].

# Actually, 11 bytes

;r⌠╦½*C≈⌡M¥


Try it online! (runs all test cases)

Explanation:

;r⌠╦½*C≈⌡M¥
;r           range(len(input))
⌠╦½*C≈⌡M   for each value in range:
╦½*C      cos(pi/2*value)
≈     floor to integer
¥  pairwise addition of the input and the new list


# Pyth, 11 bytes

.e+bss^.j)k


Try it online!

• Came up with another solution with the same byte count: .e+b@[1Z_1Z – clapp Jul 23 '17 at 7:08
• Replace ss with e for -1. – Erik the Outgolfer Jul 23 '17 at 10:30
• Does that work? .e+be^.j)k didn't seem to work when I tried it. – deltaepsilon3 Jul 23 '17 at 19:02

# CJam, 15 bytes

l~_,,[1TW0]f=.+


Try it online!

# Math.JS, 34 bytes

f(k)=k.map(j(x,y,z)=x+im(i^y))


## Explained

f(k)=k.map(j(x,y,z)=x+im(i^y))
f(k)=                               # Define a function f, which takes argument k.
k.map(                     )   # Map k to a function
j(x,y,z)=                # Function j. Takes arguments x, y, and z. Where x is the item, y is the index in the form [i], and z is the original list.
im(      )    # The imaginary component of...
i^y     # i to the power of the index.
x+              # x +, which gives our wave.


Try it Online!

# 8th, 96 63 bytes

Code

a:new swap ( swap 90 * deg>rad n:cos int + a:push ) a:each drop


This code leaves resulting array on TOS

Usage and examples

ok> [0,0,0,0,0] a:new swap ( swap 90 n:* deg>rad n:cos n:int n:+ a:push ) a:each drop .
[1,0,-1,0,1]

ok> [-4,3,0,1,7,9,8,-2,11,-88] a:new swap ( swap 90 * deg>rad n:cos int + a:push ) a:each drop .
[-3,3,-1,1,8,9,7,-2,12,-88]


Explanation

We use cos(x) in order get the right sequence [1,0,-1,0]. Each array element's index is multiplied by 90 degrees and then it is passed to cos() function to get the desired "wave factor" to be added to the corresponding item.

: f \ a -- a
a:new    \ create output array
swap     \ put input array on TOS
\ array element's index is passed to cos in order to compute
\ the "wave factor" to add to each item
( swap 90 n:* deg>rad n:cos n:int n:+
a:push ) \ push new item into output array
a:each
drop     \ get rid of input array and leave ouput array on TOS
;


# C# (.NET Core), 50 bytes

n=>{for(int i=0;i<n.Length;i+=2)n[i]+=i%4<1?1:-1;}


Try it online!

Uses a simple lambda. Modifies the original array and returns the output through reference.

# 05AB1E, 16 bytes

vy3L2.SR0¸«Nè+})


Try it online!

3L2.SR0¸« is the shortest thing I can think of for sin(x % 4) in 05AB1E.

# Ruby, 38 bytes

->a{a.zip([1,0,-1,0].cycle).map &:sum}


Try it online!