Que la trigonométrie commence!

20

Introduction:

Le sinus de xest donné par la formule:

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

Le cosinus de xest donné par la formule:

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

Tâche:

Étant donné la valeur de xet n, écrivez un programme (pas de fonctions, etc.) pour afficher la valeur de sin(x)et cos(x)corriger les ntermes de la formule ci-dessus. Supposons que ce xsoit en radians.

Contribution:

x n

Un nombre décimal x(jusqu'à 3 décimales) et un entier n. L'entrée doit être sur stdin ou une boîte de dialogue d'invite (si votre langue ne prend pas en charge stdin)

Production:

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

La valeur des deux sin(x)et cos(x)doit être arrondie à 6 décimales. Si sin(x)est 0.5588558855(10 chiffres décimaux), il doit être arrondi à 0.558856(6 chiffres décimaux). L'arrondi doit avoir lieu au plus proche, comme décrit dans la cinquième colonne, "Arrondir au plus proche", du tableau de cet article Wiki .

Contraintes:

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

Échantillons:

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

Remarques:

  1. Les failles standard sont interdites.
  2. Les fonctions mathématiques intégrées et les opérateurs de trigonométrie (sin, cos, tan, etc.), factorielle et exponentiation ne peuvent pas être utilisés. Vous êtes libre d'utiliser une fonction d'arrondi intégrée pour estimer le résultat du calcul sin(x)et cos(x)jusqu'au 6ème chiffre décimal.
  3. Pas besoin de gérer les mauvaises entrées.
  4. Seuls les caractères ASCII peuvent être utilisés dans le programme, pas ceux en chinois Unicode qui permettent la compression de code.
  5. Votre programme doit se terminer et afficher la sortie dans les 3 secondes suivant la saisie.
  6. Votre réponse doit accompagner le code non golfé, ainsi que l'explication du code (obligatoire si le code n'est pas immédiatement évident pour les programmeurs qui ne connaissent pas votre langage, en particulier GolfScript, J, etc.).
  7. Veuillez inclure un lien vers un compilateur en ligne où votre programme peut être testé.

Notation:

La réponse avec la plus petite longueur de code en caractères, y compris les espaces blancs, les tabulations, etc. gagne! Le gagnant sera déclaré le 21 mai 2014.

EDIT : 21/05/14 Winner est aditsu en utilisant le langage CJam . Le finaliste suit jpjacobs avec le langage J , et le deuxième finaliste est primo avec le langage Perl . Félicitations à tous!

Gaurang Tandon
la source
(Note du mod: commentaires nuked. S'il vous plaît envoyez-moi un ping pour toute information perdue que vous pourriez vouloir; ressemble à mon avertissement à l'avance, cependant tout a fait son chemin dans la question.)
Poignée de porte
Dans le premier paragraphe, ce devrait être "sinus", pas "péché"
Pas que Charles
Est-il toujours nécessaire d'arrondir au plus proche ou pouvons-nous utiliser des installations d'arrondi intégrées? par exemple arrondir vers zéro?
Digital Trauma
Exiger l'équivalent d'une mod 2piopération pour accélérer la convergence des entrées serait plutôt utile - c'est l'une des nombreuses améliorations que le monde réel utilise lorsqu'il s'agit de ces fonctions. (en fait mod pi et signez la conscience).
Floris
1
@Floris Je ne l'ai jamais su. Eh bien, nous ne pouvons rien faire maintenant, les règles ont déjà beaucoup changé et je ne veux pas continuer à les changer pour embêter davantage les répondeurs. Merci pour la suggestion!
Gaurang Tandon

Réponses:

6

CJam - 42

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

Essayez-le en ligne sur http://cjam.aditsu.net

Explication:

rlit un jeton de l'entrée
dconvertit en double
:Xattribue à la variable X
;affiche la valeur de la pile
1met 1 sur la pile (le premier terme)
_duplique le 1
rlit le jeton suivant (le n)
iconvertit en entier
2*,1>{...}/est une sorte de boucle de 1 à 2 * n - 1:
- 2*multiplie par 2
- ,crée un tableau de 0 à (dernière valeur) -1
- 1>supprime le premier élément du tableau (0)
- {...}/exécute le bloc pour chaque élément du tableau
_duplique la boucle " variable "(appelons-le k)
2%2*(convertit de pair / impair en -1/1:
- 2%est modulo 2 (-> 0/1)
- 2*multiplie par 2 (-> 0/2)
-(les décréments (-> -1/1) se
*multiplient, changeant ainsi le signe une fois sur deux
/divise le terme sur la pile par k ou -k; c'est le "/ k!" une partie du calcul avec le changement de signe se
X*multiplie par X; c'est la partie "X ^ k" du calcul; nous avons obtenu le terme suivant dans la série
_duplique le terme à utiliser pour calculer le terme suivant dans la prochaine itération
;(après la boucle) apparaît le dernier terme dupliqué
]recueille les termes sur la pile dans un tableau
À ce stade, nous avons un tableau [ 1 X -X ^ 2/2! -X ^ 3/3! X ^ 4/4! X ^ 5/5! ...] contenant exactement tous les termes dont nous avons besoin pour cos (x) et sin (x), entrelacé
2/divise ce tableau en paires
ztranspose la matrice, ce qui donne le tableau avec les termes pour cos (x) et le tableau avec les termes pour sin (x), car les "lignes de matrice"
{...}/exécutent à nouveau le bloc pour chaque élément du tableau (ligne de matrice):
- :+ajoute les éléments de la rangée de la matrice en même temps
- est 6mOarrondi à 6 décimales
à ce stade , nous avons les cos désirées (x) et sin (x) sur la pile
pimprime la représentation du dernier élément de la pile (sin (x)) suivi d'un retour à la ligne
a à la fin du programme, le contenu restant de la pile (cos (x)) est imprimé automatiquement.

aditsu
la source
1
+1 pour m'avoir fait découvrir une langue dont je n'ai jamais entendu parler et que je n'utiliserai probablement jamais.
Alex A.
@Alex merci, CJam est un peu comme GolfScript sur les stéroïdes
aditsu
Je n'aime pas changer les règles après avoir posté la question, mais j'ai interdit les caractères Unicode autorisant la compression de code, car je ne savais pas que les caractères Unicode pouvaient être utilisés pour compresser du code. Seuls les caractères ASCII peuvent être utilisés maintenant. Veuillez modifier votre message. Désolé pour le dérangement.
Gaurang Tandon
@GaurangTandon Je n'aime pas ça non plus. Selon vous, à quoi d'autre pourrait-il être utile d'utiliser les caractères chinois dans ce problème? Quoi qu'il en soit, édité.
aditsu
18

Perl - 72 octets

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

Ou, en comptant les options de ligne de commande comme 1 octet chacune, dans 70 octets :

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

Ou, si vous me permettez Perl 5.8, en 63 octets :

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

mais pourquoi voudriez-vous.

Edit : Conformité aux nouvelles règles. %farrondit à 6 places par défaut, comme c'est pratique!


Algorithme

Examen de la série Taylor pour le péché (x) :

on peut voir que chaque terme divise également chaque terme successif. Pour cette raison, il peut être transformé assez facilement en une expression imbriquée:

cos (x) se transforme de façon similaire, sans le x de tête , et les termes du dénominateur un plus petit.

De plus, cette expression imbriquée peut être reformulée comme une expression récursive inverse:

avec s = 0 et sin (x) = x · s 1 , qui est finalement ce qui est utilisé.


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

Exemple d'utilisation

$ 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 vous souhaitez tester cela en ligne, je vous recommande d'utiliser compileonline.com . Copiez-collez le code dans main.pl, et l'entrée dans la STDINboîte, puis Execute Script.

primo
la source
2
Quelle façon sournoise d'analyser l'entrée ... puis-je l'utiliser dans ma solution? :)
Tal
@Tal N'hésitez pas.
primo
2
Je pense que Perl (et surtout votre code) compte comme "pas immédiatement évident pour les programmeurs qui ne connaissent pas votre langage"
aditsu
1
@aditsu Accepté. J'ajouterai du code plus propre et une explication de l'algorithme.
primo
2
Cette réponse était vraiment extrêmement éducative!
Tal
10

Python 3 (102) / Python 2 (104)

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

Fondamentalement, le même code. Nous sauvons deux personnages de ne pas avoir besoin de parens printmais en perdons quatre raw_input.

Exemple d'exécution

Vous pouvez les exécuter ici .

>>>
20 20
-5364.411846
-10898.499385

Explication du code

L'idée principale est de calculer les 2*ntermes de e^(ix), puis de prendre la partie imaginaire et réelle pour obtenir les valeurs sinet cosapprochées des ntermes. Nous utilisons la troncature de la série Taylor:

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

Il s'agit d'un polynôme en i * x, mais plutôt que de calculer sa valeur en sommant chaque terme, nous utilisons une méthode de Horner modifiée pour calculer la séquence (définie récursivement à l'envers)

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

ce qui donne t_1égal à la valeur souhaitée.

Les opérations de formatage des chaînes Python sont utilisées pour obtenir les valeurs à afficher arrondies à 6 chiffres décimaux.

Modifier: Changé pour arrondir à 6 chiffres selon les nouvelles règles. Aucun autre changement n'était nécessaire.

xnor
la source
Essayez ideone pour un interprète en ligne py3 :)
Harry Beadle
@BritishColour Merci! Je l'ai ajouté au message.
xnor
Veuillez mettre à jour votre réponse. Voir détails en question. Merci.
Gaurang Tandon
8

J 98 70 69 58

Bien que cela puisse probablement être raccourci un peu en utilisant des fonctions plus sophistiquées ... les commentaires sont les bienvenus:

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

note 2: l'entrée se termine lors de la réception d'EOF (ctrl-D sous linux). Edit: et rejoindre exponentiation factoriel dans une plus belle, plus J-ish tout: ($ %&(*/) >:@i.@[ ). Cela revient à prendre un tableau de x réplications de y et un tableau des nombres de 1 à y. Multipliez chacun et divisez le résultat. Cela supprime le doublon */.

Merci à algortihmshark, encore 7 caractères de moins.

Coupe éliminée pour se débarrasser de la nouvelle ligne de fuite.

Version plus longue, pour laquelle la connaissance des fourches est un 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''

Il n'y a pas d'interprète J en ligne, mais il est open source depuis quelques années; l'installation est facile avec ces instructions:

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

Sur #jsoftware sur irc.freenode.org, il y a aussi un J bot.

stdin ne fonctionne que lorsqu'il est exécuté à partir d'un fichier, à partir de la ligne de commande, sinon remplacez stdin ''par 'a b;'où a et b sont les nombres qui auraient été passés sur la ligne de commande.

jpjacobs
la source
5
J'adore que ça commenceexit
Digital Trauma
Veuillez mettre à jour votre réponse. Voir détails en question. Merci.
Gaurang Tandon
Mis à jour pour les 6 décimales. S'il y a autre chose, veuillez préciser. Merci
jpjacobs
Vous pouvez supprimer le &de 0j6&":pour enregistrer un omble chevalier. En outre, (i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.)peut être réécrite (($%&(*/)1+i.@[)"0~i.@,&_2)/pour un autre 6.
algorithmshark
Cette tâche crie T.(fonction approximative par série de Taylor à n termes), mais je pense que c'est verboten comme une échappatoire standard.
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

Non golfé:

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

La première ligne lit l'entrée et utilise l'expression régulière pour trouver un espace; cela place automatiquement la valeur avant l'espace dans $ `et la valeur après dans $ '.

Maintenant, nous bouclons de 1 à 2*n-1. $test notre terme, que la boucle multiplie xet divise à plusieurs reprises par l'index de la boucle ( $_). La boucle commence à 1 plutôt qu'à 0 car le cosinus est initialisé à 1, ce qui m'a évité d'avoir à gérer la division par zéro.

Après la mise à jour $t, l'opérateur trinaire renvoie soit $sineou $cosine, selon que l'index est impair ou pair, et lui ajoute $tla valeur. La formule magique indique $_&2?-$t:$ts'il faut ajouter ou soustraire cette valeur (essentiellement en utilisant un bit et sur l'index et 2 pour générer la séquence répétitive de "ajouter, ajouter, soustraire, soustraire").

Vous pouvez tester-exécuter ce code sur compileonline.com .

Tal
la source
Veuillez corriger votre sortie pour 20 20.
Gaurang Tandon
1
Je pense que votre boucle for devra peut-être partir 1..$n*2-1, au lieu de 1..$n. Pendant que je suis ici ... $sest parfaitement bien laissé non initialisé, comme undefévalué à 0dans un contexte numérique. L' affectation ternaires ne entre parenthèses pas besoin: $_&1?$s:$c+=$t. "%.8f\n%.8f"peut être raccourci en "%.8f\n"x2conséquence de l'ajout d'une nouvelle ligne de fin.
primo
@Primo Merci, je ne connaissais pas certains d'entre eux. Et maintenant, il produit même le résultat correct.
Tal
@Tal Mon plaisir. Aussi, magie légèrement meilleure: $t*(1-($_&2))=> $_&2?-$t:$t.
primo
Veuillez mettre à jour votre réponse. Voir détails en question. Merci.
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

J'abuse du typage implicite, mais malheureusement, aucun type complexe implicite n'existe, j'ai donc dû spécifier cela & le complexe i. Gfortran réduit naturellement la sortie à 8 décimales, donc nous sommes bons sur cette spécification. Malheureusement, ma méthode de sortie d'origine, print*,tne répondait pas aux spécifications, j'ai donc dû ajouter 16 caractères pour produire les composants imaginaires et réels et atteindre les 8 décimales requises.

Grâce à Ventero, j'ai réussi à économiser 23 octets entre la sortie et la boucle. Et un autre caractère pour obtenir des réponses correctes et une sortie formatée. Et 3 plus sur la readdéclaration.

Ungolfed,

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
Kyle Kanos
la source
Veuillez mettre à jour votre réponse. Voir détails en question. Merci!
Gaurang Tandon
1
@GaurangTandon: Vous devriez probablement arrêter de modifier les détails du problème.
Kyle Kanos
Je sais, et je ne veux pas, mais je ne peux pas m'en empêcher. En fait, après avoir testé 5 réponses, il s'est avéré que presque tous donnaient des résultats différents (c'était en effet complètement insoupçonné). J'aurais pu suivre une autre approche, mais cela aurait exigé le changement complet des algorithmes des réponses actuelles. Celui-ci est le meilleur que j'ai pu comprendre.
Gaurang Tandon
2
Eh bien , je sais que le mien fonctionne parfaitement, je devrais donc totalement obtenir le chèque: 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);}

Pour enregistrer un octet, les instructions qui mettent à jour la valeur du sinus sont placées à l'intérieur de l' for()instruction, mais sont en fait exécutées après les instructions suivant la parenthèse fermante qui mettent à jour la valeur du cosinus. (Je suppose que je pourrais également économiser quelques octets supplémentaires en supprimant le caractère de nouvelle ligne final dans la sortie du programme.)

Les variables globales s, c, ret xsont implicitement initialisé à zéro, et iaura une valeur de 1 tant qu'il n'y a pas d' arguments fournis sur la ligne de commande. Malheureusement, par printf()défaut à 6 décimales, le format de sortie est un peu bavard.

Non golfé:

Voici le code avec un peu de réarrangement pour rendre l'ordre dans lequel les choses sont faites un peu plus claires:

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

Exemple de sortie:

$ echo 1.23 4 | ./sincos
0.94247129
0.33410995

Essayez-le en ligne:

http://ideone.com/URZWwo

ossifrage délicat
la source
3

Python> = 2.7.3, 186 184 211 200 182 170 caractères

Un peu simple comme l'enfer. Utilise la formule de la question paramétrée pour le sinus et le cosinus.

Un interprète en ligne peut être trouvé ici ici

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

Edit: version valide avec toutes les restrictions

Edit2: Changement de l'interpréteur en ligne en ideone.com en raison d' roundune sortie de fonction non valide dans Python 2.7.1

Edit3: Il s'est avéré que j'ai utilisé lambda inline inutile + changé d'arrondi au format de chaîne (volé de xnor :))

Edit4: remplacé joinpar la forboucle principale non fonctionnelle

avall
la source
Bonjour dispo, j'ai récemment édité les règles qui ne permettent plus d'exponentiation aux opérateurs intégrés (c'est ce **que je fais). Donc, je pense que vous devrez modifier votre réponse. Désolé pour le dérangement. S'il vous plait corrigez moi si je me trompe.
Gaurang Tandon
1
Je suppose que d'autres modifications sont inutiles avec la réponse de xnor :)
avall
@avail On 20 20, j'obtiens une sortie -5364.4118142500001. Pourrait vouloir le fixer à 8 décimales.
Gaurang Tandon
C'est à cause de la version repl.it de Python 2.7.1. Si vous l'exécutez sur ideone.com (Python 2.7.3), cela fonctionne correctement. ideone.com/JsYNNK
avall
Cela fonctionne bien maintenant! +1
Gaurang Tandon
3

JavaScript - 114 caractères

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

Basé sur la grande réponse de James. Même algorithme, première étape évitée avec l'initialisation de c = 1 et s = x. L'utilisation de 2 variables au lieu d'un tableau pour la sortie simplifie la boucle.

Non 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))     
edc65
la source
Typo mineur: Ce serait s += (l *= x / ++d)et non s += (l* = x / ++d)dans le code non golfé.
Gaurang Tandon
1
@GaurangTandon fixe
edc65
2

JavaScript (ECMAScript 6 Draft) - 97 96 caractères

Une solution récursive:

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

Production:

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

f(0.3,24)
["0.29552021", "0.95533649"]
MT0
la source
Cependant, cela ne correspond pas aux spécifications concernant l'arrondi.
Martin Ender
@ m.buettner fixed
MT0
1
Il ne répond pas au format d'entrée et aux no functionsexigences.
avall
Veuillez mettre à jour votre réponse. Voir détails en question. Merci.
Gaurang Tandon
2

C, 114

Réputation insuffisante pour commenter, mais suite à Squeamish Offisrage's C réponse , réduction de 7 octets en utilisant float pour doubler et supprimer des espaces, et en combinant déclaration et init de 'r' donne

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

essayez ici .

tpb261
la source
Bienvenue dans la programmation d'énigmes et de golf de code. Bravo pour avoir reconnu que votre réponse est une amélioration mineure par rapport à celle de @ squeamishossifrage (j'ai quand même réussi à l'orthographe dans ma modification.) Mieux vaut ne pas se référer à la réponse "ci-dessus" car l'ordre change à chaque fois qu'il y a une modification. BTW, j'ai remarqué l'initialisation de rdans la déclaration. Je n'ai pas testé pour voir si floatdonne la précision requise.
Level River St
@steveverrill Je ne pense pas non plus que floatcela donnerait la précision requise, mais cela fonctionne :) Et bienvenue sur PPCG, user2702245!
Gaurang Tandon
Est-ce juste moi qui obtient alors les mauvaises réponses avec des floatvariables? Pour x=5et n=3, je reçois sin(x)=10.20833206et cos(x)=14.54166412:-( (Intel Core Duo, au cas où vous vous poseriez la question)
squeamish ossifrage
Souhaitez-vous que je convertisse ceci en un commentaire sur ladite réponse?
Poignée de porte
@Doorknob May ainsi laissez-le maintenant :-)
squeamish ossifrage
2

GNU bc, piloté par bash, 128 octets

Beaucoup trop d'octets ont été utilisés pour définir des décimales et arrondir au plus près. Eh bien, le voici de toute façon:

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"

Production:

$ ./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
$ 

Outils de ligne de commande Linux, 97 caractères Unicode

Réponse de piratage Unicode supprimée à la demande de OP. Regardez l'historique des modifications si vous êtes intéressé.

Traumatisme numérique
la source
Je n'aime pas changer les règles après avoir posté la question, mais j'ai interdit les caractères Unicode autorisant la compression de code, car je ne savais pas que les caractères Unicode pouvaient être utilisés pour compresser du code. Seuls les caractères ASCII peuvent être utilisés maintenant. Veuillez modifier votre message. Désolé pour le dérangement
Gaurang Tandon
@GaurangTandon Ce n'est pas vraiment une compression - la version unicode prend en fait plus d'octets (mais moins de caractères). Mais je suis d'accord avec votre sentiment - je préfère en fait que la notation soit strictement effectuée en utilisant le nombre d'octets, mais je n'ai pas pu résister au bit concernant les caractères chinois dans votre OP.
Digital Trauma
Vous utilisez un opérateur exponentiel illégal
avall
@avall Oups. Cela m'a coûté 4 octets.
Digital Trauma
1

Rubis, 336

Probablement le plus long ici, mais je suis sûr qu'il pourrait être raccourci :(

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)
Mhmd
la source
1

JavaScript (ES6) - 185 caractères

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

Utilise une fonction qpour factorielle, ipour l'exponentiation et ppour effectuer les deux sinet cos. Exécutez sur jsbin.com. Utilise exactement la formule sans aucune modification.

EDIT : a changé les 8décimales en 6décimales. 15 / mai / 14

Code non 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]));
Gaurang Tandon
la source
1

JavaScript - 133 caractères

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

Non 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));
James
la source
L'entrée doit être deux entiers séparés par des espaces, pas dans deux boîtes de dialogue différentes. Veuillez corriger cela.
Gaurang Tandon
@GaurangTandon corrigé - merci de l'avoir signalé
James
1

Mathematica, 96 caractères

{{x,n}}=ImportString[InputString[],"Table"];Column@{Im@#,Re@#}&@Fold[1+I#x/#2&,1,2n-Range[2n-1]]
alephalpha
la source
Comment est le format d'entrée, x,nme semble-t -il?
Gaurang Tandon
@GaurangTandon C'est ça x n.
alephalpha
Ok, merci d'avoir clarifié.
Gaurang Tandon
1

Rubis - 160 152 140 caractères

En utilisant la récursivité et le fait que pour cette implémentation récursive sin (x, 2n + 1) = 1 + cos (x, 2n - 1), étant sin (x, n) et cos (x, n) la série définie ci-dessus pour cos x et sin 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]

Edit: Contribution des commentateurs (lire ci-dessous).

Boriel
la source
1
Vous pouvez économiser beaucoup de caractères en utilisant lambdas: p=->x,n{...}, f=->n{...}et ainsi de suite, puis utiliser des crochets au lieu de parenthèses à les appeler, comme p[x,n-1]. De plus, je pense que collectc'est juste un alias pour map, qui est beaucoup plus court, et puisque vous ne mappez qu'un appel membre, vous pouvez le raccourcir en gets.split.map &:to_f.
Martin Ender
@ MartinBüttner Merci! Ajoutera cela! (j'espère que votre commentaire ici a déclaré que cette solution n'est pas seulement la mienne, mais la collaboration) Pour être honnête: je suis aussi nouveau sur ruby ​​(2 mois seulement) :)))
Boriel