Introduction:
Le sinus de x
est 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 x
est 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 x
et n
, écrivez un programme (pas de fonctions, etc.) pour afficher la valeur de sin(x)
et cos(x)
corriger les n
termes de la formule ci-dessus. Supposons que ce x
soit 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:
- Les failles standard sont interdites.
- 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)
etcos(x)
jusqu'au 6ème chiffre décimal. - Pas besoin de gérer les mauvaises entrées.
- Seuls les caractères ASCII peuvent être utilisés dans le programme, pas ceux en chinois Unicode qui permettent la compression de code.
- Votre programme doit se terminer et afficher la sortie dans les 3 secondes suivant la saisie.
- 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.).
- 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!
mod 2pi
opé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).Réponses:
CJam - 42
Essayez-le en ligne sur http://cjam.aditsu.net
Explication:
r
lit un jeton de l'entréed
convertit en double:X
attribue à la variable X;
affiche la valeur de la pile1
met 1 sur la pile (le premier terme)_
duplique le 1r
lit le jeton suivant (le n)i
convertit en entier2*,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 seX*
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 pairesz
transpose 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
6mO
arrondi à 6 décimalesà ce stade , nous avons les cos désirées (x) et sin (x) sur la pile
p
imprime la représentation du dernier élément de la pile (sin (x)) suivi d'un retour à la lignea à la fin du programme, le contenu restant de la pile (cos (x)) est imprimé automatiquement.
la source
Perl - 72 octets
Ou, en comptant les options de ligne de commande comme 1 octet chacune, dans 70 octets :
Ou, si vous me permettez Perl 5.8, en 63 octets :
mais pourquoi voudriez-vous.
Edit : Conformité aux nouvelles règles.
%f
arrondit à 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é
Exemple d'utilisation
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 laSTDIN
boîte, puis Execute Script.la source
Python 3 (102) / Python 2 (104)
Python 3 (102)
Python 2.7 (104)
Fondamentalement, le même code. Nous sauvons deux personnages de ne pas avoir besoin de parens
print
mais en perdons quatreraw_input
.Exemple d'exécution
Vous pouvez les exécuter ici .
Explication du code
L'idée principale est de calculer les
2*n
termes dee^(ix)
, puis de prendre la partie imaginaire et réelle pour obtenir les valeurssin
etcos
approchées desn
termes. Nous utilisons la troncature de la série Taylor: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)
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.
la source
J
98 70 6958Bien que cela puisse probablement être raccourci un peu en utilisant des fonctions plus sophistiquées ... les commentaires sont les bienvenus:
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.
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.la source
exit
&
de0j6&":
pour enregistrer un omble chevalier. En outre,(i.@(,&_2)@{:($%&(*/)>:@i.@[)"0{.)
peut être réécrite(($%&(*/)1+i.@[)"0~i.@,&_2)/
pour un autre 6.T.
(fonction approximative par série de Taylor à n termes), mais je pense que c'est verboten comme une échappatoire standard.Perl,
1201081048985Non golfé:
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
.$t
est notre terme, que la boucle multipliex
et 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$sine
ou$cosine
, selon que l'index est impair ou pair, et lui ajoute$t
la valeur. La formule magique indique$_&2?-$t:$t
s'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 .
la source
20 20
.1..$n*2-1
, au lieu de1..$n
. Pendant que je suis ici ...$s
est parfaitement bien laissé non initialisé, commeundef
évalué à0
dans 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"x2
conséquence de l'ajout d'une nouvelle ligne de fin.$t*(1-($_&2))
=>$_&2?-$t:$t
.Fortran:
8910912510210198 bytesJ'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*,t
ne 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
read
déclaration.Ungolfed,
la source
C, 120
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
,r
etx
sont implicitement initialisé à zéro, eti
aura une valeur de 1 tant qu'il n'y a pas d' arguments fournis sur la ligne de commande. Malheureusement, parprintf()
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:
Exemple de sortie:
Essayez-le en ligne:
http://ideone.com/URZWwo
la source
Python> = 2.7.3,
186184211200182170 caractèresUn 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é
iciiciEdit: version valide avec toutes les restrictions
Edit2: Changement de l'interpréteur en ligne en ideone.com en raison d'
round
une sortie de fonction non valide dans Python 2.7.1Edit3: 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é
join
par lafor
boucle principale non fonctionnellela source
**
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.20 20
, j'obtiens une sortie-5364.4118142500001
. Pourrait vouloir le fixer à 8 décimales.2.7.1
. Si vous l'exécutez sur ideone.com (Python 2.7.3), cela fonctionne correctement. ideone.com/JsYNNKJavaScript - 114 caractères
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é
la source
s += (l *= x / ++d)
et nons += (l* = x / ++d)
dans le code non golfé.JavaScript (ECMAScript 6 Draft) -
9796 caractèresUne solution récursive:
Production:
la source
no functions
exigences.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
essayez ici .
la source
r
dans la déclaration. Je n'ai pas testé pour voir sifloat
donne la précision requise.float
cela donnerait la précision requise, mais cela fonctionne :) Et bienvenue sur PPCG, user2702245!float
variables? Pourx=5
etn=3
, je reçoissin(x)=10.20833206
etcos(x)=14.54166412
:-( (Intel Core Duo, au cas où vous vous poseriez la question)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:
Production:
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é.
la source
Rubis, 336
Probablement le plus long ici, mais je suis sûr qu'il pourrait être raccourci :(
la source
JavaScript (ES6) - 185 caractères
Utilise une fonction
q
pour factorielle,i
pour l'exponentiation etp
pour effectuer les deuxsin
etcos
. Exécutez sur jsbin.com. Utilise exactement la formule sans aucune modification.EDIT : a changé les
8
décimales en6
décimales. 15 / mai / 14Code non golfé :
la source
JavaScript - 133 caractères
Non golfé
la source
Mathematica, 96 caractères
la source
x,n
me semble-t -il?x n
.Rubis -
160152140 caractèresEn 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.
Edit: Contribution des commentateurs (lire ci-dessous).
la source
p=->x,n{...}
,f=->n{...}
et ainsi de suite, puis utiliser des crochets au lieu de parenthèses à les appeler, commep[x,n-1]
. De plus, je pense quecollect
c'est juste un alias pourmap
, qui est beaucoup plus court, et puisque vous ne mappez qu'un appel membre, vous pouvez le raccourcir engets.split.map &:to_f
.