รหัสกอล์ฟจำลองสนามกอล์ฟ


13

รับรายการของระยะหลุมขนาดสีเขียวมุมชิ้นและระยะทางสูงสุดคำนวณคะแนนกอล์ฟ

สมมติฐาน

  • โลกแบน
  • ผักใบเขียวทั้งหมดเป็นวงกลม
  • มุมสไลซ์จะอยู่ระหว่าง -45 ถึง 45 องศาและจะได้รับเป็นองศา
  • ระยะทางทั้งหมดในตัวชี้วัดเดียวกัน (หลาหรือเมตรไม่สำคัญ)
  • ไม่มีขอบเขตสิ่งกีดขวางหรือ doglegs
  • คะแนนสูงสุดในหลุมใด ๆ คือ 8
  • ทุกช็อตจะเคลื่อนที่ไปในระยะที่น้อยกว่าหรือระยะทางสูงสุดไปยังรูในทิศทางที่กำหนดโดยมุมไปยังรูบวกกับมุมของชิ้น
  • ระยะทางถูกวัดเป็นเส้นตรงหรือระยะทางแบบยุคลิดระหว่างจุดเริ่มต้นและจุดสิ้นสุด
  • ระยะทางสูงสุดและมุมชิ้นจะเท่ากันสำหรับทุกช็อตในทุกหลุม
  • นักกอล์ฟสองพัตหนึ่งครั้งบนกรีน (หรือที่ขอบกรีน)

ตัวอย่าง

ลองดูที่แฮ็กเกอร์จากกรณีทดสอบ # 5 ด้านล่างเพื่อหารู # 2 แฮ็กเกอร์สามารถตีลูกบอลได้ 320 หลา แต่จะแบ่ง 30 องศาเสมอ หากเราสมมติโดยไม่สูญเสียความคิดทั่วไปว่ากล่องทีออฟอยู่ที่ {0,0} และกรีนอยู่ที่ {497,0} จากนั้นเขาจะตีช็อตไปยังจุดต่อไปนี้มาถึงกรีนด้วยช็อตที่ 7:

{{0.,0.},{277.128,-160.},{547.543,-131.372},{569.457,7.67088},{502.872,37.2564},{479.159,7.92741},{490.646,-7.85868},{500.078,-4.22987}}

เมื่อมาถึงจุดนี้คะแนนของเขาจะเป็น 9 เนื่องจากทั้งสองพัตต์ที่ต้องการดังนั้นคะแนนสุดท้ายสำหรับเขาจะต่อยอดที่ 8 ตามสมมติฐาน

กราฟิกมันจะมีลักษณะเช่นนี้: ป้อนคำอธิบายรูปภาพที่นี่

กรณีทดสอบ

กรณีทดสอบทั้งหมดมีหลักสูตร 18 หลุมมาตรฐาน

Case#1
{MaxDistance->280,SliceAngle->10,HoleDistances->{181,368,161,416,158,526,377,427,509,148,405,443,510,494,396,388,483,172},GreenDiameters->{26,18,17,23,27,23,21,23,25,21,19,24,21,23,25,24,22,22}}
Scores: 
{4,5,4,5,4,5,5,5,5,4,5,5,5,5,5,5,5,4}
Output: 85

Case#2 (same course as Test Case #1, shorter more accurate golfer)
{MaxDistance->180,SliceAngle->5,HoleDistances->{181,368,161,416,158,526,377,427,509,148,405,443,510,494,396,388,483,172},GreenDiameters->{26,18,17,23,27,23,21,23,25,21,19,24,21,23,25,24,22,22}}
Scores:
{4,5,4,5,4,6,5,5,6,4,5,5,6,6,5,5,5,4}
Output: 89

Case#3 (Same golfer as test case #1, shorter course)
{MaxDistance->280,SliceAngle->10,HoleDistances->{147,497,110,528,409,118,196,154,134,514,374,491,131,138,523,478,481,494},GreenDiameters->{32,16,36,25,32,20,30,30,33,29,25,26,26,25,33,28,21,28}}
Scores:
{4,5,4,5,5,4,4,4,4,5,5,5,4,4,5,5,5,5}
Output: 82

Case#4 (Same course as test case #3)
{MaxDistance->180,SliceAngle->5,HoleDistances->{147,497,110,528,409,118,196,154,134,514,374,491,131,138,523,478,481,494},GreenDiameters->{32,16,36,25,32,20,30,30,33,29,25,26,26,25,33,28,21,28}}
Scores:
{3,6,3,6,5,4,4,3,3,5,5,5,3,3,5,5,6,5}
Output: 79

Case#5 (Hacker)
{MaxDistance->320,SliceAngle->30,HoleDistances->{147,497,110,528,409,118,196,154,134,514,374,491,131,138,523,478,481,494},GreenDiameters->{32,16,36,25,32,20,30,30,33,29,25,26,26,25,33,28,21,28}}
Scores:
{6,8,5,8,7,6,6,6,6,8,8,8,6,6,8,8,8,8}
Output: 126

กฎระเบียบ

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

5
ทำไม "โลกแบน" ภายใต้สมมติฐาน?
Jo King

เราสามารถสันนิษฐานได้หรือไม่ว่าจะใช้เวลาไม่เกิน 6 ช็อตในการส่งบอลเข้าไปในMaxDistanceหลุม
ETHproductions

1
@ โจกิ้งเป็นส่วนใหญ่ดังนั้นจึงใช้ระนาบแทนเรขาคณิตทรงกลม ประการที่สองเพราะไม่มีความจำเป็นที่จะถือว่าไก่ทรงกลม :)
เคลลี่ Lowder

@ ETHproductions คุณทำได้ดี แต่ไม่จำเป็น ฉันคิดว่าบางทีคุณอาจหมายถึงGreenDiameter/2ในกรณีที่ใช่เนื่องจากคะแนนถูกปกคลุมที่ 8 และมี 2 พัตเสมอ
Kelly Lowder

ไม่ต้องกังวลฉันถามคำถามนี้ว่าฉันหมายถึงมันอย่างไร ;-) เทคนิคของฉันที่ใช้ในเรื่องนี้ดูเหมือนจะไม่ใกล้เคียงกับคำตอบปัจจุบันของฉันดังนั้นอย่าคิดว่าฉันจะเดา ...
ETHproductions

คำตอบ:


10

JavaScript (ES7), 128 126 ไบต์

(m,a,D,S,t=0)=>S.map((s,i)=>t+=(r=(f=d=>d>s/2?1+f((l=d<m?d:m,l*l+d*d-2*d*l*Math.cos(a*Math.PI/180))**.5,s):2)(D[i]))<8?r:8)&&t

ลองออนไลน์!

คำอธิบาย

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

การใช้แผนภาพที่เป็นประโยชน์ของ OP อธิบายการเคลื่อนไหวของลูกบอลอีกครั้งด้วยการปรับเปลี่ยน MS Paint:

ศาสตร์แห่งกอล์ฟ

เราสามารถเข้าถึงหมายเลขเหล่านี้:

  • d , ระยะทางปัจจุบันจากลูกถึงหลุม;
  • θ , มุมชิ้น; และ
  • lความยาวของการยิง (ขั้นต่ำdและความยาวสูงสุดของการยิง)

และเป้าหมายคือการหาxระยะทางจากลูกบอลหนึ่งถึงหลุมหลังจากการยิง

ก่อนอื่นเราสังเกตว่าaและbเป็นเพียงl cos θและl sin θตามลำดับ เราจะเห็นว่าโดยทฤษฎีบทพีทาโกรัสxสามารถแสดงเป็นsqrt (ข2 + (ดา) 2 ) การขยายออกนี้เราได้รับ

x = sqrt(b^2 + (d - a)^2)
  = sqrt((l*sin(θ))^2 + (d - l*cos(θ))^2)
  = sqrt((l^2 * sin^2(θ)) + (d^2 - 2*d*l*cos(θ) + l^2 * cos^2(θ))
  = sqrt(l^2 * sin^2(θ) + l^2 * cos^2(θ) + d^2 - 2dl*cos(θ))
  = sqrt(l^2 * (sin^2(θ) + cos^2(θ)) + d^2 - 2dl*cos(θ))
  = sqrt(l^2 * 1 + d^2 - 2dl*cos(θ))
  = sqrt(l^2 + d^2 - 2dl*cos(θ))

ดังนั้นระยะทางใหม่จากลูกที่หลุมจะsqrt (L 2 + D 2 - 2DL cos θ) จากนั้นเรานับการวนซ้ำที่ใช้เพื่อให้ได้ระยะทางนี้ภายในรัศมีของสีเขียวบวก 2 และสูงสุดที่ 8 เพื่อให้ได้คะแนนสุดท้ายสำหรับหลุมนั้น

(ขอบคุณ @ LegionMammal978 ที่ชี้ให้เห็นว่าการคำนวณทั้งหมดที่ฉันทำนั้นเป็นผลโดยตรงจากกฎแห่งความผาสุก ... )


น่าสนใจพอเมื่อลูกบอลอยู่ใกล้หลุมมากกว่าการยิงสูงสุดl = dและเราสามารถทำให้สูตรง่ายขึ้นอีกเล็กน้อย:

x = sqrt(l^2 + d^2 - 2dl*cos(θ))
  = sqrt(d^2 + d^2 - 2d^2*cos(θ))
  = sqrt(2d^2 - 2d^2*cos(θ))
  = sqrt(d^2(2 - 2cos(θ)))
  = d * sqrt(2 - 2cos(θ))

ในการหาจำนวนการวนซ้ำที่เหลืออยู่เราสามารถหาd / r (โดยที่r = รัศมีของสีเขียว) แล้วหารด้วยsqrt (2 - 2cos (θ))จากนั้นนำเพดานผลลัพธ์และเพิ่ม 2 น่าเสียดายที่นี่ดูเหมือนจะไม่สั้นเท่ากับการหาd ที่เล็กลงและความยาวสูงสุด


มันดูค่อนข้างแข็ง คุณช่วยโพสต์ลิงค์ TIO เมื่อคุณมีโอกาสได้ไหม
Kelly Lowder

1
@ KellyLowder แน่นอนทำ
ETHproductions

2
สมการสุดท้ายของคุณจะไม่เป็นผลโดยตรงจากกฎของโคไซน์หรือไม่?
LegionMammal978

@ LegionMammal978 ฉันเดาว่ามันคงจะ ... ขออภัยตรีโกณมิติของฉันค่อนข้างจะเป็นสนิม: P
ETHproductions

1
@ kamoroso94 นั่นอาจเป็นความคิดที่ดี การใช้.0174533ให้ข้อผิดพลาดเพียง 2.38e-7 กับโคไซน์ 45 องศาดังนั้นมันอาจจะไม่สำคัญพอที่จะทำงานได้ ที่จริงตอนนี้ที่ฉันดูมัน71/4068(= 355/113 / 180) ดียิ่งขึ้นให้ข้อผิดพลาดเพียง 4.135e-10 ...
ETHproductions

3

Perl 5 , 144 138 + 12 ( -MMath::Trig) = 150 ไบต์

โกนสองสามไบต์โดยใช้สูตรของ @ETHproductions

sub p{$_=pi/180*pop;$m=pop;for$b(@_[0..17]){$s=!++$c;1while++$s<6&&$_[17+$c]/2<($b=sqrt$b*$b+($h=$m<$b?$m:$b)**2-2*$h*$b*cos);$t+=$s+2}$t}

ลองออนไลน์!

เปลี่ยนรูปแบบการป้อนข้อมูลเล็กน้อย:

Hole 1 distance
Hole 2 distance
...
Hole 18 distance
Hole 1 green diameter
...
Hole 18 green diameter
Maximum distance
Slice angle

2

Julia 0.6 , 106 bytes

S(m,t,D,G)=(s(m,d,g,v=2)=d<=g/2?v<8?v:8:(l=d<m?d:m;s(l,(d^2+l^2-2d*l*cosd(t))^.5,g,v+1));sum(s.([m],D,G)))

ลองออนไลน์!

ขึ้นอยู่กับคำตอบ ETHproductions'

คำอธิบาย

  • s(m,d,g,v=2)=...กำหนดฟังก์ชั่นsที่คำนวณคะแนนสำหรับหนึ่งหลุมซ้ำ
  • sum(s.([m],D,G))ใช้sสำหรับแต่ละหลุมและสรุปผล .เป็นฟังก์ชั่นการใช้งานองค์ประกอบที่ชาญฉลาดด้วยการขยายตัวซิงเกิล เช่น:min.([1],[2,3]) = [min(1,2), min(1,3)]
d<=g/2?v<8?v:8:(l=d<m?d:m;s(...)) #
d<=g/2?       :                   # is the ball on the green?
       v<8?v:8                    # yes -> return min(v,8)
               (l=d<m?d:m;s(...)) # no  ->
                                  # calculate new distance using ETHproductions' formula
                                  # increment current score
                                  # call s recursively
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.