# Euler's Geometry Puzzle

Today (or tomorrow, depending on your timezone, by the time of posting) is the birthday of the great mathematician and physicist Leonhard Euler. To celebrate his birthday, this challenge is about one of his theorems in geometry.

For a triangle, we define its incircle to be the largest circle inside the triangle and its circumcircle to be the circle that passes through all of the traingle's vertices.

Consider a triangle in a plane, we plot the center of its incircle I (sometimes called incenter) and the center of its circumcircle O (sometimes called circumcenter). Let $$\r\$$ be the radius of the incircle, $$\R\$$ be the radius of circumcircle, $$\d\$$ be the distance between I and O. Euler's theorem in geometry states that $$\d^2=R(R-2r)\$$.

# The challenge

In the spirit of this theorem, your task, is for a triangle given by the lengths of its three sides, output $$\d\$$ (the distance between incenter I and circumcenter O described above).

• Your code needs to take only the length of the three sides of triangle and output $$\d\$$. Inputs and outputs can be in any reasonable format.
• The absolute error or relative error from your output and correct answer must be no greater than $$\10^{-2}\$$.
• It's guaranteed that the three side lengths are positive integers and can form a non-degenerate triangle.
• Standard loopholes are forbidden.

Since this is a , the shortest code in bytes wins!

# Examples

In the samples, the outputs are rounded to 3 decimal places. You, however, are free to round them to more decimal places.

[a,b,c]       -> d
[2,3,4]       -> 1.265
[3,4,5]       -> 1.118
[3,5,7]       -> 3.055
[7,9,10]      -> 1.507
[8,8,8]       -> 0.000
[123,234,345] -> 309.109


List of sample inputs:

[[2,3,4],[3,4,5],[3,5,7],[7,9,10],[8,8,8],[123,234,345]]

# JavaScript (ES7),  80 74 66  65 bytes

(a,b,c)=>(s=a+b+c,(p=a*b*c/s)*p/4*(s/=2)/(s-a)/(s-b)/(s-c)-p)**.5


Try it online!

### How?

This is derived from:

• The semiperimeter $$\s\$$ of the triangle:

$$s=\frac{a+b+c}{2}$$

• The circumradius $$\R\$$ of the triangle:

$$R=\frac{abc}{4\sqrt{s(s-a)(s-b)(s-c)}}$$

• The product of the inradius $$\r\$$ and the circumradius:

$$rR=\frac{abc}{2(a+b+c)}=\frac{abc}{4s}$$

• Euler's theorem:

$$d=\sqrt{R(R-2r)}=\sqrt{R^2-2rR}=\sqrt{R^2-\frac{abc}{2s}}$$

• Clever... using the perimeter at first, and then halving it. – Tim Pederick Apr 15 '20 at 5:55
• 62 bytes – newbie Apr 15 '20 at 6:35
• @newbie Nice! But I think I'll leave this one unchanged, since the shorter version has already been posted by Tim Pederick. – Arnauld Apr 15 '20 at 7:49

# Python 3, 66 bytes

This formerly took advantage of the new assignment expressions ("walrus operator") introduced in Python 3.8. Thanks to commentors, I've taken that out, so it works on previous versions too!

lambda a,b,c:((a*b*c/(b+c-a)/(a+c-b)/(a+b-c)-1)*a*b*c/(a+b+c))**.5


Try it online!

It's based on the same calculations described in Arnauld's answer, but using the perimeter $$\p\$$ instead of the semiperimeter $$\s\$$: \begin{aligned}\\ p&=a+b+c\\ &=2s \end{aligned}\\ \therefore d=\sqrt{R^2-\frac{abc}{p}}\\ \text{and } R^2=\frac{\left(abc\right)^2}{p(p-2a)(p-2b)(p-2c)}

The grand total savings of this rearrangement is... two bytes.

Factoring $$\p\$$ out and expanding the terms in the denominator means I don't have to store $$\p\$$, saving another three bytes. I also stored the product $$\abc\$$ in a variable $$\m\$$, which saved some bytes at first... but it could later be factored out, turning the brackets-and-walrus into a liability, not a savings! Here's the final formula: \begin{aligned} d&=\sqrt{\frac{\left(abc\right)^2}{p(p-2a)(p-2b)(p-2c)}-\frac{abc}{p}}\\ &=\sqrt{\left(\frac{abc}{(b+c-a)(a+c-b)(a+b-c)}-1\right)\frac{abc}{p}} \end{aligned}

• 70 bytes – dingledooper Apr 15 '20 at 6:04
• @dingledooper: Thanks! I'd just realised the same thing myself: storing $m$ meant that I could multiply by it instead of squaring, saving a byte. – Tim Pederick Apr 15 '20 at 6:10
• Actually... 66 bytes – newbie Apr 15 '20 at 6:34
• @newbie And here I thought factoring out $m$ wouldn't save anything... I hadn't realised that it meant being able to drop a pair of parentheses. Thanks! – Tim Pederick Apr 15 '20 at 7:25
• @dingledooper: facepalm Thanks. Done. – Tim Pederick Apr 16 '20 at 5:13

# Charcoal, 31 18 bytes

Ｉ₂∕×⊖∕ΠθΠ⁻Σθ⊗θΠθΣθ


Try it online! Link is to verbose version of code. Takes input as a vector of doubles and outputs a double. Explanation:

\begin{align}d &=\sqrt{R(R-2r)}\\ &=\sqrt{R^2-2Rr}\\ &=\sqrt{\left(\frac{abc}{4\Delta}\right)^2-\frac{abc}{2s}}\\ &=\sqrt{\frac{(abc)^2}{16\Delta^2}-\frac{abc}{2s}}\\ &=\sqrt{\frac{(abc)^2}{2s(2s-2a)(2s-2b)(2s-2c)}-\frac{abc}{2s}}\\ &=\sqrt{\frac{abc}{2s}\left(\frac{abc}{(2s-2a)(2s-2b)(2s-2c)}-1\right)}\\ \end{align}

where $$\ 2s=a+b+c \$$ and $$\ \Delta=\sqrt{s(s-a)(s-b)(s-c)} \$$.

            ⊗θ      [2a, 2b, 2c]
⁻Σθ        Vectorised subtract from a+b+c
Π           Take the product
∕Πθ            Divide abc by that
⊖               Decrement
×          Πθ    Multiply by abc
∕             Σθ  Divide by a+b+c
₂                  Take the square root
Ｉ                   Cast to string
Implicitly print


# 05AB1E, 2322212015 14 bytes

PDIœÆPt/<*IO/t


-5 bytes porting @Neil's Charcoal answer, so make sure to upvote him!!
-1 byte thanks to @Grimmy.

Explanation:

P              # Take the product of the (implicit) input-list
#  [a,b,c] → abc
D             # Duplicate it
Iœ           # Get all permutations of the input-triplet
#  [a,b,c] → [[a,b,c],[a,c,b],[b,a,c],[b,c,a],[c,a,b],[c,b,a]]
Æ          # Reduce each by subtracting:
#  → [a-b-c,a-c-b,b-a-c,b-c-a,c-a-b,c-b-a]
P         # Take the product of that
#  → (a-b-c)(a-c-b)(b-a-c)(b-c-a)(c-a-b)(c-b-a)
#   → (a-b-c)²*(b-a-c)²*(c-a-b)²
t        # Take the square-root
#  → sqrt((a-b-c)²*(b-a-c)²*(c-a-b)²)
/       # Divide the initially duplicated product by it
#  → abc/(sqrt((a-b-c)²*(b-a-c)²*(c-a-b)²))
<      # Decrease it by 1
#  → abc/(sqrt((a-b-c)²*(b-a-c)²*(c-a-b)²))-1
*     # Multiply it by the initial product
#  → abc(abc/(sqrt((a-b-c)²*(b-a-c)²*(c-a-b)²))-1)
IO/  # Divide it by the input-sum
#  → abc(abc/(sqrt((a-b-c)²*(b-a-c)²*(c-a-b)²))-1)/(a+b+c)
t # And take the square-root of that
#  → sqrt(abc(abc/(sqrt((a-b-c)²*(b-a-c)²*(c-a-b)²))-1)/(a+b+c))
# (after which it is output implicitly as result)


Or as a single formula:

$$d=\sqrt{\frac{abc\left(\frac{abc}{\sqrt{(a-b-c)^2\times(b-a-c)^2\times(c-a-b)^2}}-1\right)}{a+b+c}}$$

• My attempt to port the formula I came up with clocks in at 17 bytes, which is bad, since it's only 18 in Charcoal... – Neil Apr 14 '20 at 15:57
• @Neil Nice approach! I got it down to 15 bytes porting your answer. Was about to go eat dinner, so will update it afterwards. :) – Kevin Cruijssen Apr 14 '20 at 16:04
• @Neil You're not the first one who couldn't find ·; I see answers overlooking it so many times for some reason.. I personally never really use the info.txt but use the wiki Commands page instead (although it is lacking some new builtins every now and then..) Btw, using the x we could still end up at 15 bytes: PDIxsOαP/<*IO/t. ;) – Kevin Cruijssen Apr 14 '20 at 17:53
• It doesn't help that one says a * 2 and the other says 2 * a... – Neil Apr 14 '20 at 18:53
• IOI·-P => IœÆPt for -1 (verify all) – Grimmy Apr 23 '20 at 10:28

# Java 8, 67 bytes

(a,b,c)->Math.sqrt(a*b*c*(a*b*c/(b+c-a)/(a+c-b)/(a+b-c)-1)/(a+b+c))


Try it online.

Not much to say. Uses the same formula as in @TimPederick's Python answer, which was based on @Arnauld's JavaScript answer, but which uses a rather similar formula as @Neil's Charcoal answer.

$$d=\sqrt{\frac{abc\left(abc\div(b+c-a)\div(a+c-b)\div(a+b-c)-1\right)}{a+b+c}}$$

# Io, 87 bytes

method(a,b,c,((y :=b*a*c/(z :=((b+c-a)*(c+a-b)*(a+b-c)/(x :=a+b+c))**.5)/x)*(y-z))**.5)


Try it online!

# C (gcc), 76 72 bytes

Saved 4 bytes thanks to ceilingcat!!!

#define f(a,b,c)sqrt(a*b*c*(a*b*c/(0.+b+c-a)/(a+c-b)/(a+b-c)-1)/(a+b+c))


Try it online!

Port of Kevin Cruijssen's Java answer.

• @ceilingcat Nice one - thanks! :-) – Noodle9 Apr 15 '20 at 18:00

# APL (Dyalog Unicode), 22 bytes

.5*⍨×/÷+/÷¯1+⊢×.÷+/-+⍨


Try it online!

Yet another port of Tim Pederick's Python answer.

\begin{align} d&=\sqrt{\left(\frac{abc}{(b+c-a)(a+c-b)(a+b-c)}-1\right)\frac{abc}{a+b+c}} \\ &=\sqrt{\frac{abc}{\frac{a+b+c}{\frac{abc}{(b+c-a)(a+c-b)(a+b-c)}-1}}} \end{align}

Kind of ugly, but this is precisely what the code does. Requires ⎕DIV←1, i.e. division by 0 gives 0 (otherwise a=b=c case will throw an error).

### How it works

.5*⍨×/÷+/÷¯1+⊢×.÷+/-+⍨  ⍝ Input: a 3-length vector [a b c]
+/-+⍨  ⍝ (a+b+c) - [2a, 2b, 2c] = [b+c-a, c+a-b, a+b-c]
⊢×.÷       ⍝ product([a,b,c] ÷ above)
¯1+           ⍝ above minus 1
×/÷+/÷  ⍝ product(a,b,c) ÷ (sum(a,b,c) ÷ above)
.5*⍨        ⍝ square root


# Forth (gforth), 90 bytes

: f dup 2over * * s>f fdup 3. do dup 2over - - s>f f/ rot loop 1e f- f* + + s>f f/ fsqrt ;


Try it online!

Port of Kevin Cruijssen's Java answer. Since the inputs are positive integers, it takes the input from the data stack and returns the result through the FP stack.

A separate FP stack makes the task a bit easier, but having to work through three alternating sums explicitly is definitely a pain.

In order to copy top three elements, I used dup 2over which converts a b c into a b c c a b. Thankfully I didn't need exactly "3dup" because addition + and multiplication * are commutative, and alternating sums (c - (a - b)) are calculated for all three rotations (abc, bca, cab).

: f ( a b c -- f:result )
dup 2over * * s>f fdup  ( a b c ) ( f: prod prod )
3. do dup 2over - - s>f f/ rot loop  ( a b c ) ( f: prod prod/rots )
1e f- f* + + s>f f/ fsqrt
;