Grać w bilard

17

W tym kodzie w golfa, trzeba będzie określić kierunek najkrótszym strzale, która uderza dokładnie n poduszki przed wpadnięciem do kieszeni.

Stół bilardowy to 6-kieszeniowy stół bilardowy o następujących cechach:

  • Wymiary są zmienne ( a x b )
  • Bez tarcia: piłka będzie toczyła się wiecznie, aż wpadnie do kieszeni
  • Rozmiary kieszeni i kulek są prawie zerowe. Oznacza to, że piłka wpadnie do kieszeni tylko wtedy, gdy będzie miała tę samą pozycję.
  • Piłka jest umieszczana w lewym dolnym otworze na początku (ale nie wpada w nią)

3 poduszki

Utwórz pełny program lub funkcję, która przyjmuje wymiary ( a , b ) tabeli i liczbę poduszek, które należy uderzyć n jako dane wejściowe, i zwraca kąt w stopniach najkrótszej ścieżki uderzając dokładnie n poduszek przed wpadnięciem do kieszeni.

  • a > 0
  • b > 0
  • 0 <= n <10000000
  • Dokładność 0 < alfa <90 (w stopniach): co najmniej 10 ^ -6

przykłady:

przy a = 2, b = 1, n = 1 istnieją trzy możliwe ścieżki: (1) (2) (3) na poniższym rysunku. liczba (1) jest najkrótsza, więc wyjście powinno wynosić atan (2) = 63,43494882292201 stopni

1 poduszka

Rozwiązaniem dla a = 2, b = 1, n = 4 jest atan (4/3) = 53,133010235415598 stopni

4 poduszki

próbki testowe:

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

To jest golf kodowy / bilardowy: wygrywa najkrótszy kod!

Damien
źródło
Czy piłka musi trafić dokładnie w n poduszki, a przynajmniej w n poduszki?
Peter Taylor,
@PeterTaylor dokładnie n poduszki
Damien
czy nie jest najkrótsza ścieżka zawsze tam iz powrotem między lewym górnym i dolnym bokiem, a następnie do jednego ze środkowych otworów?
Eumel,
nie, spójrz na przykład 2 1 4. Ta ścieżka ma sqrt (25) = 5, podczas gdy twoje rozwiązanie to sqrt (26)
Damien

Odpowiedzi:

11

Python 2.7, 352 344 281 bajtów

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 bajtów dzięki @Dschoni

Objaśnienie: zamiast obliczać trafienia poduszek, dodaję n tabel i biorę nowe dziury za prawidłowe: bilard czarna ramka / dziury jest oryginalna, zielona ramka / dziury jest ważna dla n = 1, czerwona ramka / dziury jest ważna dla n = 2 i tak dalej. Następnie usuwam nieprawidłowe otwory (np. Niebieska strzałka dla n = 1). Będę miał listę prawidłowych otworów i ich współrzędnych, następnie obliczę ich odległość od punktu początkowego, a następnie kąt mniejszej odległości.
Uwagi:
a = 4,76, b = 3,64, n = 27 - podaj 52,66286, próbując dowiedzieć się, dlaczego naprawiono i zapisano 8 bajtów w procesie = D
a = 43, b = 21, n = 10005 - zajmuje ~ 80 sekund ( ale daje odpowiedni kąt)

czytelna wersja:

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
Pręt
źródło
Możesz zapisać bajt, usuwając spację w : degrees
Morgan Thrapp,
Nie mam pojęcia, jak działa twoja odpowiedź (matematyczne), ale myślę, że możesz zyskać 1 bajt, usuwając spację po dwukropku. :) (Co powiedział @MorganThrapp)
basile-henry
2
Ta ścieżka jest ważna, ale nie jest najkrótsza we wszystkich przypadkach, na przykład z 2 1 4 ..
Damien
To również zakłada b < a. Można to łatwo naprawić, uzyskując minimum / maksimum ai bchociaż.
user81655,
naprawiono (sorta)
Rod
3

Haskell, 133 117 bajtów

To jest moja realizacja:

Przy stole 2x1 ścieżka trafi dokładnie n poduszek przed wejściem do kieszeni, jeśli: (x-1) / 2 + (y-1) == n i x, y są liczbami pierwszymi. gdzie x, y to odległość piłki nad osiami poziomymi / pionowymi.

Ścieżki są takie same z dowolnym rozmiarem tabeli, więc musimy tylko zaktualizować długości i kąty za pomocą (a, b) i zachować najkrótsze. Długość ścieżki to sqrt ((x * a / 2) ^ 2 + (y * b) ^ 2), a kąt to 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
Damien
źródło