Code Golf Simulated Golf

13

À partir d'une liste de mètres de trous, de tailles vertes, d'un angle de tranche et d'une distance maximale, calculez un score de golf .

Hypothèses

  • La terre est plate
  • Tous les verts sont circulaires
  • L'angle de coupe sera compris entre -45 et 45 degrés et sera donné en degrés
  • Toutes les distances dans la même métrique (yards ou mètres, peu importe)
  • Pas de limites, d'obstacles ou de doglegs
  • Le score maximum sur n'importe quel trou est de 8
  • Tous les tirs parcourent la moindre distance maximale ou distance au trou, dans une direction définie par l'angle du trou plus l'angle de la tranche.
  • La distance est mesurée comme la ligne droite ou la distance euclidienne entre le point de départ et le point d'arrivée.
  • La distance maximale et l'angle de coupe sont les mêmes pour toutes les prises de vue sur tous les trous
  • Le golfeur fait toujours deux coups roulés une fois sur le green (ou exactement au bord du green).

Exemple

Regardons le pirate du cas de test n ° 5 ci-dessous pour le trou n ° 2. Le pirate peut frapper la balle à 320 mètres, mais tranche toujours à 30 degrés. Si nous supposons sans perte de généralité que la zone de départ est à {0,0} et que le vert est à {497,0}, alors il frappera les tirs aux points suivants, arrivant sur le vert avec le 7ème coup:

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

À ce stade, son score serait de 9 en raison des deux putts requis, donc le score final pour lui est plafonné à 8, selon les hypothèses.

Graphiquement, cela ressemblera à ceci: entrez la description de l'image ici

Cas de test

Tous les cas de test ont des parcours standard de 18 trous

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

Règles

  • N'importe quel format peut être utilisé pour l'entrée. La sortie est simplement le nombre de traits simulés, donc devrait être un entier.
  • Il s'agit de donc la réponse la plus courte en octets l'emporte. Des échappatoires standard s'appliquent.
Kelly Lowder
la source
5
Pourquoi "la Terre est plate" sous des hypothèses?
Jo King
Pouvons-nous supposer qu'il ne faudra jamais plus de 6 tirs pour amener le ballon à l'intérieur MaxDistancedu trou?
ETHproductions du
1
@JoKing Principalement, de sorte que la géométrie plane plutôt que sphérique soit utilisée; deuxièmement parce qu'il n'était pas nécessaire de supposer des poulets sphériques :)
Kelly Lowder
@ETHproductions, vous pourriez bien mais ce n'est pas nécessaire. Je pense que vous voulez dire GreenDiameter/2, dans ce cas, oui, car le score est plafonné à 8 et il y a toujours 2 putts.
Kelly Lowder
Ne vous inquiétez pas, j'ai formulé cette question comme je l'entendais ;-) Ma technique qui repose sur cela ne semble cependant pas aussi courte que ma réponse actuelle, alors tant
pis

Réponses:

10

JavaScript (ES7), 128 126 octets

(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

Essayez-le en ligne!

Explication

Parce que seule la distance entre la balle et le trou est importante et non les coordonnées de la balle, nous pouvons écrire un algorithme qui calcule la distance entre la balle et le trou à chaque tir, puis la répéter jusqu'à ce que la balle atteigne le vert. Mais comment fait-on cela?

Réutilisation du diagramme utile d'OP expliquant le mouvement de la balle, avec des modifications de MS Paint:

la science du golf

Nous avons accès à ces numéros:

  • d , la distance actuelle de la balle au trou;
  • θ , l'angle de coupe; et
  • l , la longueur de la prise de vue (minimum de d et la longueur maximale de prise de vue).

Et le but est de trouver x , la distance de la balle au trou après la prise de vue.

Notons d'abord que a et b sont simplement l cos θ et l sin θ , respectivement. Nous pouvons voir que par le théorème de Pythagore, x peut être représenté comme sqrt (b 2 + (da) 2 ) . En développant cela, nous obtenons

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

Et donc, la nouvelle distance de la balle au trou sera sqrt (l 2 + d 2 - 2dl cos θ) . Ensuite, nous comptons les itérations nécessaires pour obtenir cette distance dans le rayon du vert, ajoutons 2 et plafons à 8 pour obtenir le score final pour ce trou.

(Merci à @ LegionMammal978 d'avoir souligné que tous les calculs que j'ai faits sont un résultat direct de la loi des cosinus ...)


Fait intéressant, lorsque la balle est plus proche du trou que son tir maximum, l = d et nous pouvons simplifier la formule un peu plus loin:

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

Pour trouver le nombre d'itérations restantes, nous pourrions alors simplement trouver d / r (où r = le rayon du vert) et diviser cela par sqrt (2 - 2cos (θ)) , puis prendre le plafond du résultat et ajouter 2 Malheureusement, cela ne semble pas être aussi court que de trouver le plus petit de d et la longueur de prise de vue maximale.

ETHproductions
la source
Cela semble assez solide. Pourriez-vous s'il vous plaît poster un lien TIO lorsque vous en avez l'occasion?
Kelly Lowder
1
@KellyLowder Bien sûr, c'est fait.
ETHproductions
2
Votre équation finale ne serait-elle pas une conséquence directe de la loi des cosinus?
LegionMammal978
@ LegionMammal978 Je suppose que ce serait ... Désolé, ma trigonométrie est un peu rouillée: P
ETHproductions
1
@ kamoroso94 Cela pourrait être une bonne idée. L'utilisation .0174533donne une erreur de seulement 2,38e-7 sur le cosinus de 45 degrés, il peut donc être assez négligeable pour fonctionner. En fait, maintenant que je le regarde, 71/4068(= 355/113 / 180) est encore mieux, donnant une erreur de seulement 4.135e-10 ...
ETHproductions
3

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

rasé quelques octets en utilisant la simplification de la formule @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}

Essayez-le en ligne!

Modifié un peu le format d'entrée:

Hole 1 distance
Hole 2 distance
...
Hole 18 distance
Hole 1 green diameter
...
Hole 18 green diameter
Maximum distance
Slice angle
Xcali
la source
2

Julia 0.6 , 106 octets

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

Essayez-le en ligne!

Basé sur la réponse d'ETHproductions .

Explication

  • s(m,d,g,v=2)=...Définissez la fonction squi calcule le score pour un trou de manière récursive.
  • sum(s.([m],D,G))Appliquer spour chaque trou et additionner le résultat. .est une application de fonction élément par élément avec une extension singleton. Par exemple: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
la source