Introducción:
El seno de x
está 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 x
viene 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 x
y n
, escriba un programa (sin funciones, etc.) para generar el valor sin(x)
y cos(x)
corregir hasta los n
términos de la fórmula anterior. Supongamos que x
está 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:
- Las lagunas estándar están prohibidas.
- 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)
ycos(x)
el sexto dígito decimal. - No es necesario manejar entradas incorrectas.
- Solo se pueden usar caracteres ASCII en el programa, no los Unicode chinos que permiten la compresión de código.
- Su programa debe finalizar y mostrar la salida dentro de los 3 segundos posteriores a la entrada.
- 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.).
- 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!
mod 2pi
operació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).Respuestas:
CJam - 42
Pruébelo en línea en http://cjam.aditsu.net
Explicación:
r
lee un token de la entrada sed
convierte en:X
asignaciones dobles a la variable X;
aparece el valor de la pila1
pone 1 en la pila (el primer término)_
duplica el 1r
lee el siguiente token (el n)i
convierte a entero2*,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 seX*
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 matrizEn 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 paresz
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 decimalesEn este punto, tenemos el cos (x) y sin (x) deseados en la pila
p
imprime la representación del último elemento en la pila (sin (x)) seguido de una nueva líneaen Al final del programa, el contenido restante de la pila (cos (x)) se imprime automáticamente.
fuente
Perl - 72 bytes
O, contando las opciones de línea de comando como 1 byte cada una, en 70 bytes :
O, si me permite Perl 5.8, en 63 bytes :
pero por qué lo harías
Editar : Cumplimiento de las nuevas reglas.
%f
Redondea 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
Uso de muestra
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 elSTDIN
cuadro, entonces Execute Script.fuente
Python 3 (102) / Python 2 (104)
Pitón 3 (102)
Python 2.7 (104)
Básicamente el mismo código. Salvamos a dos personajes de no necesitar padres,
print
pero perdemos cuatro por necesidadraw_input
.Ejecución de la muestra
Puedes ejecutar esto aquí .
Explicación del código
La idea principal es calcular los
2*n
términos dee^(ix)
, y luego tomar la parte imaginaria y real para obtener los valoressin
ycos
aproximados a losn
términos. Usamos el truncamiento de la serie Taylor: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)
lo que da
t_1
igual 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.
fuente
J
98 70 6958Aunque esto probablemente se puede acortar un poco usando funciones más sofisticadas ... los comentarios son bienvenidos:
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.
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.fuente
exit
&
de0j6&":
para guardar un carácter. Además,(i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.)
puede ser reescrito(($%&(*/)1+i.@[)"0~i.@,&_2)/
para otro 6.T.
(función aproximada de la serie Taylor de n términos), pero creo que eso es verboten como un resquicio estándar.Perl,
1201081048985Sin golf:
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
.$t
es nuestro término, que el bucle multiplica repetidamente porx
y 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$sine
o$cosine
, dependiendo de si el índice es par o impar, y le agrega$t
el 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 .
fuente
20 20
.1..$n*2-1
, en lugar de1..$n
. Mientras estoy aquí ...$s
está perfectamente bien sin inicializar, como seundef
evalúa0
en 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.$t*(1-($_&2))
=>$_&2?-$t:$t
.Fortran:
8910912510210198 bytesAbuso 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 salidaprint*,t
no 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
read
declaración.Sin golf,
fuente
C, 120
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
,r
yx
se 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 valorprintf()
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:
Salida de muestra:
Pruébalo en línea:
http://ideone.com/URZWwo
fuente
Python> = 2.7.3,
186184211200182170 caracteresUn 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íEditar: versión válida con todas las restricciones
Edit2: se cambió el intérprete en línea a ideone.com debido a una
round
salida de función no válida en Python 2.7.1Edit3: resultó que utilicé lambda en línea innecesaria + cambié el redondeo al formato de cadena (robado de xnor :))
Edit4: reemplazado
join
con elfor
bucle principal no funcionalfuente
**
está haciendo, supongo). Entonces, creo que tendrás que editar tu respuesta. Disculpe las molestias. Por favor, corríjame si estoy equivocado.20 20
, obtengo salida-5364.4118142500001
. Puede que quieras arreglarlo a 8 decimales.2.7.1
. Si lo ejecuta en ideone.com (Python 2.7.3) funciona correctamente. ideone.com/JsYNNKJavaScript: 114 caracteres
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
fuente
s += (l *= x / ++d)
y nos += (l* = x / ++d)
en el código no reflejado.JavaScript (borrador de ECMAScript 6) -
9796 caracteresUna solución recursiva:
Salida:
fuente
no functions
requisito.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
tratar aquí .
fuente
r
en la declaración. No he probado para ver sifloat
da la precisión requerida.float
que daría la precisión requerida, pero funciona :) ¡Y bienvenido a PPCG, user2702245!float
variables entonces? Porx=5
yn=3
, obtengosin(x)=10.20833206
ycos(x)=14.54166412
:-( (Intel Core Duo, en caso de que te lo estés preguntando)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:
Salida:
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.
fuente
Rubí, 336
Probablemente el más largo aquí, pero estoy seguro de que podría acortarse :(
fuente
JavaScript (ES6): 185 caracteres
Utiliza una función
q
para factorial,i
para exponenciación yp
para realizar ambassin
ycos
. Ejecute en jsbin.com. Utiliza exactamente la fórmula sin ninguna modificación.EDITAR : Cambió los
8
decimales a6
decimales. 15 / mayo / 14Código sin golf :
fuente
JavaScript: 133 caracteres
Sin golf
fuente
Mathematica, 96 caracteres
fuente
x,n
me parece ?x n
.Rubí
160152140 caracteresUtilizando 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.
Editar: Contribuido por comentaristas (leer más abajo).
fuente
p=->x,n{...}
,f=->n{...}
y así sucesivamente, y luego usar corchetes en lugar de paréntesis, a llamarlos, al igual quep[x,n-1]
. Además, creo quecollect
es solo un alias paramap
, que es mucho más corto, y dado que solo está asignando una llamada de miembro, puede acortar eso agets.split.map &:to_f
.