g o l f a t a n 2

18

Kadang-kadang itu benar-benar merupakan perjuangan untuk mengubah koordinat Cartesian (x,y)ke koordinat Polar (r,phi). Meskipun Anda dapat menghitung r = sqrt(x^2+y^2)dengan cukup mudah, Anda sering memerlukan beberapa pembedaan kasus ketika menghitung sudut phikarena arcsin, arccosdan arctandan semua fungsi trigonometri lainnya memiliki domain bersama yang masing-masing hanya menjangkau setengah lingkaran.

Dalam banyak bahasa ada built-in untuk mengkonversi koordinat persegi panjang ke kutub, atau setidaknya memiliki atan2fungsi, yang - diberikan (x,y)- menghitung sudut phi.

Tugas

Tugas Anda adalah menulis sebuah program / fungsi yang membutuhkan dua (titik mengambang, bukan nol) koordinat Cartesian (x,y), dan menampilkan sudut kutub yang sesuai phi, di mana phiharus dalam derajat, radian atau nilai (dengan nilai yang saya maksudkan lulusan yang 1 / 400 dari lingkaran penuh), mana yang lebih nyaman bagi Anda.

Sudut diukur dalam orientasi positif, dan kami memiliki sudut nol untuk (1,0).

Detail

Anda tidak dapat menggunakan built-in yang menghitung sudut phidiberikan dua koordinat, termasuk atan2, rect2polar, argOfComplexNumberdan fungsi yang sama. Namun Anda dapat menggunakan fungsi trigonometri biasa dan pengembaliannya, yang hanya membutuhkan satu argumen. Setiap simbol unit adalah opsional.

Jari-jari rharus non-negatif, dan phiharus dalam kisaran [-360°, 360°](tidak masalah apakah Anda output 270°atau -90°).

Contohnya

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°
cacat
sumber
Diperlukan presisi dalam rad / derajat?
Luis Mendo
Saya akan mengatakan akurat tentang presisi alat berat, tergantung pada implementasi apa yang Anda gunakan (float / double / apa pun)
flawr
Bisakah kita mengambil input sebagai bilangan kompleks tunggal?
Adám

Jawaban:

9

MATL , 12 byte

yYy/X;0G0<?_

Hasilnya dalam radian.

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

MATL tidak memiliki atanfungsi (sudah atan2, tetapi tidak dapat digunakan untuk tantangan ini). Jadi saya terpaksa 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
sumber
Apakah matl benar-benar tidak memiliki nilai absolut bawaan? Jika ya, Anda mungkin dapat menggunakannya untuk mengganti 0<?_, memotong beberapa byte
Zwei
2
@ Zwei Memiliki ( |). Tapi di sini saya mengubah tanda hasil berdasarkan tanda masukan kedua , y. Selain itu, ybisa jadi 0, saya tidak bisa mengalikannya dengany/abs(y))
Luis Mendo
5

JavaScript (ES6), 50 40 byte

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

Hasilnya dalam radian. Sunting: Disimpan 10 byte ketika saya perhatikan bahwa hasilnya diperbolehkan antara -90 ° dan 270 °. Versi sebelumnya dengan -Math.PI<=result<Math.PI:

(x,y)=>(Math.atan(y/x)||0)+Math.PI*(x<0)*(y>0||-1)
Neil
sumber
Unit apa? Tolong masukkan ke dalam jawaban Anda.
Solomon Ucko
Untuk apa ini ||0?
14m2
@ l4m2 Untuk x=y=0kasus ini.
Neil
4

MATLAB / Oktaf, 24 byte

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

Ini mendefinisikan fungsi anonim yang menghasilkan hasil dalam radian.

Cobalah di ideone .

Luis Mendo
sumber
3

Javascript ES6, 54 byte

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

Menggunakan radian

Mama Fun Roll
sumber
2

Jelly , 11 byte (tidak bersaing)

<0×ØP+÷@ÆṬ¥

Output dalam radian. Sayangnya, Jelly memiliki bug tanda di atom divisinya, membuat jawaban ini tidak bersaing karena perbaikan bug yang diperlukan.

Cobalah online! atau verifikasi semua kasus uji (dikonversi ke derajat).

Bagaimana itu bekerja

<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
sumber
Apakah perbaikan bug dianggap sebagai jawaban yang tidak bersaing? Sepertinya aneh. Jika perilaku yang benar sudah ditentukan, perbaikan bug seharusnya tidak terkait. (Lagi pula, siapa yang tahu berapa banyak jawaban lain yang Anda buat tidak bersaing dengan memperbaiki kasing yang tidak diketahui?)
Mario Carneiro
@MarioCarneiro Pada PPCG, penerjemah menentukan bahasa . Ini terutama karena sulit untuk menilai niat (dan kebanyakan esolang tidak benar-benar memiliki spesifikasi yang ringkas), sementara Anda tidak dapat berdebat dengan implementasi. Perhatikan bahwa mengubah juru bahasa tidak memengaruhi validitas jawaban yang lebih lama. Mereka hanya perlu bekerja dalam beberapa versi penerjemah yang diterbitkan.
Dennis
Maksud saya, Anda mungkin telah mengubah perilaku jawaban yang lebih lama pada beberapa masukan yang tidak dicoba saat itu. Bagaimana PPCG menangani kasus uji yang buruk ditemukan setelah fakta?
Mario Carneiro
Jika kasus uji terbukti tidak mencukupi, lebih banyak kasus uji ditambahkan. Solusi diharapkan untuk semua input yang valid, bukan hanya kasus uji dalam pertanyaan. Re: perbaikan bug. Penerjemah saya hanya menghasilkan tanda yang salah untuk pembagian dengan 0 ( -1÷0memberi infbukannya -inf), jadi itu tidak mungkin mempengaruhi sebagian besar tantangan.
Dennis
2

Python 3, 75 67 byte

8 byte berkat Dennis.

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

Ide itu!

Biarawati Bocor
sumber
Apakah Anda harus menulis anddan or?
flawr
Apa lagi yang bisa saya lakukan?
Leaky Nun
1
@ flawr Python hanya memiliki anddan or.
Dennis
2
pi*(x<0==y)or atan(y/(hypot(x,y)+x))*2menghemat beberapa byte.
Dennis
4
@ flawr: &adalah operator bitwise.
vaultah
2

APL (Dyalog Unicode) , 12 10 byte SBCS

-2 Terima kasih kepada ngn.

Fungsi infiks diam-diam anonim. Menggunakan formula alephalpha . Dibawa xsebagai argumen kanan dan ysebagai argumen kiri. Hasilnya adalah dalam radian.

11○∘⍟0J1⊥,

Cobalah online!

, menyatukan ydanx

0J1⊥ Evaluasilah sebagai basis i digit (yaitu y i ¹ + x i ⁰)

 logaritma alami itu

 kemudian

11○ bagian imajiner dari itu

Adm
sumber
1
tip
ngn
@ ngn Terima kasih.
Adám
11○∘⍟->12○
ngn
@ngn Anda tidak boleh menggunakan ...argOfComplexNumber
Adám
oh ... saya mengerti, maaf
ngn
1

Mathematica, 16 byte

Saya tidak yakin apakah Logdianggap sebagai built-in yang menghitung sudut yang diberikan dua koordinat.

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

Contoh:

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
sumber
Itu ide yang cerdas! Bisakah Anda menambahkan contoh cara memanggil fungsi ini?
flawr
1

bahasa mesin x86 (Linux 32 bit), 25 13 byte (tidak bersaing)

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

Untuk mencobanya secara online , kompilasi program C berikut (jangan lupa -m32beri tanda pada 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));
    }
  }
}
plafon
sumber
1

J , 10 byte

Fungsi infiks diam-diam anonim. Menggunakan formula alephalpha . Dibawa xsebagai argumen kiri dan ysebagai argumen kanan. Hasilnya adalah dalam radian.

11 o.^.@j.

Cobalah online!

j. menghitung x+ y× i

@ kemudian

^. logaritma alami itu

11 o. bagian imajiner dari itu

Adm
sumber
0

Pyth, 26 byte

AQ?|>G0Hy.tcH+@s^R2Q2G5.n0

theta dalam radian.

Suite uji.

Biarawati Bocor
sumber
0

𝔼𝕊𝕄𝕚𝕟, 13 karakter / 17 byte

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

Try it here (ES6 browsers only).

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

Mama Fun Roll
sumber
0

Python 3, 65 byte

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

Ini menghasilkan radian dalam kisaran [-π/2, 3π/2), setara dengan [-90, 270)derajat.

Random832
sumber
0

Aksioma, 58 byte

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

tes (saya hanya menggunakan acos () mengembalikan radiasi)

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

Python 2 , 59 byte

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

Cobalah online!

Output dalam radian dalam jangkauan [-pi,pi)

Vedant Kandoi
sumber