Billard spielen


17

Bei diesem Codegolf müssen Sie die Richtung des kürzesten Schlags bestimmen, der genau n Kissen trifft, bevor Sie in eine Tasche fallen.

Der Billardtisch ist ein Billardtisch mit 6 Taschen und den folgenden Eigenschaften:

  • Maße sind variabel ( a x b )
  • Keine Reibung: Der Ball rollt für immer, bis er in eine Tasche fällt
  • Taschen und Ballgrößen sind fast Null. Dies bedeutet, dass die Kugel nur dann in die Tasche fällt, wenn sie die gleiche Position haben.
  • Der Ball wird am Anfang am linken unteren Loch platziert (fällt aber nicht hinein)

3 Kissen

Erstellen Sie ein vollständiges Programm oder eine Funktion, die die Abmessungen ( a , b ) der Tabelle und die Anzahl der Kissen als Eingabe verwendet , um n zu treffen, und den Winkel in Grad des kürzesten Pfades zurückgibt, der genau n Kissen trifft, bevor er in eine Tasche fällt.

  • a > 0
  • b > 0
  • 0 <= n <10000000
  • 0 < Alpha <90 (in Grad) Genauigkeit: mindestens 10 ^ -6

Beispiele:

mit a = 2, b = 1, n = 1 gibt es drei mögliche Pfade: (1) (2) (3) in der folgenden Abbildung. Die Zahl (1) ist die kürzeste, daher sollte die Ausgabe bei (2) = 63,43494882292201 Grad liegen

1 Kissen

Die Lösung für a = 2, b = 1, n = 4 ist atan (4/3) = 53,13010235415598 Grad

4 Kissen

Testmuster:

a = 2,    b = 1,    n = 1,       -> alpha = 63.43494882292201
a = 2,    b = 1,    n = 2,       -> alpha = 71.56505117707799
a = 2,    b = 1,    n = 3,       -> alpha = 75.96375653207353
a = 2,    b = 1,    n = 4,       -> alpha = 53.13010235415598
a = 2,    b = 1,    n = 5,       -> alpha = 59.03624346792648
a = 2,    b = 1,    n = 6,       -> alpha = 81.86989764584403
a = 4.76, b = 3.64, n = 27,      -> alpha = 48.503531644784466
a = 2,    b = 1,    n = 6,       -> alpha = 81.86989764584403
a = 8,    b = 3,    n = 33,      -> alpha = 73.24425107080101
a = 43,   b = 21,   n = 10005,   -> alpha = 63.97789961246943

Dies ist Code / Billard Golf: Der kürzeste Code gewinnt!


Muss der Ball genau auf n Kissen treffen oder zumindest auf n Kissen?
Peter Taylor

@ Peter Taylor genau n Kissen
Damien

ist nicht der kürzeste weg immer hin und her zwischen der linken seite oben und unten und dann in eines der mittleren löcher?
Eumel

nein, schau dir das 2 1 4 Beispiel an. Dieser Pfad ist sqrt (25) = 5 lang, während Ihre Lösung sqrt (26) ist
Damien

Antworten:


11

Python 2.7, 352 344 281 Bytes

from math import*
def l(a,b,n):
 a*=1.;b*=1.
 r=set()
 for i in range(1,n+3):
  t=[]
  for k in range(1,i):
   for h in[0,.5]:
    x=(i-k-h)
    if 1-(x/k in r):r.add(x/k);t+=(x*a,k*b),
 d=(a*n+1)**2+(b*n+1)**2
 for x,y in t:
  if x*x+y*y<d:d=x*x+y*y;o=degrees(atan(y/x))
 return o
  • -16 Bytes dank @Dschoni

Erklärung: Statt die Kissenschläge zu berechnen, füge ich n Tabellen hinzu und nehme die neuen Löcher als gültig: Billard Schwarzer Rand / Löcher sind das Original, grüner Rand / Löcher sind gültig für n = 1, roter Rand / Löcher sind gültig für n = 2 und so weiter. Dann entferne ich die ungültigen Löcher (zB den blauen Pfeil für n = 1). Ich habe eine Liste der gültigen Löcher und ihrer Koordinaten, dann berechne ich ihre Entfernung vom Anfangspunkt und dann den Winkel der kleineren Entfernung.
Anmerkungen:
a = 4,76, b = 3,64, n = 27 - geben Sie 52,66286 und versuchen Sie herauszufinden, warum dies behoben wurde. Dabei wurden 8 Bytes gespeichert. = Da
= 43, b = 21, n = 10005 - dauert ~ 80 Sekunden. aber gibt den richtigen Winkel)

lesbare Version:

from math import *
def bill(a,b,n):
    a=float(a)
    b=float(b)
    ratios = set()
    for i in range(0,n+2): # Create the new boards
        outter = []
        j=i+1
        for k in range(1,j): # Calculate the new holes for each board
            #y=k
            for hole_offset in [0,0.5]:
                x=(j-k-hole_offset)
                if (x/k) not in ratios:
                    ratios.add(x/k)
                    outter.append((x*a,k*b))
    min_dist = (a*n+1)**2+(b*n+1)**2
    for x,y in outter:
        if x*x+y*y<min_dist:
            min_dist = x*x+y*y
            min_alpha=degrees(atan(y/x))
    return min_alpha

Sie können ein Byte speichern, indem Sie das Leerzeichen in ": degrees
Morgan Thrapp

Ich habe keine Ahnung, wie Ihre Antwort (mathematisch) funktioniert, aber ich denke, Sie können 1 Byte gewinnen, indem Sie das Leerzeichen nach dem Doppelpunkt entfernen. :) (Was @ MorganThrapp sagte)
Basilikum-Henry

2
Dieser Pfad ist gültig, aber nicht in allen Fällen der kürzeste, zum Beispiel mit 2 1 4 ..
Damien

Dies setzt auch das voraus b < a. Das könnte leicht behoben werden, indem das Minimum / Maximum von aund bobwohl erhalten wird.
User81655

behoben (sorta)
Rod

3

Haskell, 133 117 Bytes

Dies ist meine Implementierung:

Bei einem 2x1-Tisch trifft ein Pfad genau n Kissen, bevor er in eine Tasche geht, wenn: (x-1) / 2 + (y-1) == n und x, y gegenseitig Primzahlen sind. Dabei ist x, y der Abstand des Balls über die horizontalen / vertikalen Achsen.

Die Pfade sind bei beliebiger Tabellengröße gleich, daher müssen wir nur die Längen und Winkel mit (a, b) aktualisieren und die kürzesten beibehalten. Die Pfadlänge ist sqrt ((x * a / 2) ^ 2 + (y * b) ^ 2) und der Winkel ist atan ((y * b) / (x * a / 2))

z=toEnum
f a b n=minimum[[z x^2+r^2,180/pi*atan(r/z x)]|x<-[1..2*n+2],y<-[n+1-div(x-1)2],r<-[2*b/a*z y],gcd x y<2]!!1
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.