g o l f a t a n 2

18

Parfois, il est vraiment difficile de convertir les coordonnées cartésiennes en coordonnées (x,y)polaires (r,phi). Alors que vous pouvez calculer r = sqrt(x^2+y^2)assez facilement, il faut souvent une distinction des cas lors du calcul de l'angle phiparce que arcsin, arccoset arctanet toutes les autres fonctions trigonométriques un co-domaine que chaque seulement travées moitié du cercle.

Dans de nombreuses langues, il existe des fonctions intégrées pour convertir des coordonnées rectangulaires en coordonnées polaires, ou au moins ont une atan2fonction qui - compte tenu (x,y)- calcule l'angle phi.

Tâche

Votre tâche consiste à écrire un programme / une fonction qui prend deux coordonnées cartésiennes (virgule flottante, pas les deux nulles) (x,y)et génère l'angle polaire correspondant phi, où phidoit être exprimé en degrés, radians ou grades (avec des grades, je veux dire des gradiens qui sont 1 / 400 du cercle complet), selon ce qui vous convient le mieux.

L'angle est mesuré en orientation positive, et nous avons l'angle zéro pour (1,0).

Détails

Vous ne pouvez pas utiliser Encastrements qui calculent l'angle phidonné deux coordonnées, y compris atan2, rect2polar, argOfComplexNumberet des fonctions similaires. Cependant, vous pouvez utiliser les fonctions trigonométriques habituelles et leurs inverses, qui ne prennent qu'un seul argument. Tous les symboles d'unité sont facultatifs.

Le rayon rdoit être non négatif et phidoit être compris dans la plage [-360°, 360°](peu importe que vous produisiez 270°ou non -90°).

Exemples

Input       Output
(1,1)       45°
(0,3)       90°
(-1,1)      135°
(-5,0)      180°
(-2,-2)     225°
(0,-1.5)    270°
(4,-5)      308.66°
flawr
la source
Précision requise en rads / degrés?
Luis Mendo
Je dirais que la précision de la machine est précise, en fonction de l'implémentation que vous utilisez (flottant / double / peu importe)
flawr
Pouvons-nous prendre la saisie comme un seul numéro complexe?
Adám

Réponses:

9

MATL , 12 octets

yYy/X;0G0<?_

Le résultat est en radians.

Essayez-le en ligne! Ou vérifiez tous les cas de test .

Explication

MATL n'a pas de atanfonction (elle en a atan2, mais elle ne peut pas être utilisée pour ce défi). J'ai donc eu recours à acos.

y     % Take x, y implicitly. Duplicate x onto the top of the stack
Yy    % Compute hypothenuse from x, y
/     % Divide x by hypothenuse
X;    % Arccosine (inverse of cosine function)
0G    % Push y again
0<    % Is it negative?
?_    % If so, change sign. Implicitly end conditional branch. Implicitly display
Luis Mendo
la source
Matl n'a-t-il vraiment pas de valeur absolue intégrée? Si c'est le cas, vous pouvez probablement l'utiliser pour remplacer 0<?_, en rasant quelques octets
Zwei
2
@Zwei Il a ( |). Mais ici je change signe du résultat en fonction du signe de la seconde entrée , y. En plus, ypeut l'être 0, donc je ne peux pas multiplier pary/abs(y))
Luis Mendo
5

JavaScript (ES6), 50 40 octets

(x,y)=>(Math.atan(y/x)||0)+Math.PI*(x<0)

Le résultat est en radians. Edit: J'ai sauvé 10 octets quand j'ai remarqué qu'il était permis que le résultat soit entre -90 ° et 270 °. Version précédente avec -Math.PI<=result<Math.PI:

(x,y)=>(Math.atan(y/x)||0)+Math.PI*(x<0)*(y>0||-1)
Neil
la source
Quelles unités? Veuillez les mettre dans votre réponse.
Solomon Ucko
À quoi ça ||0sert?
l4m2
@ l4m2 Pour le x=y=0cas.
Neil
4

MATLAB / Octave, 24 octets

@(x,y)atan(y/x)+pi*(x<0)

Ceci définit une fonction anonyme qui produit le résultat en radians.

Essayez-le sur ideone .

Luis Mendo
la source
3

Javascript ES6, 54 octets

(x,y,m=Math)=>x<0&!y?m.PI:m.atan(y/(m.hypot(x,y)+x))*2

Utilise des radians.

Mama Fun Roll
la source
2

Gelée , 11 octets (non concurrent)

<0×ØP+÷@ÆṬ¥

La sortie est en radians. Malheureusement, Jelly avait un bogue de signe dans ses atomes de division, rendant cette réponse non compétitive en raison de la correction de bogue requise.

Essayez-le en ligne! ou vérifiez tous les cas de test (convertis en degrés).

Comment ça fonctionne

<0×ØP+÷@ÆṬ¥  Main link. Left argument x. Right argument: y

<0           Compare x with 0.
  ×ØP        Multiply the resulting Boolean by Pi.
          ¥  Combine the two links to the left into a dyadic chain.
      ÷@     Divide y by x.
        ÆṬ   Apply arctan to the result.
     +       Add the results to both sides.
Dennis
la source
La correction de bugs compte-t-elle comme une réponse non concurrente? Cela semble étrange. Si le comportement correct a déjà été spécifié, le correctif doit être indépendant. (Après tout, qui sait combien d'autres réponses vous avez apportées sans concurrencer en corrigeant un cas de bord inaperçu?)
Mario Carneiro
@MarioCarneiro Sur PPCG, l'interpréteur définit la langue . C'est principalement parce qu'il est difficile de juger des intentions (et la plupart des esolangs n'ont pas vraiment de spécifications concises), alors que vous ne pouvez pas discuter d'une implémentation. Notez que la modification de l'interpréteur n'affecte pas la validité des réponses plus anciennes. Ils n'ont qu'à travailler dans une version publiée de l'interprète.
Dennis
Je veux dire que vous avez peut-être changé le comportement des réponses plus anciennes sur une entrée qui n'a pas été tentée à l'époque. Comment PPCG gère-t-il les cas de test défectueux découverts après coup?
Mario Carneiro
Si les cas de test s'avèrent insuffisants, d'autres cas de test sont ajoutés. Des solutions sont attendues pour toutes les entrées valides, pas seulement les cas de test dans la question. Re: correction de bogue. Mon interprète n'a produit que le mauvais signe de division par 0 ( -1÷0donné infau lieu de -inf), il est donc peu probable qu'il affecte la plupart des défis.
Dennis
2

Python 3, 75 67 octets

8 octets grâce à Dennis.

from math import*
lambda x,y:pi*(x<0==y)or atan(y/(hypot(x,y)+x))*2

Ideone it!

Leaky Nun
la source
Devez-vous écrire andet or?
flawr
Que puis-je faire d'autre?
Leaky Nun
1
@flawr Python n'a que andet or.
Dennis
2
pi*(x<0==y)or atan(y/(hypot(x,y)+x))*2enregistre quelques octets.
Dennis
4
@flawr: &est un opérateur au niveau du bit.
vaultah
2

APL (Dyalog Unicode) , 12 10 octets SBCS

-2 grâce à ngn.

Fonction infixe tacite anonyme. Utilise la formule d'alephalpha . Prend xcomme argument de droite et ycomme argument de gauche. Le résultat est en radians.

11○∘⍟0J1⊥,

Essayez-le en ligne!

, concaténer le yetx

0J1⊥ Évaluer en tant que chiffres de base i (c'est-à-dire y i ¹ + x i ⁰)

 logarithme naturel de cette

 ensuite

11○ une partie imaginaire de cela

Adam
la source
1
astuce
ngn
@ngn Merci.
Adám
11○∘⍟->12○
ngn
@ngn Vous ne pouvez pas utiliser…argOfComplexNumber
Adám
oh ... je vois, désolé
ngn
1

Mathematica, 16 octets

Je ne sais pas si Logest considéré comme un intégré qui calcule l'angle à partir de deux coordonnées.

N@Im@Log[#+I#2]&

Exemple:

In[1]:= N@Im@Log[#+I#2]&[1,1]

Out[1]= 0.785398

In[2]:= N@Im@Log[#+I#2]&[4,-5]

Out[2]= -0.896055
alephalpha
la source
Voilà une idée intelligente! Pourriez-vous ajouter un exemple comment appeler cette fonction?
flawr
1

Langage machine x86 (Linux 32 bits), 25 13 octets (sans concurrence)

0:       55                      push   %ebp
1:       89 e5                   mov    %esp,%ebp
3:       dd 45 08                fldl   0x8(%ebp)
6:       dd 45 10                fldl   0x10(%ebp)
9:       d9 f3                   fpatan  
b:       c9                      leave
c:       c3                      ret

Pour l' essayer en ligne , compilez le programme C suivant (n'oubliez pas l' -m32indicateur sur x86_64)

#include<stdio.h>
#include<math.h>
const char j[]="U\x89\xe5\335E\b\335E\20\xd9\xf3\xc9\xc3";
int main(){
  for(double f=-1;f<1;f+=.1){
    for(double g=-1;g<1;g+=.1){
      printf("%.2f %.2f %f %f\n",f,g,atan2(f,g),((double(*)(double,double))j)(f,g));
    }
  }
}
plafond
la source
1

J , 10 octets

Fonction infixe tacite anonyme. Les usages la formule d'alephalpha . Prend xcomme argument de gauche et ycomme argument de droite. Le résultat est en radians.

11 o.^.@j.

Essayez-le en ligne!

j. calculer x+ y× i

@ ensuite

^. logarithme naturel de cette

11 o. une partie imaginaire de cela

Adam
la source
0

𝔼𝕊𝕄𝕚𝕟, 13 caractères / 17 octets

î<0)*π+МǍ í/î

Try it here (ES6 browsers only).

Utilise (x<0)*pi+tan(y/x).

Mama Fun Roll
la source
0

Python 3, 65 octets

from math import*
f=lambda x,y:atan(y/x if x else y*inf)+pi*(x<0)

Cela produit des radians dans la plage [-π/2, 3π/2), équivalant à des [-90, 270)degrés.

Aléatoire832
la source
0

Axiome, 58 octets

f(a,b)==(a=0 and b=0=>%i;sign(b)*acos(a*1./sqrt(a^2+b^2)))

test (j'utilise uniquement acos () il renvoie des radiants)

(40) -> [[a,b,f(a,b)*180/%pi] for a in [1,0,-1,-5,-2,0,4] for b in [1,3,1,0,-2,-1.5,-5] ]
   (40)
   [[1.0,1.0,45.0], [0.0,3.0,90.0], [- 1.0,1.0,135.0], [- 5.0,0.0,180.0],
    [- 2.0,- 2.0,- 135.0], [0.0,- 1.5,- 90.0],
    [4.0,- 5.0,- 51.3401917459 09909396]]
                                            Type: List List Complex Float
RosLuP
la source