ระยะห่างระหว่างสองจุดที่เดินทางบนกราฟกราฟขั้วโลก


23

คำอธิบายปัญหาโดยย่อ

เขียนโปรแกรมเพื่อค้นหาระยะห่างต่ำสุดระหว่างจุดสองจุดที่เดินทางบนแสงที่เปล่งออกมาจากแหล่งกำเนิดและวงกลมที่อยู่กึ่งกลางแหล่งกำเนิด

คำอธิบายของสถ

ทีนี้ลองจินตนาการว่าเราอยู่บนเครื่องบินและบนเครื่องบินนี้เราได้รับอนุญาตให้เดินทางด้วยวิธีพิเศษเท่านั้น เราได้รับอนุญาตให้เดินทางกับรังสีใด ๆ ที่เล็ดลอดออกมาจากแหล่งกำเนิด

รังสีที่เราสามารถเดินทางต่อไป

เราสามารถเดินทางบนวงกลมใดก็ได้ที่อยู่ตรงกลางเป็นวงกลม

แวดวงที่เราสามารถเดินทางได้

ตอนนี้เป้าหมายของเราคือการเดินทางจากจุดหนึ่งบนเครื่องบินลำนี้ไปอีกจุดหนึ่ง อย่างไรก็ตามเราไม่สามารถเดินทางในเส้นทางแบบยุคลิดอย่างง่ายเราสามารถทำสิ่งนี้ได้ก็ต่อเมื่อจุดที่เกิดขึ้นตกกระทบกับรังสีจากจุดศูนย์กลาง

ป้อนคำอธิบายรูปภาพที่นี่

เราสามารถเดินทางกับอันนี้เพราะมันตกอยู่บนหนึ่งในรังสีของเรา

ป้อนคำอธิบายรูปภาพที่นี่

นอกจากนี้เรายังสามารถเดินทางบนวงกลมที่มีศูนย์กลางที่จุดกำเนิด

ป้อนคำอธิบายรูปภาพที่นี่

ตัวอย่าง

นี่คือความท้าทาย:

เราต้องได้จากจุดหนึ่งไปอีกจุดหนึ่งในเส้นทางที่สั้นที่สุด; บ่อยครั้งที่นี่คือการรวมกันของการเดินทางในวงกลมและรังสี

ป้อนคำอธิบายรูปภาพที่นี่

อย่างไรก็ตามนี่มันอาจเดินทางด้วยรังสีสองดวง

ป้อนคำอธิบายรูปภาพที่นี่

บางครั้งมีสองเส้นทางที่เดินทางในระยะทางต่ำสุด

ป้อนคำอธิบายรูปภาพที่นี่

ปัญหา

ความท้าทายของคุณคือการเขียนโปรแกรมที่เมื่อได้รับสองคะแนนจะให้ระยะห่างขั้นต่ำระหว่างพวกเขาหากเราปฏิบัติตามกฎเหล่านี้ อินพุตสามารถกำหนดได้ทั้งในรูปแบบสี่เหลี่ยมหรือโพลาร์และเอาต์พุตควรเป็นหนึ่งหมายเลขคือระยะห่างระหว่าง

กรณีทดสอบ

(พร้อมอินพุตสี่เหลี่ยมผืนผ้า)

(1,1) (1,-1) -> ~ 2.22144
(0,0) (1, 1) -> ~ 1.41421
(1,0) (-0.4161 , 0.90929) -> ~ 2
(1,1) (1, 0) -> ~ 1.19961
(1,2) (3, 4) -> ~ 3.16609

ตัวอย่างทดสอบเป็นแบบสี่เหลี่ยมผืนผ้าหรือขั้วหรือไม่? ด้วย:
bewteen

พวกเขาอยู่ในรูปสี่เหลี่ยมฉันควรอธิบายว่า
Ando Bando

ตัวอย่างสุดท้ายถูกต้องหรือไม่ ฉันได้รับ ~ 3.166
59

6
@ Peter Taylor เพราะพวกเขาไม่ได้เป็นเส้นทางเดียวกัน ในทำนองเดียวกันเส้นทางจาก 0,0 ถึง 1,1 บนระนาบ xy ผ่านขั้นตอนเล็ก ๆ ที่สลับกันในทิศทาง x และ y จะปรากฏเหมือนกับเส้นทางแนวทแยงมุมตรงเมื่อความยาวก้าวมีแนวโน้มเป็นศูนย์ แต่เส้นทางในแนวทแยงมีความยาว sqrt (2) ในขณะที่ขั้นตอนเส้นทางจะมีความยาว 2
Penguino

1
ฉันคิดว่าความท้าทายจะดูดีขึ้นถ้าภาพไม่ใหญ่มาก ขณะนี้พวกเขาทำให้ยากต่อการติดตามข้อความ
Luis Mendo

คำตอบ:


5

Haskell, 49 48 ไบต์

(a!q)c r=min(q+r)$abs(q-r)+acos(cos$a-c)*min q r

การใช้งาน:

> let rect2polar (x,y)=(atan2 y x, sqrt(x^2+y^2))
> let test c1 c2=let [(a1,r1),(a2,r2)]=rect2polar<$>[c1,c2] in (a1!r1)a2 r2
> test (1,0) (-0.4161, 0.90929)
1.9999342590038496

ขอบคุณ @Zgarb สำหรับการบันทึกไบต์


คุณสามารถบันทึกไบต์โดยกำหนดแทน(a!q)c r d a q c r
Zgarb

4

JavaScript (ES6), 65 ไบต์

with(Math)(r,t,s,u,v=acos(cos(t-u)))=>v<2?abs(r-s)+v*min(r,s):r+s

ใช้พิกัดเชิงขั้ว ใช้เคล็ดลับ @Angs เพื่อลดมุมระหว่าง 0 ถึงπ สำหรับพิกัดรูปสี่เหลี่ยมผืนผ้าบางอย่างเช่นนี้ทำงาน:

with(Math)g=(r,t,s,u,v=acos(cos(t-u)))=>v<2?abs(r-s)+v*min(r,s):r+s
with(Math)f=(x,y,v,w)=>g(hypot(y,x),atan2(y,x),hypot(w,v),atan2(y,v))

3

MATL , 22 ไบต์

|ttsGZ}/X/bX<*|bd|+hX<

อินพุตเป็นอาร์เรย์ของจำนวนเชิงซ้อนสองจำนวน

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย

|       % Implicitly input array and take absolute value of its entries
tt      % Duplicate twice
s       % Sum. This is the length of the path that follows the two radii
GZ}     % Push input again and split into the two numbers
/X/     % Divide and compute angle. This gives the difference of the angles
        % of the two points, between -pi and pi
bX<     % Bubble up a copy of the array of radii and compute minimum
*|      % Multiply and take absolute value. This is the arc part of the
        % path that follows one arc and the difference of radii
bd|     % Bubble up a copy of the array of radii and compute absolute
        % difference. This is the other part of the second path
+       % Add. This gives the length of second path
hX<     % Concatenate and take minimum to produce the smallest length.
        % Implicitly display

2

Ruby, 64 ไบต์

ก่อนส่งของฉัน distance 1, angle 1, distance 2, angle2ฟังก์ชั่นแลมบ์ดามีข้อโต้แย้ง

->r,a,s,b{([d=(b-a).abs,?i.to_c.arg*4-d,2].min-2)*[r,s].min+s+r}

ทีนี้นี่คือทางออกที่แตกต่างกันสองทาง 66 ไบต์ (ไม่รวมการมอบหมายf=) ตามด้วยการส่งจริงของฉันอีกครั้งที่ 64 ไบต์

Solution 1:Using include Math, 66 bytes excluding f=
include Math;f=->r,a,s,b{[acos(cos(b-a)),2].min*[r,s].min+(s-r).abs}

Solution 2:Using complex number to define PI instead, 66 bytes excluding f=
f=->r,a,s,b{[d=(b-a).abs,?i.to_c.arg*4-d,2].min*[r,s].min+(s-r).abs}

SUBMISSION AGAIN, 64 bytes excluding f=
f=->r,a,s,b{([d=(b-a).abs,?i.to_c.arg*4-d,2].min-2)*[r,s].min+s+r}

การส่งจะขึ้นอยู่กับโซลูชัน 2 แต่ใช้ identity (s-r).abs= s+r-[s,r].min*2เพื่อทำให้รหัสสั้นลง 2 ไบต์ดังนั้นจึง-2อยู่ในวงเล็บ

คุณสมบัติเด่นอื่น ๆ คือการแสดงออก?i.to_c.arg*4= 2 * PI include Mathโดยไม่ต้องใช้ หากความแม่นยำต่ำกว่าเป็นที่ยอมรับสามารถเปลี่ยนได้ด้วยตัวอักษร

โซลูชันที่ 2 แสดงความคิดเห็นในโปรแกรมทดสอบ

f=->r,a,s,b{          #r,s are distances, a,b are angles for points 1 and 2 respectively.                       
    [d=(b-a).abs,       #From nearer point we can take arc of length d radians perhaps crossing zero angle to the ray of the further point
    ?i.to_c.arg*4-d,    #or go the other way round which may be shorter (?i.to_c.arg*4 == 2*PI, subtract d from this.)
    2].min*             #or go through the centre if the angle exceeds 2 radians.
  [r,s].min+          #Multiply the radians by the distance of the nearer point from the origin to get the distance travelled. 
  (s-r).abs           #Now add the distance to move along the ray out to the further point.
}

#test cases per question (given as complex numbers, converted to arrays of [distance,angle]+[distance,angle] (+ concatenates.)
#the "splat" operator * converts the array to 4 separate arguments for the function.
p f[*("1+i".to_c.polar + "1-i".to_c.polar)]
p f[*("0".to_c.polar + "1+i".to_c.polar)]
p f[*("1".to_c.polar + "-0.4161+0.90929i".to_c.polar)]
p f[*("1+i".to_c.polar + "1".to_c.polar)]
p f[*("1+2i".to_c.polar + "3+4i".to_c.polar)]

เอาท์พุต

2.221441469079183
1.4142135623730951
1.9999342590038496
1.1996117257705434
3.1660966740274357

2

Mathematica 66 Bytes

การทำเช่นนี้ต้องใช้พิกัดสี่เหลี่ยมและสามารถแสดงผลโซลูชันสัญลักษณ์ที่แน่นอนได้

Min[If[(m=Min[{p,q}=Norm/@#])>0,m*VectorAngle@@#,0]+Abs[p-q],p+q]&

การใช้งาน:

%/@{
{{1,1},{1,-1}},
{{0,0},{1,1}},
{{1,0},{-.4161,.90929}},
{{1,1},{1,0}},
{{1,2},{3,4}}
}

อัตราผลตอบแทน: ผลสัญลักษณ์

N @% ผลตอบแทน:

{2.221441469, 1.414213562, 1.999934259, 1.199611726, 3.166096674}


1
Nifty! หากคุณกำลังใช้เส้นทางสัญลักษณ์คุณสามารถแทนที่กรณีทดสอบ {1,0} {-. 4161, .90929} ด้วย {1,0} {cos (2), บาป (2)}
Ando Bando

1

Python 2, 164 126 125 132 ไบต์:

def A(a,b,c,d,p=3.1415926535):z=abs(a-c);M=lambda f:2*p*f*abs(b-d)/360.0;print min((a==c)*min(a+c,M(a))+(b==d)*z or'',M(a)+z,M(c)+z)

แม้ว่าตอนนี้ฉันกำลังมองหาการเล่นกอล์ฟมากกว่านี้ ยอมรับพิกัดเชิงขั้ว A(r1,θ1,r2,θ2)ควรจะเรียกว่าในรูปแบบ ส่งออกค่าทศนิยมที่ถูกต้องจนถึง12ตัวเลขที่สำคัญ

ลองออนไลน์! (Ideone)

การใช้งานที่เรียบง่ายตรงไปตรงมาซึ่งคำนวณและส่งออกไปยัง STDOUT เป็นค่าต่ำสุดของอาร์เรย์ที่มีค่าไม่เกิน 3 ค่าที่ประกอบด้วย:

  1. ค่าต่ำสุดจากผลรวมของความยาวทั้งสอง ( r1+r2) หรือความยาวของส่วนโค้งที่เชื่อมต่อสองจุดiff r1==r2 ;
  2. ความแตกต่างระหว่างสองระยะทาง ( abs(r1-r2)) iff θ1==θ2 (เช่นสองจุดคือ collinear);
  3. หากไม่มีการเพิ่มรายการ 2 รายการก่อนหน้านี้สตริงว่างเปล่า ( '') ตามที่ปรากฏใน Python สตริงจะมากกว่าจำนวนเต็มใด ๆ
  4. และ 2 ค่าสุดท้ายที่ได้จากระยะทางที่เดินทางตามวงกลมและรังสีและในทางกลับกันระหว่างสองจุด

ทำไมไม่math.pi?
user202729

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.