g o l f a t a n 2

18

Czasami naprawdę trudno jest przekonwertować współrzędne kartezjańskie na współrzędne (x,y)biegunowe (r,phi). Chociaż można obliczyć r = sqrt(x^2+y^2)dość łatwo, często trzeba jakieś rozróżnienie przypadków przy obliczaniu kąta phiponieważ arcsin, arccosi arctanwszystkie inne funkcje trygonometryczne mają współpracę domenę że każdy tylko przęseł pół okręgu.

W wielu językach są wbudowane atan2funkcje przekształcania współrzędnych prostokątnych na biegunowe lub przynajmniej mają funkcję, która - biorąc pod uwagę (x,y)- oblicza kąt phi.

Zadanie

Twoim zadaniem jest napisanie programu / funkcji, która przyjmuje dwie (zmiennoprzecinkowe, nie oba zerowe) współrzędne kartezjańskie (x,y)i generuje odpowiedni kąt biegunowy phi, gdzie phimusi być w stopniach, radianach lub stopniach (za stopniami mam na myśli gradianów, które są 1 / 400 pełnego koła), w zależności od tego, które jest dla Ciebie wygodniejsze.

Kąt jest mierzony w dodatniej orientacji, a my mamy kąt zerowy dla (1,0).

Detale

Użytkownik nie może używać Zabudowy że obliczenie kąta phipodane dwie współrzędne, włącznie z atan2, rect2polar, argOfComplexNumberi podobne funkcje. Można jednak użyć zwykłych funkcji trygonometrycznych i ich odwrotności, które wymagają tylko jednego argumentu. Wszelkie symbole jednostek są opcjonalne.

Promień rmusi być nieujemny i phimusi mieścić się w zakresie [-360°, 360°](nie ma znaczenia, czy dane wyjściowe 270°czy -90°).

Przykłady

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°
wada
źródło
Wymagana precyzja w radach / stopniach?
Luis Mendo
Powiedziałbym dokładnie o precyzji maszyny, w zależności od tego, jakiej implementacji używasz (float / double / cokolwiek)
flawr
Czy możemy przyjmować dane wejściowe jako pojedynczą liczbę zespoloną?
Adám

Odpowiedzi:

9

MATL , 12 bajtów

yYy/X;0G0<?_

Wynik jest w radianach.

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie

MATL nie ma atanfunkcji (ma atan2, ale nie można jej użyć do tego wyzwania). Więc uciekłem się do 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
źródło
Czy Matl naprawdę nie ma wbudowanej wartości bezwzględnej? Jeśli tak, prawdopodobnie można go użyć do zastąpienia 0<?_, goląc kilka bajtów
Zwei,
2
@Zwei It has ( |). Ale tu mam zmieniając znak wyniku opartej na znak drugiego wejścia , y. Poza tym ymoże być 0, więc nie mogę pomnożyć przezy/abs(y))
Luis Mendo
5

JavaScript (ES6), 50 40 bajtów

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

Wynik jest w radianach. Edycja: Zapisałem 10 bajtów, gdy zauważyłem, że wynik może wynosić od -90 ° do 270 °. Poprzednia wersja z -Math.PI<=result<Math.PI:

(x,y)=>(Math.atan(y/x)||0)+Math.PI*(x<0)*(y>0||-1)
Neil
źródło
Jakie jednostki? Proszę podać je w swojej odpowiedzi.
Solomon Ucko
Co to jest ||0za?
l4m2
@ l4m2 W x=y=0przypadku.
Neil,
4

MATLAB / Octave, 24 bajty

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

Definiuje to anonimową funkcję, która daje wynik w radianach.

Wypróbuj na ideone .

Luis Mendo
źródło
3

JavaScript ES6, 54 bajty

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

Korzysta z radianów.

Mama Fun Roll
źródło
2

Galaretka , 11 bajtów (niekonkurencyjna)

<0×ØP+÷@ÆṬ¥

Dane wyjściowe podano w radianach. Niestety, Jelly miał błąd znakowy w atomach podziału, przez co odpowiedź ta nie była konkurencyjna z powodu wymaganej poprawki błędu.

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe (przeliczone na stopnie).

Jak to działa

<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
źródło
Czy poprawianie błędów liczy się jako niezgodność odpowiedzi? To wydaje się dziwne. Jeśli określono już prawidłowe zachowanie, poprawka błędu powinna być niezwiązana. (W końcu, kto wie, ile innych odpowiedzi udzieliłeś niekonkurencji, naprawiając niezauważony przypadek na krawędzi?)
Mario Carneiro,
@MarioCarneiro W PPCG interpreter definiuje język . Wynika to głównie z tego, że trudno jest ocenić intencje (a większość esolangów tak naprawdę nie ma zwięzłej specyfikacji), podczas gdy nie można kłócić się z implementacją. Pamiętaj, że zmiana interpretera nie wpływa na ważność starszych odpowiedzi. Muszą pracować tylko w niektórych opublikowanych wersjach tłumacza.
Dennis
Mam na myśli to, że mogłeś zmienić zachowanie starszych odpowiedzi przy niektórych danych wejściowych, których w tym czasie nie próbowano. Jak PPCG obsługuje złe przypadki testowe odkryte po fakcie?
Mario Carneiro,
Jeśli przypadki testowe okażą się niewystarczające, dodaje się więcej przypadków testowych. Oczekuje się rozwiązań dla wszystkich ważnych danych wejściowych, nie tylko przypadków testowych w pytaniu. Re: naprawa błędu. Mój tłumacz przedstawił tylko niewłaściwy znak podziału przez 0 ( -1÷0podany infzamiast -inf), więc jest mało prawdopodobne, aby wpłynęło to na większość wyzwań.
Dennis
2

Python 3, 75 67 bajtów

8 bajtów dzięki Dennisowi.

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

Ideone to!

Leaky Nun
źródło
Czy musisz napisać andi or?
flawr
Co jeszcze mogę zrobić?
Leaky Nun
1
@flawr Python ma tylko andi or.
Dennis
2
pi*(x<0==y)or atan(y/(hypot(x,y)+x))*2oszczędza kilka bajtów.
Dennis
4
@flawr: &jest operatorem bitowym.
vaultah
2

APL (Dyalog Unicode) , 12 10 bajtów SBCS

-2 dzięki ngn.

Anonimowa funkcja ukrytej poprawki. Wykorzystuje formułę Alephalpha . Przyjmuje xjako prawy argument i ylewy argument. Wynik w radianach.

11○∘⍟0J1⊥,

Wypróbuj online!

, połączyć yix

0J1⊥ Oblicz jako podstawowe cyfry i (tj. Y i ¹ + x i ⁰)

 logarytm naturalny tego

 następnie

11○ wymyślona część tego

Adám
źródło
1
wskazówka
ngn
@ngn Dziękuję.
Adám
11○∘⍟->12○
ngn
@ngn Nie możesz używać…argOfComplexNumber
Adám
och ... rozumiem, przepraszam
ngn
1

Mathematica, 16 bajtów

Nie jestem pewien, czy Logjest uważany za wbudowany, który oblicza kąt na podstawie dwóch współrzędnych.

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

Przykład:

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
źródło
To sprytny pomysł! Czy możesz dodać przykład, jak wywołać tę funkcję?
flawr
1

język maszynowy x86 (32-bitowy system Linux), 25 13 bajtów (niekonkurencyjny)

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

Aby wypróbować online , skompiluj następujący program C (nie zapomnij -m32flagi na 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));
    }
  }
}
sufitowy
źródło
1

J , 10 bajtów

Anonimowa funkcja ukrytej poprawki. Wykorzystuje formułę Alephalpha . Przyjmuje xjako lewy argument i yprawy argument. Wynik w radianach.

11 o.^.@j.

Wypróbuj online!

j. obliczyć x+ y× i

@ następnie

^. logarytm naturalny tego

11 o. wymyślona część tego

Adám
źródło
0

𝔼𝕊𝕄𝕚𝕟, 13 znaków / 17 bajtów

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

Try it here (ES6 browsers only).

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

Mama Fun Roll
źródło
0

Python 3, 65 bajtów

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

Daje to w radianach zakres [-π/2, 3π/2)odpowiadający [-90, 270)stopniom.

Losowo 832
źródło
0

Aksjomat, 58 bajtów

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

test (używam tylko acos () zwraca promienie)

(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
źródło