Codice Golf Golf simulato


13

Dato un elenco di yardage buche, dimensioni verdi, un angolo di fetta e una distanza massima, calcolare un punteggio di golf .

ipotesi

  • La terra è piatta
  • Tutti i verdi sono circolari
  • L'angolo di taglio sarà compreso tra -45 e 45 gradi e verrà indicato in gradi
  • Tutte le distanze nella stessa metrica (iarde o metri, non importa)
  • Nessun limite, ostacolo o dogleg
  • Il punteggio massimo per ogni buca è 8
  • Tutti i colpi percorrono la distanza minima o massima rispetto al foro, in una direzione definita dall'angolo rispetto al foro più l'angolo di taglio.
  • La distanza viene misurata come linea retta o distanza euclidea tra il punto iniziale e quello finale.
  • La distanza massima e l'angolo di taglio sono gli stessi per tutti i colpi su tutti i fori
  • Il golfista fa sempre due putte una volta sul green (o esattamente sul bordo del green).

Esempio

Diamo un'occhiata all'hacker dal test case # 5 in basso per il buco # 2. L'hacker può colpire la palla 320 iarde, ma taglia sempre 30 gradi. Se assumiamo senza perdita di generalità che il tee box è a {0,0} e il verde è a {497,0}, allora colpirà i colpi nei seguenti punti, arrivando sul verde con il 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}}

A questo punto, il suo punteggio sarebbe 9 a causa dei due put richiesti, quindi il punteggio finale per lui viene limitato a 8, secondo le ipotesi.

Graficamente, sarà simile a questo: inserisci qui la descrizione dell'immagine

Casi test

Tutti i casi di test hanno percorsi standard a 18 buche

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

Regole

  • È possibile utilizzare qualsiasi formato per l'input. L'output è semplicemente il numero di tratti simulati, quindi dovrebbe essere un numero intero.
  • Questo è quindi vince la risposta più breve in byte. Si applicano scappatoie standard.

5
Perché "la Terra è piatta" sotto ipotesi?
Jo King,

Possiamo supporre che non ci vorranno mai più di 6 colpi per far entrare la palla nella MaxDistancebuca?
ETHproductions

1
@JoKing Principalmente, in modo che venga utilizzata la geometria piana anziché sferica; in secondo luogo perché non era necessario assumere polli sferici :)
Kelly Lowder,

@ETHproductions, bene, ma non è necessario. Penso che forse intendi GreenDiameter/2, nel qual caso sì, dato che il punteggio è limitato a 8 e ci sono sempre 2 punti.
Kelly Lowder,

Non ti preoccupare, ho formulato questa domanda su come intendevo ;-) La mia tecnica che si basa su questo non sembra essere altrettanto corta della mia attuale risposta, quindi non importa immagino ...
ETHproductions

Risposte:


10

JavaScript (ES7), 128 126 byte

(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

Provalo online!

Spiegazione

Poiché conta solo la distanza dalla palla alla buca e non le coordinate della palla, possiamo scrivere un algoritmo che calcola quanto la palla si avvicina alla buca ad ogni tiro, quindi correre più volte fino a quando la palla raggiunge il green. Ma come lo facciamo?

Riutilizzando il diagramma utile di OP che spiega il movimento della palla, con modifiche a MS Paint:

la scienza del golf

Abbiamo accesso a questi numeri:

  • d , la distanza attuale dalla palla alla buca;
  • θ , l'angolo di taglio; e
  • l , la lunghezza del tiro (minimo d e la lunghezza massima del tiro).

E l'obiettivo è trovare x , la distanza da palla a buca dopo il tiro.

Primo notiamo che un e b sono semplicemente l cos θ e l sin θ , rispettivamente. Possiamo vedere che dal teorema di Pitagora, x può essere rappresentato come sqrt (b 2 + (da) 2 ) . Espandendolo, otteniamo

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 così, la nuova distanza da palla a buca sarà sqrt (l 2 + d 2 - 2dl cos θ) . Quindi contiamo le iterazioni necessarie per ottenere questa distanza entro il raggio del green, aggiungiamo 2 e cap a 8 per ottenere il punteggio finale per quella buca.

(Grazie a @ LegionMammal978 per aver sottolineato che tutti i calcoli che ho fatto sono un risultato diretto della legge dei coseni ...)


È interessante notare che quando la palla è più vicina alla buca del suo tiro massimo, l = d e possiamo semplificare un po 'più la formula:

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

Per trovare il numero di iterazioni rimanenti, potremmo quindi semplicemente trovare d / r (dove r = il raggio del verde) e dividerlo per sqrt (2 - 2cos (θ)) , quindi prendere il limite del risultato e aggiungere 2 Sfortunatamente, questo non sembra essere così breve come trovare la minore di d e la lunghezza massima del tiro.


Sembra abbastanza solido. Potresti per favore pubblicare un link TIO quando ne hai la possibilità?
Kelly Lowder,

1
@KellyLowder Certo, fatto.
ETHproductions

2
La tua equazione finale non sarebbe una conseguenza diretta della legge dei coseni?
LegionMammal978,

@ LegionMammal978 Immagino che sarebbe ... Mi dispiace, la mia trigonometria è un po 'arrugginita: P
ETHproductions

1
@ kamoroso94 Potrebbe essere una buona idea. L'uso di .0174533un errore di soli 2,38e-7 sul coseno di 45 gradi, quindi potrebbe essere abbastanza trascurabile per funzionare. In realtà ora che lo guardo, 71/4068(= 355/113 / 180) è ancora meglio, dando un errore di soli 4.135e-10 ...
ETHproductions

3

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

rasato alcuni byte usando la semplificazione della formula di @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}

Provalo online!

Modificato un po 'il formato di input:

Hole 1 distance
Hole 2 distance
...
Hole 18 distance
Hole 1 green diameter
...
Hole 18 green diameter
Maximum distance
Slice angle

2

Julia 0.6 , 106 byte

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

Provalo online!

Basato sulla risposta di ETHproductions .

Spiegazione

  • s(m,d,g,v=2)=...Definire la funzione sche calcola ricorsivamente il punteggio per una buca.
  • sum(s.([m],D,G))Fare domanda sper ogni buca e sommare il risultato. .è un'applicazione con funzioni elementali con espansione singleton. Per esempio: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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.