Find i^n, given n

The Challenge

In as few characters as possible, find the value of $$\i^n\$$, given $$\n\$$, a positive integer greater than 0. This should be outputted as a String.

For those that don't know, $$\i\$$ is defined such that $$\i^2=-1\$$. So:

• $$\i^1=i\$$
• $$\i^2=-1\$$
• $$\i^3=-i\$$
• $$\i^4=1\$$

This then repeats..

Rules

• If your language supports complex numbers, don't use any functions or arithmetic that could work this out.
• Floating point inaccuracies are fine for answers that would return decimals anyway, but integer inputs should give exact results

Bonus Points

-5 if you can work the value out where n is also negative

-15 if you can work out the value for any real number (this bonus includes the -5 from the above bonus)

Good luck!

• In what format do we return exactly? Through function output or stdout? Nov 21 '14 at 15:59
• @MartinBüttner but if i choose function output, how should the output should be formatted/stored without native complex numbers in my language? Nov 21 '14 at 16:02
• @BetaDecay What are floating point integers? o.O Nov 21 '14 at 18:04
• @MartinBüttner Haha wrong word :/ Floating point number then Nov 21 '14 at 18:17
• I feel so stupid. I only just realized that python has a built in complex type. Nov 22 '14 at 6:03

Perl 6, 19 bytes - 5 = 14

{<1 i -1 -i>[$_%4]}  The result of % has the same sign as the divisor in this language. Try it online! C (gcc), 30 bytes f(x){printf(L"iㄭ椭1"+x%4);}  Try it online! C (gcc), 44 bytes -15=29 #define f(x)cos(x*acos(0))+1i*sin(x*acos(0))  Try it online! Handles signed and noninteger arguments. R, (29 bytes -15) = 14 cos(m<-scan()*pi/2)+sin(m)*1i  Try it online! Conventional complex number output; works for negative and real inputs. (for completeness, there is also c(1,scan()*90) for a score of -1, using blutorange's dubious inventive polar output format in degrees) • Based on "(this bonus includes the -5 from the above bonus)", I don't think you can include both the -5 and -15 bonuses Oct 30 '20 at 15:32 • @EthanChapman Ah, yes, you're right. Fixed. I was wondering why nobody else had such a good bonus... Oct 30 '20 at 15:33 Haskell, 29 bytes - 5 = 24 f n=words"1 i -1 -i"!!mod n 4  Works for negative powers. I had a pointfree version worked out, but it turns out it's actually longer. f=(words"1 i -1 -i"!!).(mod4)  Clojure (6454 31 chars) (defn i2n[n](println(case(mod n 4) 1 "i" 2 "-1" 3 "-i" 0 "1")))  Edit Per @SeanAllred's suggestion, here's a version which uses a literal vector instead of a case function: (defn i2n[n](println (["1" "i" "-1" "-i"] (mod n 4))))  Edit 2 By counting on the REPL to print out the resultant collection and coding the function using the #() shortcut we can reduce it to #(["1" "i" "-1" "-i"](mod % 4))  (Which is actually much more Clojure/Lisp-ish as the function now actually returns the generated result, allowing the function to be used with map, as in (map #(["1" "i" "-1" "-i"](mod % 4)) [0 1 2 3 4 5 6 7 8])  which prints ("1" "i" "-1" "-i" "1" "i" "-1" "-i" "1")  Share and enjoy. • Instead of using a select structure, can't you use some sort of explicit array as in my answer? Nov 24 '14 at 1:22 Groovy: 27-5 = 22 f={n->[1,'i',-1,'-i'][n%4]}  C 105, was 117 char c[2]; int main() { int n,i,j=0;scanf("%d",&n);i=n%4; i>1?c[j++]='-':c[j+1]='\0'; c[j]=i&1?'i':'1'; puts(c); }  • It doesn't even compile because you must parenthesize the assignments after : in ?: statements in plain C. Also, what's the point of using 0==0 when you can use single char 1? And no need in parentheses before ?. Also, the last ?: statement could be shortened to c[j]=i&1?'i':'1';. Nov 23 '14 at 14:20 • @Ruslan In CodeBlocks Mingw there is only 1 warning around i&0. i&0==0 is a test for even, if i is even the result is 0 else it is 1. Nov 25 '14 at 6:13 • Yeah, but what's the point of using 0==0 when it's identical to 1? Note that == has higher precedence than &, otherwise your (supposed) test of (i&0)==0 would always be true. Nov 25 '14 at 6:18 PARI/GP, 26 - 5 = 21 n->Str([1,I,-1,-I][n%4+1])  n->cos(t=Pi*n/2)+I*sin(t) is one character shorter, but doesn't handle exact answers. Of course n->I^n is disallowed, and presumably also PARI's powIs. Java (OpenJDK 8), 39 bytes n->new String[]{"1","i","-1","-i"}[n%4]  Try it online! Haskell, 27 bytes (cycle(words"1 i -1 -i")!!)  Try it online! 05AB1E, 12 bytes ®sfgm¹Éi1'i:  Try it online! ® # Push -1 onto the stack. sfg # Push the number of prime factors of input. m # -1^(number_prime_factors) ¹Éi # is input even? 1'i: # if input was even, replace 1 with i.  Forth (gforth), 53 bytes - 5 bytes (bonus) = 48 bytes : f 4 mod dup 1 > if ." -"then 2 mod 56 * '1 + emit ;  Try it online! This works for both positive and negative numbers Code Explanation : f \ start a new word definition 4 mod dup \ get result of n % 4 (and make a copy) 1 > if \ if result is 2 or 3 ." -' \ print a minus sign then \ end the if 2 mod 56 * \ get result modulo 2 and multiply by 56 (difference between ascii for '1' and 'i') '1 + \ add to ascii value of '1' emit \ output the character for the given value ; \ end the word definition  Zsh, 30 bytes, score 25 (-5) a=({,}{,-}{1,i}) <<<$a[$1%4+5]  Try it online! Based on the bash answer, but with some changes needed: • %4 results in a value in the range -3 to 3 (negative inputs give negative outputs), so we shift up with +5. • Arrays are 1-indexed, hence +5 instead of +4. • We make our array twice as long by using brace expansion: {,}foo expands to foo foo. Tcl, 50 bytes proc I n {expr$n%4==3?"-i":$n%4==2?-1:$n%4?"i":1}


Try it online!

• Input is in A1
• B1: A1/2*PI(
• Result: =COMPLEX(COS(B1),SIN(B1

Stax, 9 - 5 = 4 bytes

ü▲τ}εT├?á


Run and debug it

Rust34 33 bytes

fn main() {
// closure:
// |n:usize|["1","i","-1","-i"][n%4]

// call with:
print!("{}", (|n:usize|["1","i","-1","-i"][n%4])(3));
}


Try it online!

The closure itself:

|n:usize|["1","i","-1","-i"][n%4]

• You should probably put a version without comments and whitespace here as well, so it's easier to see what the actual 34 byte program is. Apr 7 at 20:51

C# 69-5 = 64

public string m(int n){return n%2==0?(n%4==0?"1":"-1"):(m(n-1)+"i");}

• output is in form -1i, 1i, i, or 1 Nov 23 '14 at 23:38
• You cannot claim the -15 bonus as this would fail on the input 3.247104. You may only claim the -5 bonus. Nov 24 '14 at 7:06
• Oh, sorry, yes - I didn't read the bonuses bit properly Nov 27 '14 at 3:34

Ruby, 208 - 15 = 193

p=Math::PI/2;t=gets.to_f*p;l=->n{Math::cos(n).round(2)};k=l.call(t);if k!=0;k=k.to_i if k.abs==1;print k;end;m=l.call(t+p);if m!=0;r="i";r='-'+r if m==-1;r="#{m}"+r if 1>m && -1<m;r=" + "+r if k!=0;puts r end


This implementation completely conforms to the spec! 1.0 is written as 1, -1.0i is written as -i, etc. I don't see any other solution that incorporates this along with supporting floating points, except for maybe the TI-Calculator.

Ungolfed:

p=Math::PI/2
t=gets.to_f*p
l=->n{Math::cos(n).round(2)}

k=l.call(t)
if k!=0
k=k.to_i if k.abs==1
print k
end

m=l.call(t+p)
if m!=0
r="i"
r='-'+r if m==-1
r="#{m}"+r if 1>m && -1<m
r=" + "+r if k!=0
puts r
end

• l.call(t)l[t]. Read Tips for golfing in Ruby for more. Dec 4 '15 at 6:43

C, 61

main(n){scanf("%d",&n);printf("%c%c",n%4/2*45,n%4%2?'i':49);}


Try it here.

Keg, 15 - 5 = 10 bytes

1i0;-i¿4%⊙&ø&


Try it online!

Pushes the four different possibilities and then takes the input modulo 4 and indexes the stack.

• You program supports negative numbers, you should have the -5 bonus! -5 if you can work the value out where n is also negative
– user85052
Nov 16 '19 at 6:09

Vyxal, r, 5 - 15 = -10 bytes

90*1"


Try it Online!

Well if the Ruby answer's output method is valid, so is this. Outputs in "polar form (angular unit: degrees)".

Explained

90*1"
90*   # Multiply the input by 90
1" # Push one and pair the two inputs. The -r flag makes dyads take their arguments in reverse.


Branch, 38 bytes

^\4^%/;c1^>/0c45^?[.0]anc2^%/49c105^?.


Try it on the online Branch interpreter!

Explanation

      Implicit - the initial node's value is set to the first argument
^\4   Create a parent and sibling and set the right child to 4
%     Modulo
/;    Go to the left child and copy the mod result
c1    Go to the right child (automatically assigned register C) and set it to 1
>     1 if the mod result is greater than 1, 0 otherwise
/0    Go to the left child and set to 0
c45   Go to the right child and set it to 45 (codepoint for "-")