31
\$\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\$ Commented Nov 21, 2014 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\$ Commented Nov 21, 2014 at 16:02
  • 18
    \$\begingroup\$ @BetaDecay What are floating point integers? o.O \$\endgroup\$ Commented Nov 21, 2014 at 18:04
  • 2
    \$\begingroup\$ @MartinBüttner Haha wrong word :/ Floating point number then \$\endgroup\$
    – Beta Decay
    Commented Nov 21, 2014 at 18:17
  • 1
    \$\begingroup\$ I feel so stupid. I only just realized that python has a built in complex type. \$\endgroup\$
    – Justin
    Commented Nov 22, 2014 at 6:03

57 Answers 57

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\$ Commented Oct 30, 2020 at 15:32
  • \$\begingroup\$ @EthanChapman Ah, yes, you're right. Fixed. I was wondering why nobody else had such a good bonus... \$\endgroup\$ Commented Oct 30, 2020 at 15:33
2
\$\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\$
    – rydwolf
    Commented Apr 7, 2021 at 20:51
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\$ Commented Nov 24, 2014 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
    Commented Nov 23, 2014 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\$ Commented Nov 25, 2014 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
    Commented Nov 25, 2014 at 6:18
1
\$\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
1
\$\begingroup\$

C, 61

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

Try it here.

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

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

Lua, 33 - 5 = 28 bytes

print(({1,'i',-1,'-i'})[...%4+1])

Try it online!

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

Go, 75 57 bytes, no bonus

func(n int)string{return[]string{"1","i","-1","-i"}[n%4]}

Try it online!

if n<0{n=4+n} is included here because the % operator in Go returns negative if the dividend is negative.

\$\endgroup\$
2
  • \$\begingroup\$ At the moment, this qualifies for a -5 bonus (since it handles negative numbers too), so your score is 70 bytes. But, if you don't go for any bonuses, you can get this down to 58 bytes \$\endgroup\$
    – The Thonnu
    Commented Jul 8, 2023 at 18:15
  • \$\begingroup\$ You can also remove the redundant newline for 57 bytes \$\endgroup\$
    – The Thonnu
    Commented Jul 8, 2023 at 19:17
1
\$\begingroup\$

C# 63-5 = 58

public string m(int n)=>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\$ Commented Nov 23, 2014 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
    Commented Nov 24, 2014 at 7:06
  • \$\begingroup\$ Oh, sorry, yes - I didn't read the bonuses bit properly \$\endgroup\$ Commented Nov 27, 2014 at 3:34
  • \$\begingroup\$ I have asked a question on meta about this answer: meta.codegolf.stackexchange.com/questions/4851/… \$\endgroup\$ Commented Mar 5, 2015 at 22:27
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
    Commented Nov 16, 2019 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\$

Thunno 2, 10 - 5 = 5 bytes

`-iu'i1K$i

Attempt This Online!

Port of Kevin Cruijssen's 05AB1E answer.

Explanation

`-iu'i1K$i  '# Implicit input
`-i          # Push the string "-i"
   u         # Push the number -1
    'i      '# Push the string "i"
      1      # Push the number 1
       K     # Wrap the stack into a list
             # -> [1, "i", -1, "-i"]
        $i   # Index the input in
             # (0-based, modular)
             # Implicit output
\$\endgroup\$
1
2

Your Answer

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

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