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.


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


  • \$\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\$
    – Adám
    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\$
    – user45941
    Aug 22, 2016 at 8:05
  • \$\begingroup\$ What good is a minimum accuracy when there is no bound on the input size? \$\endgroup\$
    – feersum
    Aug 22, 2016 at 15:23

4 Answers 4


Haskell, 103 98 bytes

f a b n|x<-a-b=[floor$(a+b+10*w)!x-(a+b)!x|w<-[1..n-1]]

05AB1E, 43 bytes



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!


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

  • \$\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\$
    – user45941
    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\$ Aug 22, 2016 at 8:27
  • \$\begingroup\$ By including the the 3* in h, you should save two bytes. \$\endgroup\$
    – Adám
    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\$
    – user45941
    Aug 22, 2016 at 8:29
  • \$\begingroup\$ @Adám Thanks for pointing that out. \$\endgroup\$ Aug 22, 2016 at 8:29

Dyalog APL, 45 bytes

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


⍳⎕ 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


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.