g o l f a t a n 2


18

A volte è davvero difficile convertire le coordinate cartesiane in coordinate (x,y)polari (r,phi). Mentre puoi calcolare r = sqrt(x^2+y^2)abbastanza facilmente, spesso hai bisogno di una certa distinzione dei casi quando calcoli l'angolo phiperché arcsin, arccose arctane tutte le altre funzioni trigonometriche hanno un co-dominio che si estende solo su metà del cerchio.

In molte lingue ci sono incorporati per convertire le coordinate rettangolari in polari, o almeno hanno una atan2funzione, che - data (x,y)- calcola l'angolo phi.

Compito

Il tuo compito è scrivere un programma / funzione che prende due coordinate cartesiane (in virgola mobile, non entrambe zero) (x,y)e genera l'angolo polare corrispondente phi, dove phideve essere espresso in gradi, radianti o gradi (con gradi intendo gradienti che sono 1 / 400 del cerchio completo), a seconda di quale sia la più conveniente per te.

L'angolo è misurato in orientamento positivo e abbiamo l'angolo zero per (1,0).

Dettagli

E 'vietato utilizzare built-in che calcolano l'angolo phidato due coordinate, tra cui atan2, rect2polar, argOfComplexNumbere funzioni simili. Tuttavia puoi usare le solite funzioni trigonometriche e i loro rovesci, che accettano solo un argomento. Tutti i simboli delle unità sono opzionali.

Il raggio rdeve essere non negativo e phideve essere compreso nell'intervallo [-360°, 360°](non importa se si produce 270°o -90°).

Esempi

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°

Precisione richiesta in rad / gradi?
Luis Mendo,

Direi preciso sulla precisione della macchina, a seconda dell'implementazione che usi (float / double / qualunque)
flawr

Possiamo prendere input come un singolo numero complesso?
Adám,

Risposte:


9

MATL , 12 byte

yYy/X;0G0<?_

Il risultato è in radianti.

Provalo online! Oppure verifica tutti i casi di test .

Spiegazione

MATL non ha una atanfunzione (ha atan2, ma non può essere usato per questa sfida). Quindi ho fatto ricorso 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

Matl non ha davvero alcun valore assoluto incorporato? In tal caso, potresti probabilmente usarlo per rimpiazzarlo 0<?_, radendo alcuni byte
Zwei

2
@Zwei It has ( |). Ma qui sto cambiando segno del risultato in base al segno del secondo ingresso , y. Inoltre, ypuò essere 0, quindi non posso moltiplicare pery/abs(y))
Luis Mendo il

5

JavaScript (ES6), 50 40 byte

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

Il risultato è in radianti. Modifica: salvato 10 byte quando ho notato che è consentito che il risultato sia compreso tra -90 ° e 270 °. Versione precedente con -Math.PI<=result<Math.PI:

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

Quali unità? Per favore, inseriscili nella tua risposta.
Solomon Ucko,

A cosa serve ||0?
l4m2

@ l4m2 Per il x=y=0caso.
Neil,

4

MATLAB / Octave, 24 byte

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

Questo definisce una funzione anonima che produce il risultato in radianti.

Provalo su ideone .


3

Javascript ES6, 54 byte

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

Usa i radianti.


2

Gelatina , 11 byte (non competitiva)

<0×ØP+÷@ÆṬ¥

L'output è in radianti. Sfortunatamente, Jelly aveva un bug di segno nei suoi atomi di divisione, rendendo questa risposta non competitiva a causa della correzione di bug richiesta.

Provalo online! oppure verifica tutti i casi di test (convertiti in gradi).

Come funziona

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

La correzione di bug conta come una risposta non competitiva? Sembra strano. Se era già stato ipotizzato il comportamento corretto, la correzione dovrebbe essere non correlata. (Dopo tutto, chissà quante altre risposte hai reso non competitivo risolvendo un caso limite inosservato?)
Mario Carneiro,

@MarioCarneiro Su PPCG, l'interprete definisce la lingua . Ciò è dovuto principalmente al fatto che è difficile giudicare le intenzioni (e la maggior parte degli esolang non ha una specifica concisa), mentre non si può discutere con un'implementazione. Si noti che la modifica dell'interprete non influisce sulla validità delle risposte precedenti. Devono funzionare solo in alcune versioni pubblicate dell'interprete.
Dennis,

Voglio dire che potresti aver modificato il comportamento delle risposte precedenti su alcuni input che non sono stati tentati al momento. In che modo PPCG gestisce i casi di test errati scoperti dopo il fatto?
Mario Carneiro,

Se i casi di test si rivelano insufficienti, vengono aggiunti altri casi di test. Sono previste soluzioni per tutti gli input validi, non solo per i casi di test nella domanda. Ri: correzione di bug. Il mio interprete ha prodotto solo il segno sbagliato per divisione per 0 ( -1÷0dato infal posto di -inf), quindi è improbabile che possa influenzare la maggior parte delle sfide.
Dennis,


2

APL (Dyalog Unicode) , 12 10 byte SBCS

-2 grazie a ngn.

Funzione anonimo di tacita infissione. Usa la formula di alephalpha . Prende xcome argomento giusto e ycome argomento sinistro. Il risultato è in radianti.

11○∘⍟0J1⊥,

Provalo online!

, concatenare il yex

0J1⊥ Valuta come cifre di base i (ovvero y i ¹ + x i ⁰)

 logaritmo naturale di quello

 poi

11○ parte immaginaria di ciò


1

@ngn Grazie.
Adám,

11○∘⍟->12○
ngn

@ngn Non puoi usare ...argOfComplexNumber
Adám,

oh ... vedo, scusa
ngn

1

Mathematica, 16 byte

Non sono sicuro che Logsia considerato come un built-in che calcola l'angolo dato due coordinate.

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

Esempio:

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

Questa è un'idea intelligente! Potresti aggiungere un esempio come chiamare questa funzione?
flawr

1

linguaggio macchina x86 (Linux a 32 bit), 25 13 byte (non competitivo)

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

Per provarlo online , compila il seguente programma C (non dimenticare -m32flag su 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));
    }
  }
}

1

J , 10 byte

Funzione anonimo di tacita infissione. Usa la formula di alephalpha . Prende xcome argomento sinistro e ycome argomento giusto. Il risultato è in radianti.

11 o.^.@j.

Provalo online!

j. calcola x+ y× i

@ poi

^. logaritmo naturale di quello

11 o. parte immaginaria di ciò




0

Python 3, 65 byte

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

Questo genera radianti nell'intervallo [-π/2, 3π/2), equivalenti a [-90, 270)gradi.


0

Assioma, 58 byte

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

test (uso solo acos () restituisce radianti)

(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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.