15
\$\begingroup\$

In races in which racers go around at least one turn of a curved track, the starting positions for each racer are staggered, so that each racer travels the same distance around the track (otherwise, the racer in the innermost lane would have a huge advantage).

Given the lengths of the major and minor axes (or semi-major and semi-minor, if you'd prefer) of an elliptical track and the number of lanes in the track, output the distances from the innermost lane's starting point that each lane should be staggered.

Specifications

  • Each lane is an ellipse with semi-major axes 5 units longer than the next-shortest lane. For simplicity, assume that the lanes have 0 width.
  • The innermost lane always starts at 0, and every other starting point is a positive integer greater than or equal to the previous starting point.
  • Input and output may be in any convenient and reasonable format.
  • The inputs will always be integers.
  • You must calculate the circumference of the track to within 0.01 units of the actual value.
  • Outputs are to be rounded down to the nearest integer (floored).
  • The finish line is the starting point for the innermost racer. There is only one lap in the race.
  • The lengths of the axes are measured using the innermost lane of the track.
  • Outputting the 0 for the innermost lane's offset is optional.

Test Cases

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 

These test cases were generated with the following Python 3 script, which uses an approximation of the circumference of an ellipse devised by 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:]]))) 

The approximation used is:

ellipse circumference approximation

Finally, here is a helpful diagram for understanding the calculations of the offsets:

track

\$\endgroup\$
3
  • \$\begingroup\$ I use Ramanujan's approximation like you did. Is that what we're supposed to do, or do you want us to evaluate the convergence of the infinite series? \$\endgroup\$ Commented Aug 22, 2016 at 8:04
  • 1
    \$\begingroup\$ @Adám You can do whatever it takes to get the required precision. The Ramanujan approximation is good for many values because its error is on the order of h**5, which is well under 0.01 for a wide range of values. \$\endgroup\$ Commented Aug 22, 2016 at 8:05
  • \$\begingroup\$ What good is a minimum accuracy when there is no bound on the input size? \$\endgroup\$ Commented Aug 22, 2016 at 15:23

4 Answers 4

2
\$\begingroup\$

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]] 
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 43 bytes

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

Explanation

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 

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Python 3, 168 164 bytes

Thanks to @Adám and @Mego for -2 bytes each

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

A function f that takes input via argument and returns a list of lane offsets, including 0 for the innermost lane.

How it works

This uses Ramanujan's approxiamtion. We simply define functions h and C for calculating the parameter and circumference, then subtract the length of the innermost lane from the length of the current lane and floor, for all lanes.

Try it on Ideone

\$\endgroup\$
5
  • \$\begingroup\$ sqrt(4-3*h(a,b)) is shorter as (4-3*h(a,b))**.5, and floor can be replaced by int. Doing both of those means you don't need to import math. \$\endgroup\$ Commented Aug 22, 2016 at 8:23
  • \$\begingroup\$ @Mego Thanks. Unless I'm being stupid, aren't those first two the same length? However, if the import statement gets removed, there is then the problem of defining pi. \$\endgroup\$ Commented Aug 22, 2016 at 8:27
  • \$\begingroup\$ By including the the 3* in h, you should save two bytes. \$\endgroup\$ Commented Aug 22, 2016 at 8:28
  • \$\begingroup\$ I totally missed that you use pi You might be able to hardcode it with enough precision. And yeah, the first two are the same length - I meant without the import, of course! :P \$\endgroup\$ Commented Aug 22, 2016 at 8:29
  • \$\begingroup\$ @Adám Thanks for pointing that out. \$\endgroup\$ Commented Aug 22, 2016 at 8:29
1
\$\begingroup\$

Dyalog APL, 45 bytes

Prompts for n, then for a b. Requires ⎕IO←0 which is default on many systems.

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

⍳⎕ prompt for n, then give {0, 1, 2, ..., n−1)

multiply by five to get {0, 5, 10, ..., 5​n−5}

⎕∘.+ prompt for a and b, then make an addition table:
  a, a+5, a+10, ... a+5​n−5
  b, b+5, b+10, ... b+5​n−5

(...)⌿ apply the parenthesised function to each vertical pair, i.e.
  f(a, b), f(a+5, b+5), f(a+10, b+10), ..., f(a+5​n−5, b+5​n−5)
  where f(x, y) is*

pi times

(x + y) times

1+ one plus

h(x, y) [the function h will be defined later] divided by

10+ ten plus

.5*⍨ the square-root of

4- four minus

h← h(x, y), which is

three times

2*⍨ the square of

(xy) divided by

+ x + y

(⊢-⊃) on the result of the function applied to each pair, subtract the value of the first result

1↓ remove the first (zero)

round down

TryAPL online!


*In procedural language:

-÷+ find the fraction of the difference between and the sum of x and y

2*⍨ square that fraction

multiply that square by three

h← assign that product to h

4- subtract that product from four

.5*⍨ take the square-root of that difference

10+ add ten to that square-root

divide h by that sum

1+ add one to that fraction

multiply that sum with the sum of x and y

multiply that product by pi

\$\endgroup\$