Giocare a biliardo


17

In questo codice golf, dovrai determinare la direzione del tiro più corto che colpisce esattamente n cuscini prima di cadere in una tasca.

Il tavolo da biliardo è un tavolo da biliardo a 6 tasche con le seguenti caratteristiche:

  • Le dimensioni sono variabili ( a x b )
  • Nessun attrito: la palla rotolerà per sempre fino a quando non cade in una tasca
  • Le dimensioni delle tasche e delle sfere sono quasi zero. Ciò significa che la palla cadrà nella tasca solo se hanno la stessa posizione.
  • La palla viene posizionata nella buca in basso a sinistra all'inizio (ma non cade in essa)

3cushion

Crea un programma o una funzione completa che prende le dimensioni ( a , b ) della tabella e il numero di cuscini per colpire n come input e restituisce l'angolo in gradi del percorso più breve colpendo esattamente n cuscini prima di cadere in una tasca.

  • a > 0
  • b > 0
  • 0 <= n <10000000
  • 0 < alfa <90 (in gradi) precisione: almeno 10 ^ -6

esempi:

con a = 2, b = 1, n = 1 ci sono tre possibili percorsi: (1) (2) (3) nella figura seguente. il numero (1) è il più corto, quindi l'uscita deve essere atan (2) = 63.43494882292201 gradi

1cushion

La soluzione per a = 2, b = 1, n = 4 è atan (4/3) = 53.13010235415598 gradi

4cushions

campioni di prova:

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

Questo è il golf code / biliardo: vince il codice più corto!


La palla deve colpire esattamente i n cuscini, o almeno i n cuscini?
Peter Taylor,

@PeterTaylor esattamente n cuscini
Damien

il percorso più breve non è sempre avanti e indietro tra il lato sinistro in alto e in basso e poi in uno dei fori centrali?
Eumel,

no, guarda l'esempio 2 1 4. Questo percorso è sqrt (25) = 5 lungo mentre la tua soluzione è sqrt (26)
Damien,

Risposte:


11

Python 2.7, 352 344 281 byte

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 byte grazie a @Dschoni

Spiegazione: invece di calcolare i colpi dei cuscini, sto aggiungendo n tabelle e prendendo i nuovi fori validi: il Billard bordo nero / fori è l'originale, il bordo verde / fori è valido per n = 1, il bordo rosso / fori è valido per n = 2 e così via. Quindi rimuovo i fori non validi (ad esempio la freccia blu per n = 1). Avrò un elenco di buchi validi e le loro coordinate, quindi calcolerò la loro distanza dal punto iniziale e quindi l'angolo della distanza più piccola.
Note:
a = 4.76, b = 3.64, n = 27 - indica 52.66286, cercando di capire perché è stato risolto e salvato 8 byte nel processo = D
a = 43, b = 21, n = 10005 - richiede ~ 80 secondi ( ma dà l'angolo giusto)

versione leggibile:

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

È possibile salvare un byte rimuovendo lo spazio in : degrees
Morgan Thrapp il

Non ho idea di come funzioni (matematicamente) la tua risposta, ma penso che puoi guadagnare 1 byte rimuovendo lo spazio dopo i due punti. :) (Cosa ha detto @MorganThrapp)
basile-henry il

2
Questo percorso è valido, ma non è il più breve in tutti i casi, ad esempio con 2 1 4 ..
Damien

Questo presuppone anche questo b < a. Ciò potrebbe essere risolto facilmente ottenendo il minimo / massimo ae bcomunque.
user81655

fixed (sorta)
Rod

3

Haskell, 133 117 byte

Questa è la mia implementazione:

Con una tabella 2x1, un percorso colpirà esattamente n cuscini prima di entrare in una tasca se: (x-1) / 2 + (y-1) == n e x, y sono numeri primi reciproci. dove x, y sono la distanza della palla sugli assi orizzontale / verticale.

I percorsi sono gli stessi con dimensioni di tabella arbitrarie, quindi non ci resta che aggiornare le lunghezze e gli angoli con (a, b) e mantenere i più brevi. La lunghezza del percorso è sqrt ((x * a / 2) ^ 2 + (y * b) ^ 2) e l'angolo è 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
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.