Código Golf Simulado Golf

13

Dada uma lista de jardas de furos, tamanhos verdes, um ângulo de fatia e uma distância máxima, calcule uma pontuação de golfe .

Premissas

  • Terra é plana
  • Todos os verdes são circulares
  • O ângulo da fatia estará entre -45 e 45 graus e será dado em graus
  • Todas as distâncias na mesma métrica (jardas ou metros, não importa)
  • Não fora dos limites, obstruções ou doglegs
  • A pontuação máxima em qualquer buraco é 8
  • Todas as fotos percorrem a menor distância máxima ou a distância do furo, em uma direção definida pelo ângulo do furo mais o ângulo da fatia.
  • A distância é medida como a linha reta ou a distância euclidiana entre o ponto inicial e final.
  • Distância máxima e ângulo de corte são iguais para todas as fotos em todos os buracos
  • O jogador de golfe sempre faz duas tacadas uma vez no green (ou exatamente na borda do green).

Exemplo

Vejamos o hacker do caso de teste nº 5 abaixo, referente ao furo nº 2. O hacker pode acertar a bola a 320 jardas, mas sempre corta 30 graus. Se assumirmos, sem perda de generalidade, que a caixa de tee está em {0,0} e o verde está em {497,0}, ele acertará os tiros nos seguintes pontos, chegando ao verde com o 7º tiro:

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

Nesse ponto, sua pontuação seria 9 devido às duas tacadas necessárias, portanto a pontuação final para ele é limitada a 8, de acordo com as suposições.

Graficamente, ficará assim: insira a descrição da imagem aqui

Casos de teste

Todos os casos de teste possuem cursos padrão de 18 buracos

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

Regras

  • Qualquer formato pode ser usado para a entrada. A saída é simplesmente o número de traços simulados, portanto deve ser um número inteiro.
  • Isso é então a resposta mais curta em bytes vence. Aplicam-se brechas padrão.
Kelly Lowder
fonte
5
Por que "a Terra é plana" sob suposições?
Jo rei
Podemos assumir que nunca serão necessários mais do que 6 chutes para colocar a bola dentro MaxDistancedo buraco?
ETHproductions
1
@JoKing Principalmente, para que a geometria plana e não a esférica seja usada; em segundo lugar porque não havia necessidade de assumir galinhas esféricas :)
Kelly Lowder
@ETHproductions, bem, você poderia, mas isso é desnecessário. Acho que você quer dizer GreenDiameter/2, nesse caso sim, já que o placar é limitado em 8 e sempre há 2 tacadas.
22418 Kelly Lowder
Não se preocupe, eu escrevi essa pergunta como eu a quis dizer ;-) Minha técnica que se baseia nisso não parece ser tão curta quanto a minha resposta atual, então não importa, eu acho ...
ETHproductions

Respostas:

10

JavaScript (ES7), 128 126 bytes

(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

Experimente online!

Explicação

Como apenas a distância da bola até o buraco é importante e não as coordenadas da bola, podemos escrever um algoritmo que calcula a distância que a bola chega ao buraco a cada tiro e, em seguida, executar repetidamente até que a bola alcance o verde. Mas como fazemos isso?

Reutilizando o diagrama útil do OP, explicando o movimento da bola, com as modificações do MS Paint:

a ciência do golfe

Temos acesso a estes números:

  • d , a distância atual da bola ao buraco;
  • θ , o ângulo da fatia; e
  • l , o comprimento do tiro (mínimo de d e o comprimento máximo do tiro).

E o objetivo é encontrar x , a distância entre a bola e o buraco após o arremesso.

Primeiro, notamos que a e b são simplesmente l cos θ e l sin θ , respectivamente. Podemos ver que, pelo teorema de Pitágoras, x pode ser representado como sqrt (b 2 + (da) 2 ) . Expandindo isso, obtemos

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(θ))

E assim, a nova distância da bola ao buraco será sqrt (l 2 + d 2 - 2dl cos θ) . Depois, contamos as iterações necessárias para obter essa distância dentro do raio do verde, adicione 2 e limpe em 8 para obter a pontuação final para esse buraco.

(Obrigado a @ LegionMammal978 por apontar que todos os cálculos que fiz são resultado direto da lei dos cossenos ...)


Curiosamente, quando a bola está mais próxima do buraco do que seu tiro máximo, l = d e podemos simplificar a fórmula um pouco mais:

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(θ))

Para encontrar o número de iterações restantes, poderíamos simplesmente encontrar d / r (em que r = raio do verde) e dividi-lo por sqrt (2 - 2cos (θ)) , depois pegar o teto do resultado e adicionar 2 Infelizmente, isso não parece tão curto quanto encontrar o menor de d e o comprimento máximo do disparo.

ETHproductions
fonte
Isso parece bastante sólido. Você poderia postar um link do TIO quando tiver uma chance?
precisa
1
@KellyLowder Claro, pronto.
ETHproductions
2
Sua equação final não seria uma conseqüência direta da lei dos cossenos?
LegionMammal978
@ LegionMammal978 Acho que sim ... Desculpe, minha trigonometria está um pouco enferrujada: P
ETHproductions
1
@ kamoroso94 Essa pode ser uma boa ideia. O uso .0174533gera um erro de apenas 2,38e-7 no cosseno de 45 graus, portanto pode ser insignificante o suficiente para funcionar. Na verdade, agora que eu olho para ele, 71/4068(= 355/113 / 180) é ainda melhor, dando um erro de apenas 4.135e-10 ...
ETHproductions
3

Perl 5 , 144 138 + 12 ( -MMath::Trig) = 150 bytes

raspou alguns bytes usando a simplificação da fórmula @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}

Experimente online!

Alterou um pouco o formato de entrada:

Hole 1 distance
Hole 2 distance
...
Hole 18 distance
Hole 1 green diameter
...
Hole 18 green diameter
Maximum distance
Slice angle
Xcali
fonte
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)))

Experimente online!

Baseado na resposta da ETHproductions .

Explicação

  • s(m,d,g,v=2)=...Defina a função sque calcula a pontuação para um buraco recursivamente.
  • sum(s.([m],D,G))Aplique spara cada furo e some o resultado. .é um aplicativo de função elemento a elemento com expansão singleton. Por exemplo: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
LukeS
fonte