Inizia scaglionati


13

Nelle gare in cui i corridori percorrono almeno un giro di una pista curva, le posizioni di partenza per ciascun corridore sono sfalsate, in modo che ciascun corridore percorra la stessa distanza intorno alla pista (altrimenti, il corridore nella corsia più interna avrebbe un enorme vantaggio ).

Date le lunghezze degli assi maggiore e minore (o semi-maggiore e semi-minore, se preferisci) di una traccia ellittica e il numero di corsie nella traccia, emetti le distanze dal punto di partenza della corsia più interna che ogni corsia dovrebbe essere scaglionato.

specificazioni

  • Ogni corsia è un'ellisse con assi semi-maggiori 5 unità più lunghe della corsia più corta successiva. Per semplicità, supponi che le corsie abbiano larghezza 0.
  • La corsia più interna inizia sempre da 0 e ogni altro punto iniziale è un numero intero positivo maggiore o uguale al punto iniziale precedente.
  • L'input e l'output possono essere in qualsiasi formato conveniente e ragionevole.
  • Gli input saranno sempre numeri interi.
  • È necessario calcolare la circonferenza della traccia entro 0,01 unità dal valore effettivo.
  • Le uscite devono essere arrotondate per difetto all'intero più vicino (piano).
  • Il traguardo è il punto di partenza per il corridore più intimo. C'è solo un giro in gara.
  • Le lunghezze degli assi vengono misurate utilizzando la corsia più interna della pista.
  • L'output dello 0 per l'offset della corsia più interna è facoltativo.

Casi test

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

Questi casi di test sono stati generati con il seguente script Python 3, che utilizza un'approssimazione della circonferenza di un'ellisse ideata da 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'approssimazione utilizzata è:

approssimazione della circonferenza dell'ellisse

Infine, ecco un diagramma utile per comprendere i calcoli degli offset:

traccia


Uso l'approssimazione di Ramanujan come hai fatto tu. È quello che dovremmo fare o vuoi che valutiamo la convergenza delle serie infinite?
Adám,

1
@Adám Puoi fare tutto il necessario per ottenere la precisione richiesta. L'approssimazione di Ramanujan è buona per molti valori perché il suo errore è nell'ordine di h**5, che è ben al di sotto 0.01per una vasta gamma di valori.
Mego,

A che serve una precisione minima quando non ci sono limiti alle dimensioni dell'input?
feersum

Risposte:


2

05AB1E , 43 byte

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

Spiegazione

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

Provalo online!


2

Haskell, 103 98 byte

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

1

Python 3, 168 164 byte

Grazie a @ Adám e @Mego per -2 byte ciascuno

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 funzione fche accetta input tramite argomento e restituisce un elenco di offset di corsia, anche 0per la corsia più interna.

Come funziona

Questo utilizza l'approssimazione di Ramanujan. Definiamo semplicemente le funzioni he Cper calcolare il parametro e la circonferenza, quindi sottraggiamo la lunghezza della corsia più interna dalla lunghezza della corsia e del pavimento attuali, per tutte le corsie.

Provalo su Ideone


sqrt(4-3*h(a,b))è più corto come (4-3*h(a,b))**.5e floorpuò essere sostituito da int. Fare entrambi significa che non è necessario importare math.
Mego,

@Mego Grazie. A meno che non sia stupido, quei primi due non sono della stessa lunghezza? Tuttavia, se l'istruzione import viene rimossa, allora c'è il problema di definire pi.
TheBikingViking

Includendo il 3*in h, è necessario salvare due byte.
Adám,

Mi è mancato del tutto il fatto che tu pipossa essere in grado di codificarlo con sufficiente precisione. E sì, i primi due hanno la stessa lunghezza - intendevo senza importazione, ovviamente! : P
Mego,

@Adám Grazie per averlo sottolineato.
TheBikingViking

1

Dyalog APL , 45 byte

Richiede n , quindi a a b . Richiede il ⎕IO←0valore predefinito su molti sistemi.

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

⍳⎕richiedere n , quindi dare {0, 1, 2, ..., n −1)

moltiplicare per cinque per ottenere {0, 5, 10, ..., 5 n -5}

⎕∘.+pronta per un e b , quindi fare un tavolo inoltre:
  una , una +5, un +10, ... un +5 n -5
  b , b 5, b +10, ... b +5 n -5

(... )⌿applica la funzione tra parentesi a ciascuna coppia verticale, ovvero
  f ( a , b ), f ( a +5, b +5), f ( a +10, b +10), ..., f ( a + 5 n -5, b +5 n -5)
  dove f ( x , y ) è *

pi volte

( x + y ) volte

1+ uno più

h ( x , y ) [la funzione h verrà definita in seguito] divisa per

10+ dieci più

.5*⍨ la radice quadrata di

4- quattro meno

h← h ( x , y ), che è

tre volte

2*⍨ la piazza di

( x - y ) diviso per

+ x + y

(⊢-⊃) sul risultato della funzione applicata a ciascuna coppia, sottrarre il valore del primo risultato

1↓ rimuove il primo (zero)

arrotondare per difetto

ProvaAPL online!


* Nel linguaggio procedurale:

-÷+trovare la frazione della differenza tra e la somma di x e y

2*⍨ quadrare quella frazione

moltiplica quel quadrato per tre

h←assegnare quel prodotto a h

4- sottrarre quel prodotto da quattro

.5*⍨ prendi la radice quadrata di quella differenza

10+ aggiungi dieci a quella radice quadrata

dividere h per quella somma

1+ aggiungine uno a quella frazione

moltiplicare tale somma con la somma di x ed y

moltiplicare quel prodotto per pi

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.