Jugar al billar

17

En este código de golf, tendrá que determinar la dirección del tiro más corto que golpea exactamente n cojines antes de caer en un bolsillo.

La mesa de billar es una mesa de billar de 6 bolsillos con las siguientes características:

  • Las dimensiones son variables ( a x b )
  • Sin fricción: la pelota rodará para siempre hasta que caiga en un bolsillo
  • Los bolsillos y los tamaños de las bolas son casi cero. Esto significa que la pelota caerá en el bolsillo solo si tienen la misma posición.
  • La pelota se coloca en el hoyo inferior izquierdo al principio (pero no cae dentro)

3cushion

Cree un programa o función completa que tome las dimensiones ( a , b ) de la tabla y el número de cojines para golpear n como entrada y devuelva el ángulo en grados del camino más corto que golpea exactamente n cojines antes de caer en un bolsillo.

  • a > 0
  • b > 0
  • 0 <= n <10000000
  • Precisión 0 < alfa <90 (en grados): al menos 10 ^ -6

ejemplos:

con a = 2, b = 1, n = 1 hay tres caminos posibles: (1) (2) (3) en la siguiente figura. el número (1) es el más corto, por lo que la salida debe ser atan (2) = 63.43494882292201 grados

1cushion

La solución para a = 2, b = 1, n = 4 es atan (4/3) = 53.13010235415598 grados

4cushions

muestras de prueba :

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

Este es el código / billar golf: ¡el código más corto gana!

Damien
fuente
¿La pelota tiene que golpear exactamente n cojines, o al menos n cojines?
Peter Taylor
@PeterTaylor exactamente n cojines
Damien
¿No es el camino más corto siempre de ida y vuelta entre la parte superior e inferior del lado izquierdo y luego en uno de los agujeros del medio?
Eumel
no, mira el ejemplo 2 1 4. Esta ruta es sqrt (25) = 5 de largo, mientras que su solución es sqrt (26)
Damien

Respuestas:

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 gracias a @Dschoni

Explicación: en lugar de calcular los golpes de los cojines, agrego n tablas y tomo los nuevos agujeros como válidos: billard el borde negro / agujeros es el original, el borde verde / agujeros es válido para n = 1, el borde rojo / agujeros es válido para n = 2 y así sucesivamente. Luego elimino los agujeros no válidos (por ejemplo, la flecha azul para n = 1). Tendré una lista de agujeros válidos y sus coordenadas, luego calcularé su distancia desde el punto inicial y luego el ángulo de la distancia más pequeña.
Notas:
a = 4.76, b = 3.64, n = 27 - dé 52.66286, tratando de averiguar por qué se corrigió y guardó 8 bytes en el proceso = D
a = 43, b = 21, n = 10005 - toma ~ 80 segundos ( pero da el ángulo correcto)

versión legible:

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
varilla
fuente
Puede guardar un byte eliminando el espacio en : degrees
Morgan Thrapp
No tengo idea de cómo funciona su respuesta (matemáticamente) pero creo que puede ganar 1 byte eliminando el espacio después de los dos puntos. :) (Lo que dijo @MorganThrapp)
basile-henry
2
Esta ruta es válida, pero no es la más corta en todos los casos, por ejemplo con 2 1 4 ..
Damien
Esto también supone eso b < a. Eso podría solucionarse fácilmente obteniendo el mínimo / máximo de ay bsin embargo.
user81655
fijo (más o menos)
Rod
3

Haskell, 133117 bytes

Esta es mi implementación:

Con una tabla 2x1, una ruta alcanzará exactamente n cojines antes de entrar en un bolsillo si: (x-1) / 2 + (y-1) == ny x, y son primos mutuos. donde x, y son la distancia de la pelota sobre ejes horizontales / verticales.

Las rutas son las mismas con un tamaño de tabla arbitrario, por lo que solo tenemos que actualizar longitudes y ángulos con (a, b) y mantener el más corto. La longitud del camino es sqrt ((x * a / 2) ^ 2 + (y * b) ^ 2) y el ángulo es 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
fuente