Skip to main content
12 of 13
added 218 characters in body
primo
  • 33.5k
  • 5
  • 61
  • 139

Perl - 72 bytes

$~=<>=~$"+$'*2;$_=1-$_*$`/$~--/$~*$`for($,,$;)x$';printf'%f
%f',$`*$,,$;

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

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

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

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

but why would you.

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


Algorithm

Examining the Taylor series for sin(x):

http://chart.googleapis.com/chart?cht=tx&chf=bg,s,FFFFFF00&chl=%5Csin%28x%29%3Dx-%5Cfrac%7Bx%5E3%7D%7B3%21%7D%2B%5Cfrac%7Bx%5E5%7D%7B5%21%7D-%5Cfrac%7Bx%5E7%7D%7B7%21%7D%2B%5Cfrac%7Bx%5E9%7D%7B9%21%7D-%5Cfrac%7Bx%5E%7B11%7D%7D%7B11%21%7D%2B%5Cdots

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:

http://chart.googleapis.com/chart?cht=tx&chf=bg,s,FFFFFF00&chl=%5Csin%28x%29%3Dx%281-%5Cfrac%7Bx%5E2%7D%7B2%5Ccdot+3%7D%281-%5Cfrac%7Bx%5E2%7D%7B4%5Ccdot+5%7D%281-%5Cfrac%7Bx%5E2%7D%7B6%5Ccdot+7%7D%281-%5Cfrac%7Bx%5E2%7D%7B8%5Ccdot+9%7D%281-%5Cfrac%7Bx%5E2%7D%7B10%5Ccdot+11%7D%281-%5Cdots%29%29%29%29%29%29

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:

http://chart.googleapis.com/chart?cht=tx&chf=bg,s,FFFFFF00&chl=s_n%3D1-%5Cfrac%7Bs_%7Bn%2B1%7D%5Ccdot+x%5E2%7D%7B%282n%29%5Ccdot%282n%2B1%29%7D

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


Ungolfed

<> =~ 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
10.208333
14.541667

$ echo 8.555 13 | perl sin-cos.pl
0.765431
-0.641092

$ echo 9.26 10 | perl sin-cos.pl
-3.154677
-8.404354

$ echo 6.54 12 | perl sin-cos.pl
0.253986
0.967147

$ echo 5 1 | perl sin-cos.pl
5.000000
1.000000

$ echo 20 20 | perl sin-cos.pl
-5364.411846
-10898.499385

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.

primo
  • 33.5k
  • 5
  • 61
  • 139