Départs échelonnés

13

Dans les courses où les coureurs font au moins un tour de piste courbe, les positions de départ de chaque coureur sont échelonnées, de sorte que chaque coureur parcourt la même distance autour de la piste (sinon, le coureur dans la voie la plus intérieure aurait un énorme avantage ).

Compte tenu des longueurs des axes majeurs et mineurs (ou semi-majeur et semi-mineur, si vous préférez) d'une piste elliptique et du nombre de voies dans la piste, affichez les distances à partir du point de départ de la voie la plus intérieure que chaque voie devrait être échelonné.

Caractéristiques

  • Chaque voie est une ellipse avec des axes semi-majeurs 5 unités plus longues que la voie la plus courte suivante. Par souci de simplicité, supposons que les voies ont une largeur de 0.
  • La voie la plus intérieure commence toujours à 0, et chaque autre point de départ est un entier positif supérieur ou égal au point de départ précédent.
  • L'entrée et la sortie peuvent être dans n'importe quel format pratique et raisonnable.
  • Les entrées seront toujours des entiers.
  • Vous devez calculer la circonférence de la piste à 0,01 unité près de la valeur réelle.
  • Les sorties doivent être arrondies à l'entier le plus proche (plancher).
  • La ligne d'arrivée est le point de départ du coureur le plus interne. Il n'y a qu'un tour dans la course.
  • Les longueurs des axes sont mesurées en utilisant la voie la plus intérieure de la piste.
  • La sortie du 0 pour le décalage de la voie la plus intérieure est facultative.

Cas de test

Format: 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

Ces cas de test ont été générés avec le script Python 3 suivant, qui utilise une approximation de la circonférence d'une ellipse conçue par 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:]])))

L'approximation utilisée est:

approximation de la circonférence de l'ellipse

Enfin, voici un diagramme utile pour comprendre les calculs des décalages:

Piste

Mego
la source
J'utilise l'approximation de Ramanujan comme vous l'avez fait. Est-ce ce que nous sommes censés faire, ou voulez-vous que nous évaluions la convergence de la série infinie?
Adám
1
@ Adám Vous pouvez faire tout ce qu'il faut pour obtenir la précision requise. L'approximation de Ramanujan est bonne pour de nombreuses valeurs car son erreur est de l'ordre de h**5, ce qui est bien inférieur 0.01à une large gamme de valeurs.
Mego
À quoi sert une précision minimale lorsqu'il n'y a pas de limite sur la taille d'entrée?
feersum

Réponses:

2

05AB1E , 43 octets

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

Explication

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

Essayez-le en ligne!

Emigna
la source
2

Haskell, 103 98 octets

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
la source
1

Python 3, 168 164 octets

Merci à @ Adám et @Mego pour -2 octets chacun

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)]

Une fonction fqui prend une entrée via un argument et renvoie une liste de décalages de voie, y compris 0pour la voie la plus intérieure.

Comment ça fonctionne

Cela utilise l'approximation de Ramanujan. Nous définissons simplement les fonctions het Cpour calculer le paramètre et la circonférence, puis soustrayons la longueur de la voie la plus intérieure de la longueur de la voie et du plancher actuels, pour toutes les voies.

Essayez-le sur Ideone

TheBikingViking
la source
sqrt(4-3*h(a,b))est plus court (4-3*h(a,b))**.5et floorpeut être remplacé par int. Faire ces deux signifie que vous n'avez pas besoin d'importer math.
Mego
@Mego Merci. À moins que je sois stupide, ces deux premiers ne sont-ils pas de la même longueur? Cependant, si l'instruction import est supprimée, il y a alors le problème de la définition de pi.
TheBikingViking
En incluant le 3*in h, vous devez enregistrer deux octets.
Adám
J'ai manqué totalement que vous utilisiez piVous pourriez être en mesure de coder en dur avec suffisamment de précision. Et oui, les deux premiers sont de la même longueur - je voulais dire sans l'importation, bien sûr! : P
Mego
@ Adám Merci de l'avoir signalé.
TheBikingViking
1

Dyalog APL , 45 octets

Demande pour n , puis pour a b . Requiert ⎕IO←0ce qui est par défaut sur de nombreux systèmes.

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

⍳⎕demander n , puis donner {0, 1, 2, ..., n −1)

multiplier par cinq pour obtenir {0, 5, 10, ..., 5 n -5}

⎕∘.+invite pour un et b , puis faire une table d'addition:
  un , un 5, un 10, ... une +5 n -5
  b , b 5, b 10, ... b +5 n -5

(... )⌿applique la fonction entre parenthèses à chaque paire verticale, c'est-à-dire
  f ( a , b ), f ( a +5, b +5), f ( a +10, b +10), ..., f ( a + 5 n -5, b 5 n -5)
  où f ( x , y ) est *

pi fois

( x + y ) fois

1+ un plus

h ( x , y ) [la fonction h sera définie ultérieurement] divisée par

10+ dix plus

.5*⍨ la racine carrée de

4- quatre moins

h← h ( x , y ), qui est

trois fois

2*⍨ le carré de

( x - y ) divisé par

+ x + y

(⊢-⊃) sur le résultat de la fonction appliquée à chaque paire, soustrayez la valeur du premier résultat

1↓ supprimer le premier (zéro)

arrondir vers le bas

TryAPL en ligne!


* En langage procédural:

-÷+trouver la fraction de la différence entre et la somme de x et y

2*⍨ carré cette fraction

multiplier ce carré par trois

h←affecter ce produit à h

4- soustraire ce produit de quatre

.5*⍨ prendre la racine carrée de cette différence

10+ ajouter dix à cette racine carrée

diviser h par cette somme

1+ ajouter un à cette fraction

multiplier cette somme par la somme de x et y

multiplier ce produit par pi

Adam
la source