29
\$\begingroup\$

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!

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

54 Answers 54

1
2
2
\$\begingroup\$

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!

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

C (gcc), 30 bytes

f(x){printf(L"iㄭ椭1"+x%4);}

Try it online!

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

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.

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

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)

\$\endgroup\$
2
  • \$\begingroup\$ Based on "(this bonus includes the -5 from the above bonus)", I don't think you can include both the -5 and -15 bonuses \$\endgroup\$ Oct 30 '20 at 15:32
  • \$\begingroup\$ @EthanChapman Ah, yes, you're right. Fixed. I was wondering why nobody else had such a good bonus... \$\endgroup\$ Oct 30 '20 at 15:33
1
\$\begingroup\$

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"!!).(`mod`4)
\$\endgroup\$
1
\$\begingroup\$

Clojure (64 54 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.

\$\endgroup\$
1
  • \$\begingroup\$ Instead of using a select structure, can't you use some sort of explicit array as in my answer? \$\endgroup\$ Nov 24 '14 at 1:22
1
\$\begingroup\$

Groovy: 27-5 = 22

f={n->[1,'i',-1,'-i'][n%4]}
\$\endgroup\$
1
\$\begingroup\$

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);
}
\$\endgroup\$
3
  • \$\begingroup\$ 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';. \$\endgroup\$
    – Ruslan
    Nov 23 '14 at 14:20
  • \$\begingroup\$ @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. \$\endgroup\$ Nov 25 '14 at 6:13
  • \$\begingroup\$ 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. \$\endgroup\$
    – Ruslan
    Nov 25 '14 at 6:18
1
\$\begingroup\$

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.

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

Java (OpenJDK 8), 39 bytes

n->new String[]{"1","i","-1","-i"}[n%4]

Try it online!

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

Haskell, 27 bytes

(cycle(words"1 i -1 -i")!!)

Try it online!

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

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

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

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

Tcl, 50 bytes

proc I n {expr $n%4==3?"-i":$n%4==2?-1:$n%4?"i":1}

Try it online!

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

Google Sheets, 32-15=17

  • Input is in A1
  • B1: A1/2*PI(
  • Result: =COMPLEX(COS(B1),SIN(B1
\$\endgroup\$
1
\$\begingroup\$

Stax, 9 - 5 = 4 bytes

ü▲τ}εT├?á

Run and debug it

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

Rust 34 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]
\$\endgroup\$
1
  • \$\begingroup\$ 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. \$\endgroup\$ Apr 7 at 20:51
0
\$\begingroup\$

C# 69-5 = 64

public string m(int n){return n%2==0?(n%4==0?"1":"-1"):(m(n-1)+"i");}
\$\endgroup\$
4
  • \$\begingroup\$ output is in form -1i, 1i, i, or 1 \$\endgroup\$ Nov 23 '14 at 23:38
  • 1
    \$\begingroup\$ You cannot claim the -15 bonus as this would fail on the input 3.247104. You may only claim the -5 bonus. \$\endgroup\$
    – Beta Decay
    Nov 24 '14 at 7:06
  • \$\begingroup\$ Oh, sorry, yes - I didn't read the bonuses bit properly \$\endgroup\$ Nov 27 '14 at 3:34
  • \$\begingroup\$ I have asked a question on meta about this answer: meta.codegolf.stackexchange.com/questions/4851/… \$\endgroup\$ Mar 5 '15 at 22:27
0
\$\begingroup\$

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

C, 61

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

Try it here.

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

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.

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

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

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
^     Return to the parent (the mod result)
>     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 "-")
^     Return to the parent
?     Conditional - if the mod was greater, go to the right child (45), and left child (0) otherwise
[  ]  While the value isn't 0
 .    Output it
  0   And set it to zero (this is basically an if statement)
an    Go to the left child and load the first argument (register N by default)
c2    Go to the right child and set it to 2
%     Modulo
/49   Go to the left child and set it to 49 (codepoint for "1")
c105  Go to the right child and set it to 105 (codepoint for "i")
^     Go to the parent
?     Conditional - if the exponent was even, go left, otherwise, go right
.     Output
\$\endgroup\$
1
2

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.