Generate the list [1, 0, -1, 0, 1, 0, -1, 0, ...]

5

1

In the spirit of a question on math.se: given an integer n, return the integer in position n of the sequence [1, 0, -1, 0, 1, 0, -1, 0, ...]. Assume n >= 0.

Rules:

  1. You may only use the operations -x, x+y, x-y, x*y, x/y, and xy, whatever their representations are in the language you choose.
  2. Your function must be called a.
  3. Your function must run in constant time for all n.

Example:

a=lambda n:((-1)**(n*n-n)//2)+(-1)**(n*n+n)//2))//2

Non-example (uses list subscripting operation and modulo operator):

a=lambda n:[1,0,-1,0][n%4]

Non-example (uses cos operation):

from math import *;a=lambda n:int(cos(n*pi/2))

Non-example (does not run in constant time and uses if operation):

a=lambda n:-a(n-2) if n>1 else 0 if n>0 else 1

Clarifications: Both integer and float division are allowed. Your solution may return either an integer or a float (or complex number, I suppose, since some answers already used it). If your solution returns a float: your solution should, if it were to theoretically be carried out to infinite precision, give the exact answer.

Snowball

Posted 2012-04-15T13:07:30.693

Reputation: 167

Question was closed 2018-06-07T08:41:00.367

Is the allowed x/y any kind of division (including div) or always floating point division? — Certainly, "Your function must run in constant time for all n" is limited to some reasonable limit, no need to work for bigInts? – ceased to turn counterclockwis – 2012-04-15T15:05:30.403

What about conditionals, Boolean negation, etc? – Peter Taylor – 2012-04-15T22:07:53.167

Your example uses ** and // but you didn't allow them. a) What does ** and // mean, and why can you use them? – user unknown – 2012-04-15T23:25:54.740

@user unknown: Sorry I didn't make that clear. x**y is x to the yth power and x//y is integer division. – Snowball – 2012-04-16T00:05:10.637

@Peter Taylor: Conditionals, boolean negation, and such are not allowed. My real goal here was to translate that math problem I linked into a code golf problem. – Snowball – 2012-04-16T00:06:20.540

Um. Conditionals, Boolean algebra, etc. are perfectly cromulent mathematical objects. – Peter Taylor – 2012-04-16T07:54:01.043

@Peter Taylor: Of course they are, but the author of the other question on math.se asked for solutions that used only things you would find on a basic pocket calculator. I wanted to stay true to that restriction. – Snowball – 2012-04-16T19:29:02.490

In that case you should have disallowed exponentiation and complex numbers. Too late now, but next time you might want to post your question on the sandbox thread in meta to get a bit of feedback before people start answering.

– Peter Taylor – 2012-04-17T08:10:13.500

3How does the restriction on the name of the function work in languages where functions can't be named, or where a isn't a valid function name? – None – 2016-12-19T22:07:55.710

Also: It's impossible to solve this in constant time. Reading n takes time O(log n). VTC as unclear. – user202729 – 2018-06-07T02:07:14.243

@user202729 This is incorrect. You do not actually need to read the input, since the output is periodic (with period) you only need to read the last 2 bits. Hypothetically if your input is provided as a bit stream you can do this in constant time. However it does not look like any of the answers here actually do that. – Post Rock Garf Hunter – 2018-06-07T02:39:18.847

1@HatWizard in little endian. ... not a bad point. – user202729 – 2018-06-07T02:54:59.153

Answers

5

Ruby, 26 characters

a=->n{1-(k=n-n/4*4)+k/3*2}

Example:

> p (0..10).map{|n| a[n]}
[1, 0, -1, 0, 1, 0, -1, 0, 1, 0, -1]

Note: This solution assumes that integer division / is an allowed operation.

Howard

Posted 2012-04-15T13:07:30.693

Reputation: 23 109

1

I know it's been 6 years (lol..), but it can be golfed by 1 byte by reusing n instead of using a new variable k: a=->n{1-(n-=n/4*4)+n/3*2}. Try it online 25 bytes.

– Kevin Cruijssen – 2018-04-12T12:53:42.750

3

Python, 29 chars

a=lambda n:(1j**n+(-1j)**n)/2

Kind of cheating, but fun.

Edit:

Now that we can return complex numbers, this is competitive and no longer cheating (with Howard's suggestion).

Keith Randall

Posted 2012-04-15T13:07:30.693

Reputation: 19 865

I think that operator .real is not supported by the rules. You may use (j**n+(-j)**n)/2 instead. – Howard – 2012-04-16T04:04:58.917

1Should be 1j**-n. – lirtosiast – 2015-08-08T04:31:34.273

1j**-n instead of (-1j)**n saves 2 bytes. – Dennis – 2018-03-30T14:35:34.760

3

C, 36 chars

a(n){return(1-n+n/2*2)*(1-n+n/4*4);}

The same function used by Peter Taylor.

ugoren

Posted 2012-04-15T13:07:30.693

Reputation: 16 527

By using a(n){return(n-n/2*2)*(2-n+n/4*4);} you can shave off two characters. – Superbest – 2012-05-02T22:10:22.040

@Superbest, this gives the series shifted by one position. Close, but not it. – ugoren – 2012-05-03T07:49:40.293

According to http://codepad.org/sO0mFkhI output from your function is 0, -1, 0, 1, 0, -1, 0, 1, 0, .... Output from mine is 1, 0, -1, 0, 1, 0, -1, 0, 1. The original question gives the example output 1, 0, -1, 0, 1, 0, -1, 0, ....

– Superbest – 2012-05-03T09:57:00.823

@Superbest, you seem to start with n=1, I start with n=0. All examples (except the first, which gives a syntax error), give a(0)=1, like my answer. You can say your suggestion is valid, because it gives the same series starting from another position, but I'll stick with my version. – ugoren – 2012-05-03T13:00:36.617

Ah, that's right. I'm not sure why I thought the first one was 1 not 0. Sorry. – Superbest – 2012-05-03T13:14:52.917

C is best! thanks for algorithmic approach! – None – 2017-05-17T23:59:19.447

I know it's been almost six years (lol..), but you can golf it to a(n){return 1-(n-=n/4*4)+n/3*2;} by creating a port of Howard's answer. Try it online 32 bytes.

– Kevin Cruijssen – 2018-03-30T14:22:50.930

2

Python, 36 chars

a=lambda n:(-1)**(n/2)*(1+(-1)**n)/2

Keith Randall

Posted 2012-04-15T13:07:30.693

Reputation: 19 865

2

J, 18 characters

a=:[:{.[:+._1^2%~]

Works, but is probably cheating by the rules set out above.

Calculates -1 to the power of the given integer divided by 2 which gives 0j1 for any odd number. The {. and the +. return the real part so that the odd numbers give 0.

Usage:

   a 1
0
   a 6
_1

Edit: After feeling a bit smug about this I've just looked properly at Keith's answers and realized I've done essentially the same thing.

Gareth

Posted 2012-04-15T13:07:30.693

Reputation: 11 678

2

GolfScript (20 19 chars)

{.4/4*-.3/2*)\-}:a;

This is a port of Howard's solution.

If, in addition to division, the remainder operation were permitted, this could be improved substantially (by 6 5 chars):

{.2%(\4%(*}:b;

Mathematically that's

x => (x%2 - 1) (x%4 - 1)

I can't see any logic behind excluding remainder, since it's defined in terms of permitted operations.

Peter Taylor

Posted 2012-04-15T13:07:30.693

Reputation: 41 901

I think you should spend a semicolon after your code. Otherwise it interferes with the input to your program. – Howard – 2012-04-16T11:06:01.093

@Howard, I see your point. I think it's arguable, because the spec's badly worded, but on balance I think the leave-it-off position is weaker. – Peter Taylor – 2012-04-16T11:14:43.103

1

Python, 34 chars

Poor man's modulus... saves a whopping 2 chars over Keith Randall's solution. Take that! ;)

a=lambda n:(n-1-n/2*2)*(n-1-n/4*4)

edit: on reading others' solutions, this is the same as Peter Taylor's

boothby

Posted 2012-04-15T13:07:30.693

Reputation: 9 038

0

TI-Basic, 12 bytes

i^Ans+i^-Ans
Ans/2

Store in prgmA and run with 5:prgmA, with the input in place of 5.

TI-Basic implicitly returns the last evaluated value.

pizzapants184

Posted 2012-04-15T13:07:30.693

Reputation: 3 174

0

Python 2, 28 bytes

a=lambda n:(n/2*2-n+1)*1j**n

Try it online!

Proof of validity for those who don't know Python:

The expression is (n/2*2-n+1)*1j**n. If you add parentheses, it becomes ((((n/2)*2)-n)+1)*(1j**n). / is integer division, since both n and 2 are integers in this case, * is multiplication, - is subtraction, + is addition and ** is exponentiation.

Erik the Outgolfer

Posted 2012-04-15T13:07:30.693

Reputation: 38 134

0

Java 8, 21 bytes

n->1-(n-=n/4*4)+n/3*2

Port of @Howard's Ruby answer.

Try it online.

Kevin Cruijssen

Posted 2012-04-15T13:07:30.693

Reputation: 67 575

0

bc: 28 chars

echo 'a=4;(1-a+a/2*2)*(1-a+a/4*4)' | bc

user unknown

Posted 2012-04-15T13:07:30.693

Reputation: 4 210

0

Python, 49 chars

a=lambda n:(lambda x:(x**3-3*x*x-x+3)/3)(n-n/4*4)

Note: In Python3 you'll have to replace n/4 with n//4 at the end.

rubik

Posted 2012-04-15T13:07:30.693

Reputation: 222

0

8086 Assembler (14 bytes of machine code):

 ; ax holds the index into the sequence
 ; returns the sequence value in ax
 a: inc al
    shl al,6
    sar al,6
    cbw
    xor al,ah
    add al,ah
    cbw                     
    ret        

Skizz

Posted 2012-04-15T13:07:30.693

Reputation: 2 225

But in machine code, it isn't named a. The name's only used by the assembler and by the linker, so you'd have to count the length of the assembly code or the object code (unless the OP clarifies that it's ok for the function to be named 0 instead, which would be the closest analogue to the name of a function in machine code). – None – 2016-12-19T22:10:11.383