g o l f a t a n 2

18

Às vezes, é realmente difícil converter coordenadas cartesianas em coordenadas (x,y)polares (r,phi). Enquanto você pode calcular r = sqrt(x^2+y^2)com bastante facilidade, muitas vezes você precisa de alguma distinção de casos no cálculo do ângulo phi, pois arcsin, arccose arctane todas as outras funções trigonométricas ter um co-domínio que cada um só spans metade do círculo.

Em muitos idiomas, existem embutidos para converter coordenadas retangulares em polares, ou pelo menos possuem uma atan2função que - dada (x,y)- calcula o ângulo phi.

Tarefa

Sua tarefa é escrever um programa / função que use duas coordenadas cartesianas (ponto flutuante, e não zero) (x,y)e produza o ângulo polar correspondente phi, onde phideve ser em graus, radianos ou notas (com notas, quero dizer graduados que são 1 / 400 do círculo completo), o que for mais conveniente para você.

O ângulo é medido em orientação positiva, e temos o ângulo zero para (1,0).

Detalhes

Você não pode usar built-ins que calculam o ângulo phidado duas coordenadas, incluindo atan2, rect2polar, argOfComplexNumbere funções similares. No entanto, você pode usar as funções trigonométricas usuais e seus reversos, que levam apenas um argumento. Quaisquer símbolos da unidade são opcionais.

O raio rdeve ser não negativo e phideve estar no intervalo [-360°, 360°](não importa se você produz 270°ou não -90°).

Exemplos

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
fonte
Precisão necessária em rads / graus?
Luis Mendo
Eu diria que precisa de cerca de precisão da máquina, dependendo do que aplicação você usa (float / double / whatever)
flawr
Podemos considerar a entrada como um único número complexo?
Adám

Respostas:

9

MATL , 12 bytes

yYy/X;0G0<?_

O resultado está em radianos.

Experimente online! Ou verifique todos os casos de teste .

Explicação

O MATL não possui uma atanfunção (possui atan2, mas não pode ser usada para esse desafio). Então eu recorri 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
fonte
Matl realmente não tem valor absoluto embutido? Se isso acontecer, você provavelmente poderia usá-lo para substituir 0<?_, raspar fora de alguns bytes
Zwei
2
@Zwei Tem ( |). Mas aqui eu estou mudando sinal do resultado com base no sinal da segunda entrada , y. Além disso, ypode ser 0, então não posso multiplicar pory/abs(y))
Luis Mendo
5

JavaScript (ES6), 50 40 bytes

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

O resultado está em radianos. Edit: Salvo 10 bytes quando notei que é permitido que o resultado esteja entre -90 ° e 270 °. Versão anterior com -Math.PI<=result<Math.PI:

(x,y)=>(Math.atan(y/x)||0)+Math.PI*(x<0)*(y>0||-1)
Neil
fonte
Quais unidades? Por favor, coloque-os na sua resposta.
Solomon Ucko,
Para que serve ||0?
l4m2
@ l4m2 Para o x=y=0caso.
Neil
4

MATLAB / oitava, 24 bytes

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

Isso define uma função anônima que produz o resultado em radianos.

Experimente em ideone .

Luis Mendo
fonte
3

Javascript ES6, 54 bytes

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

Usa radianos.

Mama Fun Roll
fonte
2

Gelatina , 11 bytes (não concorrente)

<0×ØP+÷@ÆṬ¥

A saída é em radianos. Infelizmente, Jelly teve um bug de sinal em seus átomos de divisão, tornando essa resposta não competitiva devido à correção de bug necessária.

Experimente online! ou verifique todos os casos de teste (convertidos em graus).

Como funciona

<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
fonte
A correção de bugs conta como resposta não competitiva? Isso parece estranho. Se o comportamento correto já foi especificado, a correção de bug não deve ser relacionada. (Afinal de contas, quem sabe quantas outras respostas que você fez não concorrentes através da fixação de uma vantagem caso despercebida?)
Mario Carneiro
@MarioCarneiro No PPCG, o intérprete define o idioma . Isso ocorre principalmente porque é difícil julgar intenções (e a maioria dos esolangs realmente não tem uma especificação concisa), enquanto você não pode argumentar com uma implementação. Observe que alterar o intérprete não afeta a validade das respostas mais antigas. Eles só precisam trabalhar em alguma versão publicada do intérprete.
Dennis
Quero dizer que você pode ter alterado o comportamento das respostas mais antigas em algumas informações que não foram tentadas no momento. Como o PPCG lida com casos de teste ruins descobertos após o fato?
Mario Carneiro
Se os casos de teste forem insuficientes, mais casos de teste serão adicionados. São esperadas soluções para todas as entradas válidas, não apenas para os casos de teste em questão. Re: correção de bugs. Meu intérprete só produziu o sinal errado para divisão por 0 ( -1÷0deu em infvez de -inf), por isso é improvável que afete a maioria dos desafios.
Dennis
2

Python 3, 75 67 bytes

8 bytes graças a Dennis.

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

Ideone it!

Freira Furada
fonte
Você tem que escrever ande or?
flawr
O que mais eu posso fazer?
Freira vazada
1
O @flawr Python possui apenas ande or.
Dennis
2
pi*(x<0==y)or atan(y/(hypot(x,y)+x))*2salva alguns bytes.
Dennis
4
@ flawr: &é um operador bit a bit.
vaultah
2

APL (Dyalog Unicode) , 12 10 bytes SBCS de

-2 graças a ngn.

Função de infixo tácito anônimo. Usa a fórmula de alefalpha . Toma xcomo argumento certo e ycomo argumento esquerdo. O resultado é em radianos.

11○∘⍟0J1⊥,

Experimente online!

, concatenar o y ex

0J1⊥ Avalie como dígitos base i (ou seja, y i ¹ + x i ⁰)

 logaritmo natural desse

 então

11○ parte imaginária disso

Adão
fonte
1
tip
ngn
@ngn Obrigado.
Adám
11○∘⍟->12○
NGN
@ngn Você não pode usar…argOfComplexNumber
Adám
oh ... eu vejo, desculpe
ngn
1

Mathematica, 16 bytes

Não tenho certeza se Logé considerado um built-in que calcula o ângulo dado duas coordenadas.

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

Exemplo:

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
alefalpha
fonte
Essa é uma ideia inteligente! Você poderia adicionar um exemplo de como chamar essa função?
flawr
1

linguagem de máquina x86 (Linux de 32 bits), 25 13 bytes (não-concorrente)

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

Para experimentá-lo online , compile o seguinte programa C (não esqueça o -m32sinalizador em 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));
    }
  }
}
teto
fonte
1

J , 10 bytes

Função de infixo tácito anônimo. Usa a fórmula de alefalpha . Toma xcomo argumento à esquerda e ycomo argumento à direita. O resultado é em radianos.

11 o.^.@j.

Experimente online!

j. calcular x+ y× i

@ então

^. logaritmo natural desse

11 o. parte imaginária disso

Adão
fonte
0

Python 3, 65 bytes

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

Isso gera radianos no intervalo [-π/2, 3π/2), equivalente a [-90, 270)graus.

Random832
fonte
0

Axioma, 58 bytes

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

teste (eu uso apenas acos () retorna radiantes)

(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
fonte
0

Python 2 , 59 bytes

lambda x,y:acos(x/hypot(x,y))/(-1,1)[y>0]
from math import*

Experimente online!

Saídas em radianos na faixa [-pi,pi)

Vedant Kandoi
fonte