Code Golf Simuliertes Golf

13

In einer vorgegebenen Liste von Loch yardages, grün Größen, ein Stück Winkel und einem maximalen Abstand, berechnet ein Golf - Score.

Annahmen

  • Die Erde ist flach
  • Alle Grüns sind kreisförmig
  • Der Schnittwinkel liegt zwischen -45 und 45 Grad und wird in Grad angegeben
  • Alle Entfernungen in derselben Metrik (Yards oder Meter, egal)
  • Nicht außerhalb der Grenzen, Hindernisse oder Doglegs
  • Die maximale Punktzahl für ein Loch beträgt 8
  • Alle Schläge bewegen sich in einer Richtung, die durch den Winkel zum Loch plus den Schnittwinkel definiert ist, um die geringere maximale Distanz oder Distanz zum Loch.
  • Die Entfernung wird als gerade Linie oder euklidische Entfernung zwischen Start- und Endpunkt gemessen.
  • Der maximale Abstand und der Schnittwinkel sind für alle Schläge auf alle Löcher gleich
  • Der Golfer hat immer zwei Putts einmal auf dem Grün (oder genau am Rand des Grüns).

Beispiel

Schauen wir uns den Hacker aus dem Testfall Nr. 5 für Loch Nr. 2 an. Der Hacker kann den Ball 320 Yards schlagen, schneidet aber immer 30 Grad. Wenn wir ohne Einschränkung der Allgemeinheit davon ausgehen, dass sich der Abschlag bei {0,0} und das Grün bei {497,0} befindet, wird er die folgenden Punkte treffen und mit dem 7. Schuss auf dem Grün eintreffen:

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

Zu diesem Zeitpunkt wäre seine Punktzahl aufgrund der zwei erforderlichen Putts 9, sodass die endgültige Punktzahl für ihn gemäß den Annahmen auf 8 begrenzt wird.

Grafisch wird es so aussehen: Bildbeschreibung hier eingeben

Testfälle

Alle Testfälle haben Standard-18-Loch-Plätze

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

Regeln

  • Für die Eingabe kann ein beliebiges Format verwendet werden. Die Ausgabe ist einfach die Anzahl der simulierten Striche, sollte also eine ganze Zahl sein.
  • Das ist also gewinnt die kürzeste Antwort in Bytes. Es gelten Standardlücken.
Kelly Lowder
quelle
5
Warum ist "die Erde ist flach" unter Annahmen?
Jo King
Können wir davon ausgehen, dass es nie mehr als 6 Schläge dauert, um den Ball in MaxDistancedas Loch zu bekommen?
ETHproductions
1
@JoKing Hauptsächlich wird also ebene statt sphärische Geometrie verwendet; zweitens, weil es keine Notwendigkeit gab, kugelförmige Hühner anzunehmen :)
Kelly Lowder
@ETHproductions, naja du könntest aber das ist unnötig. Ich denke, vielleicht meinst du GreenDiameter/2, in diesem Fall ja, da die Punktzahl auf 8 begrenzt ist und es immer 2 Putts gibt.
Kelly Lowder
Keine Sorge, formulierte ich die Frage , wie ich meinte , es ;-) Meine Technik , die auf diese angewiesen scheint nicht annähernd so kurz wie meine aktuelle Antwort zu sein , obwohl, so geschweige denn ich denke , ...
ETHproductions

Antworten:

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

Probieren Sie es online!

Erläuterung

Da es nur auf die Entfernung vom Ball zum Loch ankommt und nicht auf die Koordinaten des Balls, können wir einen Algorithmus schreiben, der berechnet, wie nah der Ball bei jedem Schlag am Loch ist, und diesen dann wiederholt ausführen, bis der Ball das Grün erreicht. Aber wie machen wir das?

Wiederverwendung des hilfreichen Diagramms von OP zur Erläuterung der Kugelbewegung mit MS Paint-Modifikationen:

die Wissenschaft des Golfs

Wir haben Zugriff auf diese Nummern:

  • d , der aktuelle Abstand von der Kugel zum Loch;
  • θ der Schnittwinkel; und
  • l , die Länge des Schusses (Minimum von d und die maximale Schusslänge).

Und das Ziel ist es, x zu finden , die Entfernung vom Ball zum Loch, nachdem der Schuss ausgeführt wurde.

Zuerst stellen wir fest, dass a und b einfach l cos θ bzw. l sin θ sind. Wir können sehen, dass durch den Satz des Pythagoras x als sqrt (b 2 + (da) 2 ) dargestellt werden kann . Wenn wir das erweitern, bekommen wir

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

Und so wird der neue Abstand von Kugel zu Loch sqrt sein (l 2 + d 2 - 2dl cos θ) . Dann zählen wir die Iterationen, die erforderlich sind, um diese Distanz innerhalb des Radius des Grüns zu erhalten, addieren 2 und kappen bei 8, um die endgültige Punktzahl für dieses Loch zu erhalten.

(Danke an @ LegionMammal978 für den Hinweis, dass alle Berechnungen, die ich gemacht habe, ein direktes Ergebnis des Kosinusgesetzes sind ...)


Interessanterweise ist l = d , wenn der Ball näher am Loch ist als der maximale Schuss, und wir können die Formel ein Stück weiter vereinfachen:

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

Um die Anzahl der verbleibenden Iterationen zu ermitteln, können wir einfach d / r (wobei r = der Radius des Grüns ist) ermitteln und durch sqrt (2 - 2cos (θ)) dividieren , dann die Obergrenze des Ergebnisses nehmen und 2 addieren Leider scheint dies nicht so kurz zu sein, als nur das kleinere von d und die maximale Schusslänge zu finden.

ETHproductions
quelle
Das sieht ziemlich solide aus. Könnten Sie bitte einen TIO-Link posten, wenn Sie eine Chance haben?
Kelly Lowder
1
@ KellyLowder Sicher, fertig.
ETHproductions
2
Wäre Ihre endgültige Gleichung nicht eine direkte Konsequenz des Kosinusgesetzes?
LegionMammal978
@ LegionMammal978 Ich denke, es würde ... Entschuldigung, meine Trigonometrie ist ein wenig verrostet: P
ETHproductions
1
@ kamoroso94 Das könnte eine gute Idee sein. Die Verwendung von .0174533gibt einen Fehler von nur 2,38e-7 auf dem Cosinus von 45 Grad, sodass er möglicherweise vernachlässigbar ist, um zu funktionieren. Eigentlich ist 71/4068(= 355/113 / 180) jetzt, wo ich es mir ansehe, sogar noch besser und gibt einen Fehler von nur 4.135-10 ...
ETHproductions
3

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

einige Bytes mit @ETHproductions 'Vereinfachung der Formel rasiert

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}

Probieren Sie es online!

Eingabeformat etwas geändert:

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

Probieren Sie es online!

Basierend auf der Antwort von ETHproductions .

Erläuterung

  • s(m,d,g,v=2)=...Definieren Sie eine Funktion s, die die Punktzahl für ein Loch rekursiv berechnet.
  • sum(s.([m],D,G))sFür jedes Loch anwenden und das Ergebnis summieren. .ist eine elementweise Funktionsanwendung mit Singleton-Erweiterung. Z.B: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
quelle