代码高尔夫模拟高尔夫


13

给定一系列孔码,果岭尺寸,切角和最大距离,即可计算出高尔夫球得分。

假设条件

  • 地球是平坦的
  • 所有果岭都是圆形的
  • 切片角度将在-45至45度之间,以度为单位
  • 所有距离均以同一度量标准(码或米,无关紧要)
  • 没有界限,障碍物或狗腿
  • 任何洞的最高分数是8
  • 所有镜头在与孔的角度加上切片角度所定义的方向上移动的最大距离或与孔的距离中的较小者。
  • 距离以起点或终点之间的直线或欧几里得距离的形式测量。
  • 所有孔上的所有镜头的最大距离和切片角度均相同
  • 高尔夫球手总是在果岭上两次击球(或者恰好在果岭边缘)。

让我们从下面测试用例#5的漏洞#2看一下黑客。黑客可以将球打到320码,但始终会切成30度。如果我们不失一般性地假设发球区框在{0,0}而果岭在{497,0},那么他将击球到以下点,并在第七杆处到达果岭:

{{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

我们是否可以假设将球MaxDistance打入洞内绝不会超过6球?
ETHproductions

1
@JoKing主要是使用平面而不是球形几何图形;其次,因为没有必要假设球形鸡:)
凯利·洛德

@ETHproductions,好吧,但这是不必要的。我认为您的意思是GreenDiameter/2,在这种情况下,是的,因为得分上限为8,并且总有2个推杆。
凯利·洛德

不用担心,我说的是这个问题的意思;-)我依赖它的技术似乎并不像我目前的回答那么短,所以我没关系...
ETHproductions

Answers:


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,即射门后从球到洞的距离。

首先,我们注意到ab分别只是l cosθl sinθ。我们可以看到,根据勾股定理,x可以表示为sqrt(b 2 +(da)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链接吗?
凯莉·洛德

1
@KellyLowder当然可以。
ETHproductions

2
您的最终方程式不是余弦定律的直接结果吗?
LegionMammal978 '18

@ LegionMammal978我想这会...对不起,我的三角学有点生锈:P
ETHproductions

1
@ kamoroso94这可能是个好主意。使用.017453345度余弦时,误差仅为2.38e-7,因此可以正常工作了。实际上,现在我看,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

朱莉娅0.6,106字节

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.