카테고리 보관물: 코딩

코딩

코드 골프 시뮬레이션 골프 수는 있지만 항상 30도 슬라이스합니다. 일반성을 잃지

홀 야드 수, 녹색 크기, 슬라이스 각도 및 최대 거리 목록이 주어지면 골프 점수를 계산하십시오 .

가정

  • 지구는 평평하다
  • 모든 녹색은 원형입니다
  • 슬라이스 각도는 -45 ~ 45도 사이이며 각도로 표시됩니다
  • 동일한 측정 항목의 모든 거리 (야드 또는 미터, 중요하지 않음)
  • 경계, 장애물 또는 도그 레그 없음
  • 모든 홀에서 최대 점수는 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

규칙

  • 모든 형식을 입력에 사용할 수 있습니다. 출력은 단순히 시뮬레이션 된 스트로크의 수이므로 정수 여야합니다.
  • 이것은 이므로 바이트 단위의 최단 답변이 이깁니다. 표준 허점이 적용됩니다.


답변

자바 스크립트 (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

온라인으로 사용해보십시오!

설명

볼에서 홀까지의 거리 만 중요하고 볼의 좌표는 중요하지 않기 때문에 각 샷에서 볼이 홀에 얼마나 가까운 지 계산하는 알고리즘을 작성한 다음 볼이 녹색에 도달 할 때까지 반복적으로 실행할 수 있습니다. 그러나 우리는 이것을 어떻게합니까?

MS 페인트 수정과 함께 공의 움직임을 설명하는 OP의 유용한 다이어그램을 다시 사용합니다.

골프 과학

우리는이 번호에 접근 할 수 있습니다 :

  • d , 공에서 구멍까지의 현재 거리;
  • θ , 슬라이스 각도; 과
  • l , 샷 길이 (최소 d 및 최대 샷 길이).

그리고 목표는 샷을 얻은 후 공에서 구멍까지의 거리 인 x 를 찾는 것입니다.

먼저 ab 는 각각 l cos θl sin θ 라는 것을 알 수 있습니다. 피타고라스 정리에 따르면 xsqrt (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 와 최대 샷 길이를 찾는 것만 큼 짧지 않은 것 같습니다 .


답변

펄 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


답변

줄리아 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


답변