Comienzos escalonados

13

En las carreras en las que los corredores recorren al menos una vuelta de una pista curva, las posiciones iniciales para cada corredor se escalonan, de modo que cada corredor recorre la misma distancia alrededor de la pista (de lo contrario, el corredor en el carril más interno tendría una gran ventaja )

Dadas las longitudes de los ejes mayor y menor (o semi-mayor y semi-menor, si lo prefiere) de una pista elíptica y el número de carriles en la pista, muestre las distancias desde el punto de inicio del carril más interno que cada carril. debe ser escalonado

Especificaciones

  • Cada carril es una elipse con ejes semi-principales 5 unidades más largos que el siguiente carril más corto. Para simplificar, suponga que los carriles tienen un ancho de 0.
  • El carril más interno siempre comienza en 0, y cualquier otro punto de partida es un número entero positivo mayor o igual que el punto de partida anterior.
  • La entrada y la salida pueden estar en cualquier formato conveniente y razonable.
  • Las entradas siempre serán enteras.
  • Debe calcular la circunferencia de la pista dentro de 0.01 unidades del valor real.
  • Las salidas se deben redondear al entero más cercano (con piso).
  • La línea de meta es el punto de partida para el corredor más interno. Solo hay una vuelta en la carrera.
  • Las longitudes de los ejes se miden utilizando el carril más interno de la pista.
  • La salida del 0 para el desplazamiento del carril más interno es opcional.

Casos de prueba

Formato: a, b, n -> <list of offsets, excluding innermost lane>

20, 10, 5 -> 30, 61, 92, 124
5, 5, 2 -> 31
15, 40, 7 -> 29, 60, 91, 121, 152, 183
35, 40, 4 -> 31, 62, 94

Estos casos de prueba se generaron con el siguiente script de Python 3, que utiliza una aproximación de la circunferencia de una elipse ideada por Ramanujan:

#!/usr/bin/env python3

import math

a = 35 # semi-major axis
b = 40 # semi-minor axis
n = 4  # number of lanes
w = 5  # spacing between lanes (constant)

h = lambda a,b:(a-b)**2/(a+b)**2
lane_lengths = [math.pi*(a+b+w*i*2)*(1+3*h(a+w*i,b+w*i)/(10+math.sqrt(4-3*h(a+w*i,b+w*i)))) for i in range(n)]

print("{}, {}, {} -> {}".format(a, b, n, ', '.join([str(int(x-lane_lengths[0])) for x in lane_lengths[1:]])))

La aproximación utilizada es:

aproximación de circunferencia de elipse

Finalmente, aquí hay un diagrama útil para comprender los cálculos de las compensaciones:

pista

Mego
fuente
Uso la aproximación de Ramanujan como lo hiciste tú. ¿Es eso lo que se supone que debemos hacer, o quieres que evaluemos la convergencia de las series infinitas?
Adám
1
@ Adám Puede hacer lo que sea necesario para obtener la precisión requerida. La aproximación de Ramanujan es buena para muchos valores porque su error es del orden de h**5, que está muy 0.01por debajo de una amplia gama de valores.
Mego
¿De qué sirve una precisión mínima cuando no hay límite en el tamaño de entrada?
feersum

Respuestas:

2

05AB1E , 43 bytes

UVFXY-nXY+WZn/3*©T4®-t+/>Z*žq*5DX+UY+V})¬-ï

Explicación

UV                                           # X = a, Y = b
  F                                   }      # n times do
   XY-n                                      # (a-b)^2
       XY+W                                  # Z = (a + b)
             /                               # divide (a-b)^2
           Zn                                # by (a+b)^2
              3*                             # multiply by 3
                ©                            # C = 3h
                       /                     # 3h divided by 
                 T                           # 10
                      +                      # +
                  4®-t                       # sqrt(4-3h)
                        >                    # increment
                         Z*žq*               # times (a + b)*pi
                              5DX+UY+V       # increase a and b by 5
                                       )     # wrap in list of circumferences
                                        ¬-   # divide by inner circumference
                                          ï  # floor
                                             # implicitly display

Pruébalo en línea!

Emigna
fuente
2

Haskell, 103 98 bytes

c!d|h<-3*d*d/c/c=pi*c*(1+h/(10+sqrt(4-h)))
f a b n|x<-a-b=[floor$(a+b+10*w)!x-(a+b)!x|w<-[1..n-1]]
Damien
fuente
1

Python 3, 168 164 bytes

Gracias a @ Adám y @Mego por -2 bytes cada uno

from math import*
h=lambda a,b:3*(a-b)**2/(a+b)**2;C=lambda a,b:pi*(a+b)*(1+h(a,b)/(10+sqrt(4-h(a,b))))
f=lambda a,b,n:[int(C(a+i*5,b+i*5)-C(a,b))for i in range(n)]

Una función fque toma datos a través de argumentos y devuelve una lista de desplazamientos de carril, incluso 0para el carril más interno.

Cómo funciona

Esto usa la aproximación de Ramanujan. Simplemente definimos funciones hy Cpara calcular el parámetro y la circunferencia, luego restamos la longitud del carril más interno de la longitud del carril y piso actuales, para todos los carriles.

Pruébalo en Ideone

TheBikingViking
fuente
sqrt(4-3*h(a,b))es más corto como (4-3*h(a,b))**.5y floorpuede ser reemplazado por int. Hacer ambas cosas significa que no necesita importar math.
Mego
@Mego Gracias. A menos que sea estúpido, ¿no son esos dos primeros del mismo largo? Sin embargo, si se elimina la declaración de importación, existe el problema de definir pi.
TheBikingViking
Al incluir el 3*en h, debe guardar dos bytes.
Adám
Echaba mucho de menos que utilizas. piPodrías codificarlo con suficiente precisión. Y sí, los dos primeros tienen la misma longitud, ¡quiero decir sin importar, por supuesto! : P
Mego
@ Adám Gracias por señalar eso.
TheBikingViking
1

Dyalog APL , 45 bytes

Solicita n , entonces para una b . Requiere ⎕IO←0cuál es el predeterminado en muchos sistemas.

1↓(⊢-⊃)(○+×1+h÷10+.5*⍨4-h3×2*⍨-÷+)⌿⎕∘.+5×⍳⎕

⍳⎕solicite n , luego dé {0, 1, 2, ..., n −1)

se multiplica por cinco para obtener {0, 5, 10, ..., 5 n -5}

⎕∘.+pronta para un y b , a continuación, hacer una tabla de sumar:
  una , un 5, un 10, ... un 5 n -5
  b , b 5, b 10, ... b 5 n −5

(... )⌿aplique la función entre paréntesis a cada par vertical, es decir,
  f ( a , b ), f ( a +5, b +5), f ( a +10, b +10), ..., f ( a + 5 n -5, b 5 n -5)
  donde f ( x , y ) es *

pi veces

( x + y ) veces

1+ uno más

h ( x , y ) [la función h se definirá más adelante] dividida por

10+ diez plus

.5*⍨ la raíz cuadrada de

4- cuatro menos

h← h ( x , y ), que es

tres veces

2*⍨ el cuadrado de

( x - y ) dividido por

+ x + y

(⊢-⊃) en el resultado de la función aplicada a cada par, reste el valor del primer resultado

1↓ eliminar el primero (cero)

redondear a la baja

TryAPL en línea!


* En lenguaje procesal:

-÷+encontrar la fracción de la diferencia entre y la suma de x e y

2*⍨ cuadrar esa fracción

multiplica ese cuadrado por tres

h←asignar ese producto a h

4- reste ese producto de cuatro

.5*⍨ tomar la raíz cuadrada de esa diferencia

10+ agrega diez a esa raíz cuadrada

dividir h por esa suma

1+ agregue uno a esa fracción

multiplica esa suma con la suma de x e y

multiplica ese producto por pi

Adán
fuente