# Circumference of an ellipse

## Challenge

### Code explanation

y       % Implicit inputs: a, b. Duplicate from below
% STACK: a, b, a
/       % Divide
% STACK: a, b/a
U_Q     % Square, negate, add 1
% STACK: a, 1-(b/a)^2
.5t_h   % Push 0.5, duplicate, negate, concatenate
% STACK: a, 1-(b/a)^2, [0.5, -0.5]
1       % Push 1
% STACK: a, 1-(b/a)^2, [0.5, -0.5], 1
b       % Bubble up in the stack
% STACK: a, [0.5, -0.5], 1, 1-(b/a)^2
Zh      % Hypergeometric function, 2F1
% STACK: a, 2F1([0.5, -0.5], 1, 1-(b/a)^2)
*       % Multiply
% STACK: a * 2F1([0.5, -0.5], 1, 1-(b/a)^2)
YPE     % Push pi, multiply by 2
% STACK: a * 2F1([0.5, -0.5], 1, 1-(b/a)^2), 2*pi
*       % Multiply. Implicit display
% STACK: 2*pi*a * 2F1([0.5, -0.5], 1, 1-(b/a)^2)


# Charcoal, 52 bytes

≧×χφＮθＮηＩ×⁴ΣＥＥφＥ²∕⁺ιλφ₂⁺××θθ⁻Σι⊗₂Πι××ηη⁻⁻²Σι⊗₂⁻⊕ΠιΣι


Try it online! Link is to verbose version of code. Works by approximating the line integral for a quadrant. The default precision is unfortunately only ~5 significant figures so the first four bytes are needed to increase the precision to ~7 significant figures. Further increases are possible for the same byte count but then it becomes too slow to demonstrate on TIO. Explanation:

≧×χφ


Increase the number of pieces $$\ n \$$ in which to divide the quadrant from $$\ 1,000 \$$ to $$\ 10,000 \$$. ≧×φφ would increase it to $$\ 1,000,000 \$$ but that's too slow for TIO.

ＮθＮη


Input the ellipse's axes $$\ a \$$ and $$\ b \$$.

Ｉ×⁴Σ


After calculating the approximate arc length of each piece into which the quadrant was subdivided, take the sum, multiply by $$\ 4 \$$ for the whole ellipse and output the result.

ＥＥφＥ²∕⁺ιλφ


Create a list of pieces of the quadrant. In the ellipse equation $$\ \left ( \frac x a \right ) ^ 2 + \left ( \frac y b \right ) ^ 2 = 1 \$$ we can set $$\ \left ( \frac {x_i} a \right ) ^ 2 = \frac i n \$$ and $$\ \left ( \frac {y_i} b \right ) ^ 2 = 1 - \frac i n \$$. Given a piece index $$\ i \$$ we want to calculate the distance between $$\ ( x_i, y_i ) \$$ and $$\ ( x _{i+1}, y_{i+1} ) \$$. For each $$\ i \$$ we calculate $$\ j = \frac i n \$$ and $$\ k = \frac {i+1} n \$$ and loop over the list.

₂⁺××θθ⁻Σι⊗₂Πι××ηη⁻⁻²Σι⊗₂⁻⊕ΠιΣι


The distance $$\ \sqrt { ( a \sqrt k - a \sqrt j ) ^ 2 + ( b \sqrt { 1 - j } - b \sqrt { 1 - k } ) ^ 2 } \$$ expands to $$\ \sqrt { a^2 \left ( j + k - 2 \sqrt { j k } \right ) + b^2 \left ( (1 - j) + (1 - k) - 2 \sqrt { (1 - j) (1 - k) } \right ) } \$$ which expands to $$\ \sqrt { a^2 \left ( j + k - 2 \sqrt { j k } \right ) + b^2 \left ( 2 - (j + k) - 2 \sqrt { 1 + j k - (j + k) } \right ) } \$$.

I÷S²3×÷ạ4½+⁵Ʋ$‘×S×ØP  A monadic Link accepting a pair of [a, b] which yields the result of formula 5. Try it online! I thought formula 4 would be the way to go, but only got 21: 9Ḷ.c×⁹I÷S*⁸¤²ʋ€×ØP×SS  Try it online! # Haskell, 73 bytes e a b=(a+b)*pi*(1+3*l/(10+sqrt(4-3*l))+3*l^5/2^17)where l=((a-b)/(a+b))^2  Experimenting with an improved version of (5): $$E(a,b) = \pi (a+b) \left( 1 + \frac{3h^2}{10 + \sqrt{4-3h^2}} + \frac{3h^{10}}{2^{17}}\right)$$ # Pyth, 40 bytes A,hQeQJc^-GH2^+GH2**.n0+GHhc*3J+T@-4*3J2  Try it online! Just formula 5, like most other answers here. # Perl 5, 70 bytes sub{my$s;map$s+=sqrt+($_[0]*cos)**2+($_[1]*sin)**2,0..1570795;4e-6*$s}


Try it online!

# Perl 5, 78 bytes

sub f{($a,$b)=@_;$H=3*(($a-$b)/($a+=$b))**2;3.141593*$a*(1+$H/(10+sqrt 4-$H))}


With the a+=b trick stolen from the Javascript answer.

Try it online!

Or this one which is 13 bytes less (but uses core module List::Util)

# Perl 5 -MList::Util=sum, 7465 65+16 bytes

sub f{4e-6*sum map sqrt+($_[0]*cos)**2+($_[1]*sin)**2,0..1570795}


Try it online!

Which numerically calculates a variant of formula (1).

I was surprised this worked with sin and cos of integers up to 1570795 ≈ 500000π. But the tests in the question in "Try it online" has relative error < 0.000001. Guess sin²(the integers) is "averaged out" good enough.

• Our usual rules require you to include use List::Util 'sum'; in the byte count, no? That said, map sqrt(($_[0]*cos$_)**2+($_[1]*sin$_)**2) saves 4 bytes. – Anders Kaseorg Oct 2 at 9:06
• Maybe? I swapped the first answer to my four byte longer answer. I thought that since List::Util has been a core module for many years (since 2002), all normal Perl installations have it. Seems a matter of "administration" for a language which functions are true built-ins and which are semi-built-in in core modules that doesnt require extra installations. I've seen C answers without #include <math.h> and Javascript answers regularly omits f= in function definitions. – Kjetil S. Oct 3 at 18:20
• @AndersKaseorg Thx for the cos-sin-tip. And it can even loose five extra bytes with map sqrt+($_[0]*cos)**2+($_[1]*sin)**2. I get a warning about sqrt not having parens. Sin and cos uses \$_ without args. – Kjetil S. Oct 3 at 18:24
• There’s no exemption for matters of “administration”. A C program can still run (with a warning) without #include <math.h>, and we allow function expressions without f= (unless the function is recursive). Your program does not run without use List::Util 'sum';. The issue is not whether it exists to be imported; the issue is that must be explicitly imported to be used even when it exists. – Anders Kaseorg Oct 3 at 23:22
• As for -MList::Util=sum, we count the command line flag as +17 bytes. – Anders Kaseorg Oct 3 at 23:32

# Symja, 35 bytes

f=N(4*#1*EllipticE(1-#2*#2/#1/#1))&


Try It Online!

A port of the SageMath answer in Symja.

# Japt, 35 bytes

MP*ºH=3*(U-V ²/(U±V)/(A+(4-H/U ¬ +U


Try it