¡Que comience la trigonometría!


20

Introducción:

El seno de xestá dado por la fórmula:

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

El coseno de xviene dado por la fórmula:

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

Tarea:

Dado el valor de xy n, escriba un programa (sin funciones, etc.) para generar el valor sin(x)y cos(x)corregir hasta los ntérminos de la fórmula anterior. Supongamos que xestá en radianes.

Entrada:

x n

Un número decimal x(con hasta 3 lugares decimales) y un número entero n. La entrada debe estar en stdin o en un cuadro de diálogo (si su idioma no admite stdin)

Salida:

[sin(x)]
[cos(x)]

El valor de ambos sin(x)y cos(x)debe redondearse a 6 decimales. Si sin(x)es 0.5588558855(10 dígitos decimales), debe redondearse a 0.558856(6 dígitos decimales). El redondeo debe realizarse al más cercano, como se describe en la quinta columna, "Redondear al más cercano", de la tabla en este artículo de Wiki .

Restricciones:

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

Muestras:

----
5 3

10.208333
14.541667
----
8.555 13

0.765431
-0.641092
----
9.26 10

-3.154677
-8.404354
----
6.54 12

0.253986
0.967147
----
5 1

5.000000
1.000000
----
20 20

-5364.411846
-10898.499385
----

Notas:

  1. Las lagunas estándar están prohibidas.
  2. Las funciones matemáticas incorporadas y los operadores de trigonometría (sin, cos, tan, etc.), factorial y exponenciación no se pueden usar. Puede utilizar una función de redondeo incorporada para estimar el resultado de la computación sin(x)y cos(x)el sexto dígito decimal.
  3. No es necesario manejar entradas incorrectas.
  4. Solo se pueden usar caracteres ASCII en el programa, no los Unicode chinos que permiten la compresión de código.
  5. Su programa debe finalizar y mostrar la salida dentro de los 3 segundos posteriores a la entrada.
  6. Su respuesta debe acompañar el código no escrito, junto con la explicación del código (obligatorio si el código no es inmediatamente obvio para los programadores que no están familiarizados con su lenguaje, especialmente GolfScript, J, etc.).
  7. Incluya un enlace a un compilador en línea donde se pueda probar su programa.

Puntuación:

¡La respuesta con la longitud de código más baja en caracteres, incluidos espacios en blanco, tabulaciones, etc., gana! El ganador sería declarado el 21 de mayo de 2014.

EDITAR : 21/05/14 El ganador es aditsu usando el lenguaje CJam . El segundo lugar sigue a jpjacobs con lenguaje J , y el segundo lugar es primo con lenguaje Perl . ¡Felicidades a todos!


(Nota de modificación: comentarios desviados. Por favor, hágame un ping por cualquier información perdida que pueda desear; parece que después de mi advertencia por adelantado, todo se abrió paso en la pregunta.)
Pomo de la puerta

En el primer párrafo, debería ser "seno", no "pecado"
No es que Charles

¿ Sigue siendo un requisito "Redondear al más cercano" , o podemos usar alguna instalación de redondeo incorporada? por ejemplo, redondear hacia cero?
Trauma digital

Requerir el equivalente de una mod 2pioperación para hacer que las entradas converjan más rápido sería bastante útil: es una de las muchas mejoras que utiliza el mundo real cuando se trata de estas funciones. (en realidad mod pi y reconocimiento de signos).
Floris

1
@ Floris Nunca supe esto. Bueno, no podemos hacer nada ahora, las reglas ya han cambiado mucho, y no quiero seguir cambiándolas para molestar aún más a los que responden. Gracias por la sugerencia sin embargo!
Gaurang Tandon

Respuestas:


6

CJam - 42

rd:X;1_ri2*,1>{_2%2*(*/X*_}/;]2/z{:+6mO}/p

Pruébelo en línea en http://cjam.aditsu.net

Explicación:

rlee un token de la entrada se
dconvierte en
:Xasignaciones dobles a la variable X
;aparece el valor de la pila
1pone 1 en la pila (el primer término)
_duplica el 1
rlee el siguiente token (el n)
iconvierte a entero
2*,1>{...}/es una especie de bucle de 1 a 2 * n - 1:
- se 2*multiplica por 2
- ,forma una matriz de 0 a (último valor) -1
- 1>elimina el primer elemento de la matriz (0)
- {...}/ejecuta el bloque para cada elemento de la matriz
_duplica el "ciclo variable "(llamémosla k)
2%2*(convierte de par / impar a -1/1:
- 2%es el módulo 2 (-> 0/1)
- se 2*multiplica por 2 (-> 0/2)
-(los decrementos (-> -1/1) se
*multiplican, por lo que cambiar el signo cada dos veces
/divide el término en la pila por k o -k; este es el "/ k!" parte del cálculo junto con el cambio de signo se
X*multiplica por X; esta es la parte "X ^ k" del cálculo; obtuvimos el siguiente término en la serie
_duplica el término que se utilizará para calcular el siguiente término en la siguiente iteración
;(después del bucle) aparece el último término duplicado
]recoge los términos en la pila en una matriz
En este punto tenemos una matriz [ 1 X -X ^ 2/2! -X ^ 3/3! X ^ 4/4! X ^ 5/5! ...] que contiene exactamente todos los términos que necesitamos para cos (x) y sin (x), intercalados
2/divide esta matriz en pares
z transpone la matriz, dando como resultado la matriz con los términos para cos (x) y la matriz con los términos para sin (x), como "filas de matriz"
{...}/nuevamente ejecuta el bloque para cada elemento de la matriz (fila de la matriz):
- :+agrega los elementos de la fila de la matriz juntos
-6mO redondea a 6 decimales
En este punto, tenemos el cos (x) y sin (x) deseados en la pila
pimprime la representación del último elemento en la pila (sin (x)) seguido de una nueva línea
en Al final del programa, el contenido restante de la pila (cos (x)) se imprime automáticamente.


1
+1 por presentarme un idioma del que nunca he oído hablar y que probablemente nunca usaré.
Alex A.

@Alex gracias, CJam es algo así como GolfScript con esteroides
aditsu

No me gusta cambiar las reglas después de publicar la pregunta, pero he rechazado los caracteres Unicode de compresión de código, ya que no sabía que los caracteres Unicode podrían usarse para comprimir el código. Solo los caracteres ASCII se pueden usar ahora. Por favor edita tu publicación. Disculpe las molestias.
Gaurang Tandon

@GaurangTandon No me gusta mucho tampoco. ¿Para qué más creías que podrían usarse los caracteres chinos en este problema? De todos modos, editado.
aditsu

18

Perl - 72 bytes

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

O, contando las opciones de línea de comando como 1 byte cada una, en 70 bytes :

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

O, si me permite Perl 5.8, en 63 bytes :

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

pero por qué lo harías

Editar : Cumplimiento de las nuevas reglas. %fRedondea a 6 lugares por defecto, ¡qué conveniente!


Algoritmo

Examinando la serie de Taylor para el pecado (x) :

Se puede ver que cada término divide equitativamente cada término sucesivo. Debido a esto, se puede transformar sin esfuerzo en una expresión anidada:

cos (x) transforma de manera similar, sin la x inicial , y los términos del denominador son más pequeños.

Además, esta expresión anidada puede reformularse como una expresión recursiva inversa:

con s = 0 y sin (x) = x · s 1 , que en última instancia es lo que se usa.


Sin golf

<> =~ 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);

Uso de muestra

$ 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

Si desea probar esto en línea, le recomiendo usar compileonline.com . Copie y pegue el código en main.pl, y la entrada en el STDINcuadro, entonces Execute Script.


2
¿Qué manera tortuosa de analizar la entrada ... puedo usar eso en mi solución? :)
Tal

@Tal Siéntete libre.
primo

2
Creo que Perl (y especialmente su código) cuenta como "no inmediatamente obvio para los programadores que no están familiarizados con su idioma"
Aditsu

1
@aditsu De acuerdo. Agregaré un código más limpio y una explicación del algoritmo.
primo

2
¡Esta respuesta realmente fue extremadamente educativa!
Tal

10

Python 3 (102) / Python 2 (104)

Pitón 3 (102)

x,n=map(float,input().split())
k=2*n
t=1
while k>1:k-=1;t=1+t*1j*x/k
print('%.6f\n'*2%(t.imag,t.real))

Python 2.7 (104)

x,n=map(float,raw_input().split())
k=2*n
t=1
while k>1:k-=1;t=1+t*1j*x/k
print'%.6f\n'*2%(t.imag,t.real)

Básicamente el mismo código. Salvamos a dos personajes de no necesitar padres, printpero perdemos cuatro por necesidad raw_input.

Ejecución de la muestra

Puedes ejecutar esto aquí .

>>>
20 20
-5364.411846
-10898.499385

Explicación del código

La idea principal es calcular los 2*ntérminos de e^(ix), y luego tomar la parte imaginaria y real para obtener los valores siny cosaproximados a los ntérminos. Usamos el truncamiento de la serie Taylor:

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

Esto es polinomial en i * x, pero en lugar de calcular su valor sumando cada término, usamos un Método de Horner modificado para calcular la secuencia (definida recursivamente en reversa)

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

lo que da t_1igual el valor deseado.

Las operaciones de formato de cadenas de Python se utilizan para obtener los valores para mostrar redondeados hasta 6 dígitos decimales.

Editar: cambiado a redondear a 6 dígitos según las nuevas reglas. No se necesitaron otros cambios.


Prueba ideone para un intérprete en línea de py3 :)
Harry Beadle

@BritishColour ¡Gracias! Lo he agregado a la publicación.
xnor

Por favor actualice su respuesta. Ver detalles en cuestión. Gracias.
Gaurang Tandon

8

J 98 70 69 58

Aunque esto probablemente se puede acortar un poco usando funciones más sofisticadas ... los comentarios son bienvenidos:

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

nota 2: la entrada finaliza cuando se recibe EOF (ctrl-D en linux). Editar: unir exponenciación y factorial en un conjunto J-ish más agradable y más completo:($ %&(*/) >:@i.@[ ) . Esto se reduce a tomar una matriz de x réplicas de y y una matriz de los números del 1 al y. Multiplica cada uno y divide el resultado. Esto elimina el duplicado */.

Gracias a algortihmshark, otros 7 caracteres apagados.

Corte eliminado para deshacerse de la nueva línea final.

Versión más larga, para la cual es imprescindible conocer los tenedores.

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''

No hay un intérprete J en línea, pero es de código abierto desde hace unos años; La instalación es fácil con estas instrucciones:

http://www.jsoftware.com/jwiki/System/Installation/J801

En #jsoftware en irc.freenode.org, también hay un J bot.

stdin funciona solo cuando se ejecuta desde un archivo, desde la línea de comandos, de lo contrario, reemplace stdin ''con 'a b;'donde ayb son los números que se habrían pasado en la línea de comandos.


55
Me encanta que comience conexit
Digital Trauma

Por favor actualice su respuesta. Ver detalles en cuestión. Gracias.
Gaurang Tandon

Actualizado para los 6 decimales. Si hay algo más, por favor especifique. Gracias
jpjacobs

Puede eliminar el &de 0j6&":para guardar un carácter. Además, (i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.)puede ser reescrito (($%&(*/)1+i.@[)"0~i.@,&_2)/para otro 6.
algoritmshark

Esta tarea es un grito T.(función aproximada de la serie Taylor de n términos), pero creo que eso es verboten como un resquicio estándar.
FUZxxl

6

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

Sin golf:

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

La primera línea lee la entrada y usa expresiones regulares para encontrar un espacio; esto coloca automáticamente el valor antes del espacio en $ `y el valor después de este en $ '.

Ahora hacemos un bucle de 1 a 2*n-1. $tes nuestro término, que el bucle multiplica repetidamente por xy divide por el índice del bucle ($_ ). El ciclo comienza en 1 en lugar de 0 porque el coseno se inicializa en 1, lo que me ahorró tener que lidiar con la división por cero.

Después de la actualización $t, el operador trinario devuelve $sineo $cosine, dependiendo de si el índice es par o impar, y le agrega $tel valor. La fórmula mágica$_&2?-$t:$t calcula si se debe sumar o restar este valor (básicamente usando un bit a bit y en el índice y 2 para generar la secuencia repetitiva de "sumar, sumar, restar, restar").

Puede probar y ejecutar este código en compileonline.com .


Por favor corrija su salida para 20 20.
Gaurang Tandon

1
Creo que tu bucle for debe ir desde 1..$n*2-1, en lugar de 1..$n. Mientras estoy aquí ... $sestá perfectamente bien sin inicializar, como se undefevalúa 0en un contexto numérico. Asignación ternaria no necesita paréntesis: $_&1?$s:$c+=$t. "%.8f\n%.8f"se puede acortar a "%.8f\n"x2, como consecuencia de agregar una nueva línea final.
primo

@Primo Gracias, no sabía nada de eso. Y ahora incluso produce el resultado correcto también.
Tal

@Tal Un placer. Además, un poco mejor magia: $t*(1-($_&2))=> $_&2?-$t:$t.
primo

Por favor actualice su respuesta. Ver detalles en cuestión. Gracias.
Gaurang Tandon

5

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

Abuso del tipeo implícito, pero desafortunadamente no existe ese tipo complejo implícito, así que tuve que especificar eso y el complejo i. Gfortran corta la producción en 8 decimales de forma natural, por lo que somos buenos en esa especificación. Desafortunadamente, mi método original de salida print*,tno cumplía con las especificaciones, así que tuve que agregar 16 caracteres para generar los componentes imaginarios y reales y presionar los 8 decimales requeridos.

Gracias a Ventero, logré guardar 23 bytes entre la salida y el bucle. Y otro personaje para obtener respuestas correctas y resultados formateados. Y 3 más en la readdeclaración.

Sin golf,

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

Por favor actualice su respuesta. Ver detalles en cuestión. ¡Gracias!
Gaurang Tandon

1
@GaurangTandon: Probablemente deberías dejar de cambiar los detalles del problema.
Kyle Kanos

Lo sé y no quiero, pero no puedo evitarlo. En realidad, después de probar 5 respuestas, resultó que casi todas daban resultados diferentes (esto era completamente insospechado). Podría haber seguido algún otro enfoque, pero eso habría requerido el cambio completo de los algoritmos de las respuestas actuales. Este es el mejor que pude entender.
Gaurang Tandon

2
Bueno, sé que el mío funciona perfectamente, así que debería obtener el cheque por completo : D;)
Kyle Kanos

4

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);}

Para guardar un byte, las instrucciones que actualizan el valor seno se colocan dentro del for() declaración, pero en realidad se ejecutan después de las declaraciones que siguen al paréntesis de cierre que actualizan el valor coseno. (Supongo que también podría guardar un par de bytes más eliminando el carácter de nueva línea final en la salida del programa).

Las variables globales s , c, ry xse inicializan a cero de forma implícita, yi tendrán un valor de 1, siempre y cuando no hay argumentos que aparecen en la línea de comandos. Lamentablemente, el valor printf()predeterminado es 6 lugares de decimales, por lo que el formato de salida es un poco detallado.

Sin golf:

Aquí está el código con un poco de reorganización para que el orden en que se hacen las cosas sea un poco más claro:

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

Salida de muestra:

$ echo 1.23 4 | ./sincos
0.94247129
0.33410995

Pruébalo en línea:

http://ideone.com/URZWwo


3

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

Un poco simple como el infierno. Utiliza la fórmula de la pregunta parametrizada para seno y coseno.

Intérprete en línea se puede encontrar aquí aquí

x,n=map(eval,raw_input().split())
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))

Editar: versión válida con todas las restricciones

Edit2: se cambió el intérprete en línea a ideone.com debido a una roundsalida de función no válida en Python 2.7.1

Edit3: resultó que utilicé lambda en línea innecesaria + cambié el redondeo al formato de cadena (robado de xnor :))

Edit4: reemplazado joincon el forbucle principal no funcional


Hola, he editado recientemente las reglas que ahora no permiten la exponenciación de los operadores integrados (eso es lo que **está haciendo, supongo). Entonces, creo que tendrás que editar tu respuesta. Disculpe las molestias. Por favor, corríjame si estoy equivocado.
Gaurang Tandon

1
Supongo modificaciones adicionales son inútiles con la XNOR respuesta :)
Avall

@avail Encendido 20 20, obtengo salida -5364.4118142500001. Puede que quieras arreglarlo a 8 decimales.
Gaurang Tandon

Es por la versión repl.it de Python 2.7.1. Si lo ejecuta en ideone.com (Python 2.7.3) funciona correctamente. ideone.com/JsYNNK
Avall

¡Funciona bien ahora! +1
Gaurang Tandon

3

JavaScript: 114 caracteres

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))

Basado en la gran respuesta de James. Mismo algoritmo, primer paso evitado con la inicialización de c = 1 y s = x. El uso de 2 vars en lugar de una matriz para la salida simplifica el bucle.

Sin golf

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))     

Error tipográfico menor: Sería s += (l *= x / ++d)y no s += (l* = x / ++d)en el código no reflejado.
Gaurang Tandon

1
@GaurangTandon solucionado
edc65

2

JavaScript (borrador de ECMAScript 6) - 97 96 caracteres

Una solución recursiva:

f=(x,n,m=1,i=0,s=x,c=1)=>i<2*n?f(x,n,m*=-x*x/++i/++i,i,s+m*x/++i,c+m):[s,c].map(x=>x.toFixed(8))

Salida:

f(0.3,1)
["0.29550000", "0.95500000"]

f(0.3,24)
["0.29552021", "0.95533649"]

Sin embargo, eso no cumple con las especificaciones con respecto al redondeo.
Martin Ender

@ m.buettner fijo
MT0

1
No cumple con el formato de entrada y el no functionsrequisito.
Avall

Por favor actualice su respuesta. Ver detalles en cuestión. Gracias.
Gaurang Tandon

2

C, 114

Reputación insuficiente para comentar, pero más allá de la respuesta C de Squeamish Offisrage , la reducción de 7 bytes mediante el uso de flotante para duplicar y eliminar espacios, y la combinación de declaración e inicio de 'r' da

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);}

tratar aquí .


Bienvenido a la programación de rompecabezas y código de golf. Bien hecho por reconocer que su respuesta es una mejora menor en @ squeamishossifrage (todavía logré deletrearlo mal en mi edición). Es mejor no referirse a la respuesta "anterior" porque el orden cambia cada vez que hay una edición. Por cierto, noté la inicialización de ren la declaración. No he probado para ver si floatda la precisión requerida.
Level River St

@steveverrill Tampoco pensé floatque daría la precisión requerida, pero funciona :) ¡Y bienvenido a PPCG, user2702245!
Gaurang Tandon

¿Soy yo el único que obtiene las respuestas incorrectas con las floatvariables entonces? Por x=5y n=3, obtengo sin(x)=10.20833206y cos(x)=14.54166412:-( (Intel Core Duo, en caso de que te lo estés preguntando)
apretujado ossifrage

¿Desea que convierta esto en un comentario sobre dicha respuesta?
Pomo de la puerta

@Doorknob también puede dejarlo ahora :-)
apretujado ossifrage

2

GNU bc, controlado por bash, 128 bytes

Se gastaron demasiados bytes para establecer lugares decimales y el redondeo más cercano. Oh bueno, aquí está de todos modos:

bc -l<<<"m=1000000
w=s=$1
c=1
for(p=2;p/2<$2;s+=w){w*=-1*$1/p++
c+=w
w*=$1/p++}
s+=((s>0)-.5)/m
c+=((c>0)-.5)/m
scale=6
s/1
c/1"

Salida:

$ ./trig.sh 5 3
10.208333
14.541667
$ ./trig.sh 8.555 13
.765431
-.641092
$ ./trig.sh 9.26 10
-3.154677
-8.404354
$ ./trig.sh 6.54 12
.253986
.967147
$ ./trig.sh 5 1
5.000000
1.000000
$ ./trig.sh 20 20
-5364.411846
-10898.499385
PS 

Herramientas de línea de comandos de Linux, 97 caracteres unicode

Se ha eliminado la respuesta de pirateo de Unicode a pedido de OP Mira el historial de edición si te interesa.


No me gusta cambiar las reglas después de publicar la pregunta, pero he rechazado los caracteres Unicode de compresión de código, ya que no sabía que los caracteres Unicode podrían usarse para comprimir el código. Solo los caracteres ASCII se pueden usar ahora. Por favor edita tu publicación. Disculpe las molestias
Gaurang Tandon

@GaurangTandon No es realmente compresión: la versión Unicode en realidad toma más bytes (pero menos caracteres). Pero estoy de acuerdo con su opinión: en realidad prefiero que la puntuación se realice estrictamente utilizando el conteo de bytes, pero no pude resistir un poco sobre los caracteres chinos en su OP.
Trauma digital

Se utiliza el operador exponencial ilegal
Avall

@avall Oops. Eso me costó 4 bytes.
Trauma digital

1

Rubí, 336

Probablemente el más largo aquí, pero estoy seguro de que podría acortarse :(

def f(n)
n==0 ? 1: 1.upto(n).inject(:*)
end
def p(x,y)
i=1
return 1 if y==0 
y.times {i *= x}
i
end
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)
end
a.round(8)
end
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)
end
a.round(8)
end
x = gets.chomp
n = gets.chomp.to_i
puts s(x,n), c(x,n)

1

JavaScript (ES6): 185 caracteres

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]))

Utiliza una función qpara factorial, ipara exponenciación y ppara realizar ambas siny cos. Ejecute en jsbin.com. Utiliza exactamente la fórmula sin ninguna modificación.

EDITAR : Cambió los 8decimales a 6decimales. 15 / mayo / 14

Código sin golf :

/*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]));

1

JavaScript: 133 caracteres

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));

Sin golf

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);
}

prompt(out[1].toFixed(6));
prompt(out[0].toFixed(6));

La entrada debe ser dos enteros separados por espacios, no en dos cuadros de diálogo diferentes. Por favor arregla eso.
Gaurang Tandon

@GaurangTandon solucionado - gracias por señalarlo
James


1

Rubí 160 152 140 caracteres

Utilizando la recursividad y el hecho de que para esta implementación recursiva sin (x, 2n + 1) = 1 + cos (x, 2n - 1), siendo sin (x, n) y cos (x, n) la serie definida anteriormente para cos x y sen x.

p=->x,n{n<1?1:x*p[x,n-1]}
f=->n{n<2?1:n*f[n-1]}
c=->x,n{n<1?1:p[x,n]/f[n]-c[x,n-2]}
x,n=gets.split.map &:to_f
n*=2
puts c[x,n-1]+1,c[x,n-2]

Editar: Contribuido por comentaristas (leer más abajo).


1
Usted puede ahorrar una gran cantidad de caracteres mediante el uso de lambdas: p=->x,n{...}, f=->n{...}y así sucesivamente, y luego usar corchetes en lugar de paréntesis, a llamarlos, al igual que p[x,n-1]. Además, creo que collectes solo un alias para map, que es mucho más corto, y dado que solo está asignando una llamada de miembro, puede acortar eso a gets.split.map &:to_f.
Martin Ender

@ MartinBüttner Gracias! Agregará esto! (espero que su comentario aquí indique que esta solución no es solo mía, sino de colaboración) Para ser honesto: también soy nuevo en ruby ​​(solo 2 meses) :)))
Boriel
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.