24
\$\begingroup\$

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
[0]                                 | [1]
[-1]                                | [0]
[-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!

\$\endgroup\$
3
  • \$\begingroup\$ Somewhat unexepectedly, many solutions are using imaginary number magic... \$\endgroup\$
    – Pavel
    Jul 23, 2017 at 2:50
  • 2
    \$\begingroup\$ 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 ... \$\endgroup\$
    – Wheat Wizard
    Jul 23, 2017 at 4:00
  • 3
    \$\begingroup\$ @WheatWizard It's a pretty big proportion given most languages don't have support for imaginary numbers. \$\endgroup\$
    – Pavel
    Jul 23, 2017 at 4:10

30 Answers 30

14
\$\begingroup\$

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

Explanation (already pretty understandable):

 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
\$\endgroup\$
4
  • \$\begingroup\$ Hah, I knew someone would come up with a sine-based answer. \$\endgroup\$ Jul 23, 2017 at 2:39
  • 2
    \$\begingroup\$ @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. \$\endgroup\$
    – Pavel
    Jul 23, 2017 at 2:42
  • 1
    \$\begingroup\$ @Phoenix I'm shocked that I didn't notice... \$\endgroup\$ Jul 23, 2017 at 2:44
  • \$\begingroup\$ @ETHproductions and.... Sine has been golfed out of the R answer too. I think it's doing the same thing as the Mathematica answer. \$\endgroup\$
    – Pavel
    Jul 23, 2017 at 2:46
13
\$\begingroup\$

Haskell, 26 bytes

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
\$\endgroup\$
10
\$\begingroup\$

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

\$\endgroup\$
10
\$\begingroup\$

Mathematica, 26 23 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.

\$\endgroup\$
1
  • \$\begingroup\$ There is a 19-byte Mathematica solution below (with 4 bytes of initialization) \$\endgroup\$
    – DELETE_ME
    Jul 25, 2017 at 1:28
9
\$\begingroup\$

Python 2, 40 bytes

i=2
for x in input():print~-x+i%5%3;i*=2

Try it online!

\$\endgroup\$
8
\$\begingroup\$

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

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]
\$\endgroup\$
0
3
\$\begingroup\$

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

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

R, 29 24 bytes

(l=scan())+Im(1i^seq(l))

Try it online!

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

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!

\$\endgroup\$
2
  • \$\begingroup\$ lambda l:map(sum,zip(l,[1,0,-1,0]*len(l))) for Python 2 \$\endgroup\$
    – Sisyphus
    Jul 23, 2017 at 2:57
  • \$\begingroup\$ Nice, that saves 5 bytes in Python 3 and then 3 more in Python 2. Thanks! \$\endgroup\$ Jul 23, 2017 at 3:01
3
\$\begingroup\$

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.

Haskell, 56 bytes

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!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Eek! You ninja'd me by 20 seconds! \$\endgroup\$
    – user45941
    Jul 23, 2017 at 3:33
3
\$\begingroup\$

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.

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

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 ]

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

C++, 93 85 83 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;}
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Your first one is valid i/o. \$\endgroup\$
    – Pavel
    Jul 23, 2017 at 22:56
  • 1
    \$\begingroup\$ You can use j%4 to save 2 bytes. \$\endgroup\$
    – Nevay
    Jul 23, 2017 at 23:34
  • 1
    \$\begingroup\$ I don't think you need parens around j%4. \$\endgroup\$
    – Adalynn
    Sep 4, 2017 at 16:37
2
\$\begingroup\$

Pari/GP, 30 bytes

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

Try it online!

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

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

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

Ruby, 38 bytes

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

Try it online!

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

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!

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

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.

+

To the current element add...

gE

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

[1TJT]

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

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

Perl 6, 28 22 bytes

{((1+0i,×i...)Z+$_)».re}

(*Z-(i*i,*i...*))».re

Try it online!

i*i, *i ... * produces an infinite list of the numbers -1, -i, 1, i repeateded in a cycle. Those numbers are zipped with subtraction (Z-) with the input list (*), and then the real components of the resulting complex numbers are extracted (».re).

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

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
\$\endgroup\$
1
\$\begingroup\$

Pyth, 11 bytes

.e+bss^.j)k

Try it online!

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

CJam, 15 bytes

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

Try it online!

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

Math.JS, 34 bytes

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

Explained

f(k)=k.map(j(x,y,z)=x+im(i^y[1]))
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[1]     # i to the power of the index.
                    x+              # x +, which gives our wave.

Try it Online!

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

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
;
\$\endgroup\$
1
\$\begingroup\$

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.

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

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.

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

Arturo, 33 bytes

$=>[i:0map&=>[&-((i%4)-1)%2'i+1]]

Try it

Port of ETHproductions' JavaScript answer.

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

Zsh, 34 bytes

for i;echo $[++j%2*(j%4>2?-1:1)+i]

Try it online!

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

Pyt, 9 bytes

ĐŁřπ*₂šƖ+

Try it online!

Đ            implicit input; Đuplicate
 Ł           get Łength
  ř          řangify
   π*₂       multiply by pi/2
      š      take šin
       Ɩ     cast to Ɩnteger
        +    add the two arrays element-wise
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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