Take the 2-minute tour ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.


The sine of x is given by the formula:

sin(x) = x - x^3/3! + x^5/5! - x^7/7! + x^9/9! - x^11/11! // and more follows...

The cosine of x is given by the formula:

cos(x) = 1 - x^2/2! + x^4/4! - x^6/6! + x^8/8! - x^10/10! // and more follows...


Given the value of x and n, write a program (no functions, etc.) to output the value of sin(x) and cos(x) correct upto n terms of the formula above. Assume that x is in radians.


x n

A decimal number x (with upto 3 decimal places) and an integer n. Input must be on stdin or a prompt dialog box (iff your language doesn't support stdin)



The value of both sin(x) and cos(x) should be rounded to 6 decimal places. If sin(x) is 0.5588558855 (10 decimal digits), it should be rounded to 0.558856 (6 decimal digits). The rounding must take place to the nearest, as described in the fifth column, "Round to nearest", of the the table in this Wiki article.


1 <= x <= 20
1 <= n <= 20


5 3

8.555 13

9.26 10

6.54 12

5 1

20 20



  1. Standard loopholes are prohibited.
  2. Built-in math functions and operators of trigonometry (sin, cos, tan, etc.), factorial, and exponentiation cannot be used. You are free to use a built-in rounding function for estimating the result of computing sin(x) and cos(x) to the 6-th decimal digit.
  3. No need to handle wrong inputs.
  4. Only ASCII characters can be used in the program, not the Chinese Unicode ones that allow code compression.
  5. Your program must terminate, and display the output, within 3 seconds of input.
  6. Your answer must accompany the ungolfed code, along with the explanation of the code (compulsory if the code is not immediately obvious to programmers-not-familiar-with-your-language, especially GolfScript, J, etc.).
  7. Please include a link to an online compiler where your program can be tested.


The answer with lowest code length in characters, including white space, tabs, etc. wins! Winner would be declared on 21 May 2014.

EDIT: 21/05/14 Winner is aditsu using CJam language. Runner up follows jpjacobs with J language, and second runner up is primo with Perl language. Congrats all!

share|improve this question
(Mod note: comments nuked. Please ping me for any lost information that you might want; looks like after my warning in advance, everything made its way into the question though.) –  Doorknob May 15 '14 at 15:00
In the first paragraph, it should be "sine", not "sin" –  Not that Charles May 15 '14 at 18:03
Is "Round to nearest" still a requirement, or can we use any built-in rounding facilities? e.g. round towards zero? –  DigitalTrauma May 15 '14 at 18:04
Requiring the equivalent of a mod 2pi operation to make the inputs converge faster would be rather useful - it's one of many improvements that the real world uses when dealing with these functions. (actually mod pi and sign awareness). –  Floris May 16 '14 at 1:21
@Floris I never knew this. Well, we can't do anything now, the rules have already changed much, and I don't want to keep changing them to further annoy the answerers. Thanks for the suggestion though! –  Gaurang Tandon May 16 '14 at 3:57

16 Answers 16

up vote 5 down vote accepted

CJam - 42


Try it online at http://cjam.aditsu.net


r reads a token from the input
d converts to double
:X assigns to the variable X
; pops the value from the stack
1 puts 1 on the stack (the first term)
_ duplicates the 1
r reads the next token (the n)
i converts to integer
2*,1>{...}/ is a kind of loop from 1 to 2*n - 1:
- 2* multiplies by 2
- , makes an array from 0 to (last value)-1
- 1> removes the first item of the array (0)
- {...}/ executes the block for each item in the array
_ duplicates the "loop variable" (let's call it k)
2%2*( converts from even/odd to -1/1:
- 2% is modulo 2 (-> 0/1)
- 2* multiplies by 2 (-> 0/2)
- ( decrements (-> -1/1)
* multiplies, thus changing the sign every second time
/ divides the term on the stack by k or -k; this is the "/k!" part of the calculation together with the sign change
X* multiplies by X; this is the "X^k" part of the calculation; we obtained the next term in the series
_ duplicates the term to be used for calculating the following term in the next iteration
; (after the loop) pops the last duplicated term
] collects the terms on the stack in an array
At this point we have an array [1 X -X^2/2! -X^3/3! X^4/4! X^5/5! ...] containing exactly all the terms we need for cos(x) and sin(x), interleaved
2/ splits this array into pairs
z transposes the matrix, resulting in the array with the terms for cos(x) and the array with the terms for sin(x), as "matrix rows"
{...}/ again executes the block for each array item (matrix row):
- :+ adds the elements of the matrix row together
- 6mO rounds to 6 decimals
At this point we have the desired cos(x) and sin(x) on the stack
p prints the representation of the last item on the stack (sin(x)) followed by a newline
At the end of the program, the remaining contents of the stack (cos(x)) are printed automatically.

share|improve this answer
+1 for introducing me to a language I've never heard of and will probably never use. –  Alex May 15 '14 at 14:41
@Alex thanks, CJam is somewhat like GolfScript on steroids –  aditsu May 15 '14 at 15:00
I don't like changing rules after posting the question, but I have disallowed code-compression-allowing-Unicode characters, as I did not know Unicode characters could be used to compress code. Only ASCII characters can be used now. Please edit your post. Sorry for inconvenience. –  Gaurang Tandon May 15 '14 at 17:46
@GaurangTandon I don't like that very much either. What else did you think Chinese characters could possibly be used for in this problem? Anyway, edited. –  aditsu May 15 '14 at 23:31

Perl - 72 bytes


Or, counting command line options as 1 byte each, in 70 bytes:

#!perl -n
$-=/ /+$'*2;$_=1-$_*$`/$---/$-*$`for($,,$;)x$';printf'%f

Or, if you'll allow me Perl 5.8, in 63 bytes:

#!perl -p
$.+=$'<</ /;$_=1-$_*$`/$.--/$.*$`for($_=$#='%f

but why would you.

Edit: Compliance with the new rules. %f rounds to 6 places by default, how convenient!


Examining the Taylor series for sin(x):

it can be seen that each term evenly divides every successive term. Because of this, it can be transformed rather effortlessly into a nested expression:

cos(x) transforms similarly, without the leading x, and denominator terms one smaller.

Additionally, this nested expression can be reformulated as a reverse recursive expression:

with s = 0 and sin(x) = x·s1, which is ultimately what is used.


<> =~ m/ /;          # read one line from stdin, match a space
                     # prematch ($`) is now x, postmatch ($') is now n
($x, $n) = ($`, $'); # reassign, for clarity
$i = 2*$n + 1;       # counting variable (denominators)

for (($s, $c)x$n) {  # iterate over $s and $c, n times each
  # compute the next term of the recursive expression
  # note: inside this loop $_ is not the _value_
  # of $s and $c alternately, it _is_ $s and $c

  $_ = 1 - $_ * $x**2 / $i-- / $i;

# formated output
printf("%f\n%f", $x*$s, $c);

Sample Usage

$ echo 5 3 | perl sin-cos.pl

$ echo 8.555 13 | perl sin-cos.pl

$ echo 9.26 10 | perl sin-cos.pl

$ echo 6.54 12 | perl sin-cos.pl

$ echo 5 1 | perl sin-cos.pl

$ echo 20 20 | perl sin-cos.pl

If you want to test this online, I recommend using compileonline.com. Copy-Paste the code into main.pl, and the input into the STDIN box, then Execute Script.

share|improve this answer
What a devious way to parse the input... can I use that in my solution? :) –  Tal May 14 '14 at 12:22
@Tal Feel free. –  primo May 14 '14 at 12:25
I think perl (and especially your code) counts as "not immediately obvious to programmers-not-familiar-with-your-language" –  aditsu May 15 '14 at 1:35
@aditsu Agreed. I'll add some cleaner code, and an explanation of the algorithm. –  primo May 15 '14 at 3:08
This answer really was extremely educational! –  Tal May 15 '14 at 20:04

Python 3 (102) / Python 2 (104)

Python 3 (102)

while k>1:k-=1;t=1+t*1j*x/k

Python 2.7 (104)

while k>1:k-=1;t=1+t*1j*x/k

Basically the same code. We save two characters from not needing parens for print but lose four from needing raw_input.

Sample run

You can run these here.

20 20

Code explanation

The main idea is to compute 2*n terms of e^(ix), and then take the imaginary and real part to get the sin and cos values approximated to n terms. We use the truncation of the Taylor series:

e^(ix)≈sum_{k=0}^{2n-1} (i*x)^k/k!

This is polynomial in i*x, but rather than compute its value by summing each term, we use a modified Horner's Method to compute the sequence (defined recursively in reverse)

t_{2n} = 1
t_k = 1 + t_{k+1}*i*x/k,

which gives t_1 equaling the desired value.

Python string formatting operations are used to get the values to display rounded up to 6 decimal digits.

Edit: Changed to round to 6 digits as per new rules. No other changes were needed.

share|improve this answer
Try ideone for an online py3 interpreter :) –  British Colour May 14 '14 at 7:05
@BritishColour Thanks! I've added it to the post. –  xnor May 14 '14 at 7:09
Please update your answer. See details in question. Thanks. –  Gaurang Tandon May 16 '14 at 14:56

J 98 70 69 58

Though this can probably be shortened quite a bit using more fancy functions ... comments are welcome:

exit echo 0j6":,.-/(($%&(*/)1+i.@[)"0~i.@,&_2)/".}:stdin''

note 2: input ends when receiving EOF (ctrl-D in linux). Edit: join exponentiation and factorial into a nicer, more J-ish whole: ($ %&(*/) >:@i.@[ ). This boils down to take an array of x replications of y and an array of the numbers from 1 to y. Multiply each and divide the result. This gets rid of the duplicate */.

Thanks to algortihmshark, another 7 characters off.

Eliminated cut for getting rid of the trailing newline.

Longer version, for which knowing about forks is a must.

NB. recursive Factorial
f=: */@>:@i.      NB. multiply all from 1 to n
NB. Exponential
e=: */@$          NB. replicate y x times, take the product.
NB. the x t y is the Nth (general) term without sign of the joint series
t=: (e % f@[)"0  NB. pretty straight forward: divide by (x!) on the exponential

NB. Piece the parts together, from right to left:
NB. read from stdin, cut the linefeed off , make the 2 n terms in 2 columns, which
NB. effectively splits out pair and odd terms, put in the minuses, put in rows
NB. instead of columns, echo, exit
exit echo 0j6&": ,. (-/) (i.@(,&_2)@{: t {.) , (". ;. _2) stdin''

There is no online J interpreter, but it's open source since a few years; installation is easy with these instructions:


On #jsoftware on irc.freenode.org, there is a J bot too.

stdin works only when ran from a file, from the commandline, else replace stdin '' with 'a b;' where a and b are the numbers that would have been passed on the commandline.

share|improve this answer
I love that it starts with exit –  DigitalTrauma May 15 '14 at 4:09
Please update your answer. See details in question. Thanks. –  Gaurang Tandon May 16 '14 at 14:57
Updated for the 6 decimal places. If there's something else, please specify. Thanks –  jpjacobs May 19 '14 at 20:49
You can remove the & from 0j6&": to save a char. Also, (i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.) can be rewritten (($%&(*/)1+i.@[)"0~i.@,&_2)/ for another 6. –  algorithmshark May 19 '14 at 21:29

Perl, 120 108 104 89 85

<>=~/ /;$c=$t=1;for(1..2*$'-1){$t*=$`/$_;$_%2?$s:$c+=$_&2?-$t:$t}printf"%f\n"x2,$s,$c


<> =~ / /;
$cosine = $t = 1;
for (1.. 2*$' - 1){
  $t *= $` / $_;
  ($_%2 ? $sine : $cosine) += $_&2?-$t:$t
printf "%.6f\n" x2, $sine, $cosine

The first line reads the input and uses regex to find a space; this automatically puts the value before the space in $` and the value after it in $'.

Now we loop from 1 to 2*n-1. $t is our term, which the loop repeatedly multiplies by x and divides by the loop's index ($_). The loop starts at 1 rather than 0 because the cosine is initialized to 1, which saved me having to deal with dividing by zero.

After updating $t, the trinary operator returns either $sine or $cosine, depending on whether the index is odd or even, and adds $t's value to it. The magic formula $_&2?-$t:$t figures whether to add or subtract this value (basically using a bitwise-and on the index and 2 to generate the repeating sequence of "add, add, subtract, subtract").

You can test-run this code at compileonline.com.

share|improve this answer
Please correct your output for 20 20. –  Gaurang Tandon May 15 '14 at 6:32
I think your for loop may need to go from 1..$n*2-1, instead of 1..$n. While I'm here... $s is perfectly fine left uninitialized, as undef evaluates to 0 in a numeric context. Ternary assignment doesn't need parentheses: $_&1?$s:$c+=$t. "%.8f\n%.8f" can be shortened to "%.8f\n"x2, at the consequence of adding a trailing newline. –  primo May 15 '14 at 9:15
@Primo Thanks, I didn't know about some of those. And now it even produces the correct result as well. –  Tal May 15 '14 at 10:38
@Tal My pleasure. Also, slightly better magic: $t*(1-($_&2)) => $_&2?-$t:$t. –  primo May 15 '14 at 10:53
Please update your answer. See details in question. Thanks. –  Gaurang Tandon May 16 '14 at 14:56

Fortran: 89 109 125 102 101 98 bytes

complex*16::t=1;read*,x,n;do k=2*n-1,1,-1;t=1+t*(0,1)*x/k;enddo;print'(f0.6)',aimag(t),real(t);end

I abuse implicit typing, but unfortunately no such implicit complex type exists, so I had to specify that & the complex i. Gfortran cuts output at 8 decimal places naturally, so we're good on that spec. Unfortunately, my original method of output, print*,t, did not meet specs so I had to add 16 characters to output the imaginary and real components & hit the required 8 decimal places.

Thanks to Ventero, I managed to save 23 bytes between output and the loop. And another character to get correct answers and formatted output. And 3 more on the read statement.


do k=2*n-1,1,-1
share|improve this answer
Please update your answer. See details in question. Thanks! –  Gaurang Tandon May 16 '14 at 14:57
@GaurangTandon: You probably should stop changing the details of the problem. –  Kyle Kanos May 16 '14 at 15:01
I know, and I don't want to, but I can't help it. Actually, after testing 5 answers, it turned out that almost all of them were giving different results (this was indeed completely unsuspected). I could have followed some other approach, but that would have requried the complete change of the algorithms of the current answers. This one is the best I could figure out. –  Gaurang Tandon May 16 '14 at 15:03
Well I know that mine works perfectly, so I should totally get the check :D ;) –  Kyle Kanos May 16 '14 at 15:05

C, 120

double s,c,r,x;main(i,n){for(scanf("%lf %d",&x,&n),r=1;i<n*2;s+=r,r*=-x/i++)c+=r,r*=x/i++;printf("%.8lf\n%.8lf\n",s,c);}

To save a byte, the statements that update the sine value are placed inside the for() statement, but are actually executed after the statements following the closing parenthesis that update the cosine value. (I guess I could also save a couple more bytes by removing the final newline character in the program's output.)

The global variables s, c, r and x are implicitly initialized to zero, and i will have a value of 1 as long as there are no arguments provided on the command line. Unfortunately printf() defaults to 6 places of decimals, so the output format is a bit verbose.


Here's the code with a bit of rearrangement to make the order in which things are done a bit clearer:

double s,c,r,x;
main(i,n) {
    scanf("%lf %d",&x,&n);
    for(;i<n*2;) {

Sample output:

$ echo 1.23 4 | ./sincos

Try it online:


share|improve this answer

Python >=2.7.3, 186 184 211 200 182 170 characters

Kinda simple as hell. Uses formula from the question parameterized for sine and cosine.

Online interpreter can be found here here

f=lambda n:n<2and 1or n*f(n-1.)
for i in[1,0]:print"%.6f"%sum((1-j%2*2)*reduce(lambda o,p:o*p,[x]*(i+2*j),1)/f(i+2*j)for j in range(n))

Edit: Valid version with all the restrictions

Edit2: Changed online interpreter to ideone.com because of invalid round function output in Python 2.7.1

Edit3: Turned out that I used unnecessary inline lambda + changed rounding to string format (stolen from xnor :) )

Edit4: Replaced join with not functional main for loop

share|improve this answer
Hello avail, I have recently edited the rules which now do not allow the built-in operators for exponentiation (that is what the ** is doing I suppose). So, I think you will have to edit your answer. Sorry for inconvenience. Please correct me if I am wrong. –  Gaurang Tandon May 14 '14 at 6:37
I guess further modifications are useless with xnor's answer :) –  avall May 14 '14 at 7:51
@avail On 20 20, I get output -5364.4118142500001. Might want to fix it to 8 decimals. –  Gaurang Tandon May 15 '14 at 6:31
It is because of repl.it Python version 2.7.1. If you run it on ideone.com (Python 2.7.3) it works properly. ideone.com/JsYNNK –  avall May 15 '14 at 7:49
It works nice now! +1 –  Gaurang Tandon May 15 '14 at 12:22

JavaScript - 114 chars

y=(z=prompt)().split(' ');for(x=l=s=+y[0],c=d=1;--y[1];c+=l*=-x/++d,s+=l*=x/++d);z(s.toFixed(6)+'\n'+c.toFixed(6))

Based on james' great answer. Same algorithm, first step avoided with initialization of c=1 and s=x. Using 2 vars instead of an array for output simplifies the loop.


y = ( z = prompt)().split(' ');
for ( 
    x = l = s = +y[0], /* init to value x, note the plus sign to convert from string to number */
    c = d = 1;
    --y[1]; /* No loop variable, just decrement counter */
    c += (l *= -x / ++d), /* Change sign of multiplier on each loop */
    s += (l *= x / ++d) 
); /* for body is empty */
z(s.toFixed(6) + '\n' + c.toFixed(6))     
share|improve this answer
Minor typo: It would be s += (l *= x / ++d) and not s += (l* = x / ++d) in the ungolfed code. –  Gaurang Tandon May 15 '14 at 12:50
@GaurangTandon fixed –  edc65 May 15 '14 at 13:07

JavaScript (ECMAScript 6 Draft) - 97 96 Characters

A recursive solution:



["0.29550000", "0.95500000"]

["0.29552021", "0.95533649"]
share|improve this answer
That doesn't meet the spec regarding rounding though. –  Martin Büttner May 14 '14 at 18:31
@m.buettner fixed –  MT0 May 14 '14 at 19:07
It doesn't meet input format and no functions requirement. –  avall May 15 '14 at 6:11
Please update your answer. See details in question. Thanks. –  Gaurang Tandon May 16 '14 at 15:08


Insufficient reputation to comment, but further to Squeamish Offisrage's C answer, 7 byte reduction by using float for double and removing spaces, and combining declaration and init of 'r' gives

float s,c,r=1,x;main(i,n){for(scanf("%f%d",&x,&n);i<n*2;s+=r,r*=-x/i++)c+=r,r*=x/i++;printf("%.8f\n%.8f\n",s,c);}

try here.

share|improve this answer
Welcome to programming puzzles and code golf. Well done for acknowledging that your answer is a minor improvement on @squeamishossifrage's (I still managed to spell it wrong in my edit.) Best not to refer to the answer "above" because the order changes every time there is an edit. BTW, I noticed the initialization of r in the declaration. I haven't tested to see if float gives the required precision. –  steveverrill May 15 '14 at 12:36
@steveverrill Neither did I think float would give the required precision, but it does work :) And welcome to PPCG, user2702245 ! –  Gaurang Tandon May 15 '14 at 12:54
Is it just me thats getting the wrong answers with float variables then? For x=5 and n=3, I get sin(x)=10.20833206 and cos(x)=14.54166412 :-( (Intel Core Duo, in case you were wondering) –  squeamish ossifrage May 15 '14 at 14:26
Would you like me to convert this to a comment on said answer? –  Doorknob May 15 '14 at 18:19
@Doorknob May as well leave it now :-) –  squeamish ossifrage May 15 '14 at 18:51

GNU bc, driven by bash, 128 bytes

Far too many bytes spent setting decimal places and to-nearest rounding. Oh well, here it is anyway:

bc -l<<<"m=1000000


$ ./trig.sh 5 3
$ ./trig.sh 8.555 13
$ ./trig.sh 9.26 10
$ ./trig.sh 6.54 12
$ ./trig.sh 5 1
$ ./trig.sh 20 20

Linux command-line tools, 97 unicode characters

Unicode hack answer removed at OP's request. Look at the edit history if you interested.

share|improve this answer
I don't like changing rules after posting the question, but I have disallowed code-compression-allowing-Unicode characters, as I did not know Unicode characters could be used to compress code. Only ASCII characters can be used now. Please edit your post. Sorry for inconvenience –  Gaurang Tandon May 15 '14 at 17:47
@GaurangTandon Its not really compression - the unicode version actually takes more bytes (but less characters). But I agree with your sentiment - I actually prefer scoring to strictly be done using byte count, but couldn't resist the bit about Chinese characters in your OP. –  DigitalTrauma May 15 '14 at 17:50
You use illegal exponential operator –  avall May 15 '14 at 21:27
@avall Oops. That cost me 4 bytes. –  DigitalTrauma May 15 '14 at 21:32

Ruby, 336

Probably the longest one here, but I'm sure it could be made shorter :(

def f(n)
n==0 ? 1: 1.upto(n).inject(:*)
def p(x,y)
return 1 if y==0 
y.times {i *= x}
def s(x,n)
a = 0.0
for k in 0...n
a += p(-1,k) * p(x.to_f, 1+2*k)/f(1+2*k)
def c(x,n)
a= 0.0
for k in 0...n
a +=p(-1,k) * p(x.to_f, 2*k)/f(2*k)
x = gets.chomp
n = gets.chomp.to_i
puts s(x,n), c(x,n)
share|improve this answer

JavaScript (ES6) - 185 chars

i=(h,n)=>n?h*i(h,n-1):1;q=x=>x?x*q(x-1):1;p=(a,j,n)=>{for(c=b=0,e=1;c++<n;j+=2,e=-e)b+=e*i(a,j)/q(j);return b.toFixed(6)}
_=(y=prompt)().split(" ");y(p(_[0],1,_[1])+"\n"+p(_[0],0,_[1]))

Uses a function q for factorial, i for exponentiation, and p for performing both sin and cos. Run at jsbin.com. Uses exactly the formula without any modification.

EDIT: Changed 8 decimal places to 6 decimal places. 15/May/14

Ungolfed Code:

/*Note that `name=args=>function_body` is the same as `function name(args){function_body} */

// factorial
function fact(x) {
    return x > 1 ? x * fact(x - 1) : 1

// Exponentiation
function expo(number, power){
    return power > 0 ? number * expo(number, power - 1) : 1;

function sin_and_cos(number, starter, terms) {
    for (count = sum = 0, negater = 1;
            count++ < terms;
            starter += 2, negater = -negater) 

        sum += (negater * expo(number, starter)) / fact(starter);

    // to 6-decimal places
    return sum.toFixed(6);

input = (out = prompt)().split(" ");

out(sin_and_cos(input[0], 1,input[1]) 
        + "\n" +                
        sin_and_cos(input[0], 0, input[1]));
share|improve this answer

JavaScript - 133 chars

y=(z=prompt)().split(" "),s=[0,0],l=1;for(i=0;i<y[1]*2;i++){s[i%2]+=i%4>1?-1*l:l;l*=y[0]/(i+1)}z(s[1].toFixed(6));z(s[0].toFixed(6));


var y = prompt().split(" ");

var out = [0,0]; // out[1] is sin(x), out[0] is cos(x)
var l = 1; // keep track of last term in series
for (var i=0; i < y[1] * 2; i++) {
    out[i % 2] += (i % 4 > 1) ? -1 * l : l;
    l *= y[0] / (i + 1);

share|improve this answer
Input has to be two space-separated integers, not in two different dialog boxes. Please fix that. –  Gaurang Tandon May 15 '14 at 6:35
@GaurangTandon fixed - thanks for pointing it out –  James May 15 '14 at 14:55

Mathematica, 96 chars

share|improve this answer
How is the input format, seems x,n to me ? –  Gaurang Tandon May 16 '14 at 3:58
@GaurangTandon It is x n. –  alephalpha May 16 '14 at 14:27
Ok, thanks for clarifying. –  Gaurang Tandon May 16 '14 at 14:55

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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