24
\$\begingroup\$

Output the area \$A\$ of a triangle given its side lengths \$a, b, c\$ as inputs. This can be computed using Heron's formula:

$$ A=\sqrt{s(s-a)(s-b)(s-c)}\textrm{, where } s=\frac{a+b+c}{2}.$$

This can be written in various ways, such as

$$ A= \frac{1}{4}\sqrt{(a+b+c)(-a+b+c)(a-b+c)(a+b-c)}$$ $$ A= \frac{1}{4}\sqrt{(a^2+b^2+c^2)^2-2(a^4+b^4+c^4)}$$

See Wikipedia for more. Related: What are my dimensions?

The inputs will be three positive integers that satisfy the triangle inequality and so are sides of a non-degenerate triangle. While the order of the three sides doesn't affect the output, you may not assume they're given in a particular order like sorted. You may take inputs in a list or tuple or the like. Any reasonable float output is fine.

Test cases

1 1 1 -> 0.4330
3 4 5 -> 6.0000
9 3 7 -> 8.7856
\$\endgroup\$
6
  • \$\begingroup\$ There is a similar but closed challenge. \$\endgroup\$
    – alephalpha
    Jul 28, 2022 at 1:32
  • \$\begingroup\$ Similar challenge on anagol (round to int) \$\endgroup\$
    – Sisyphus
    Jul 28, 2022 at 1:43
  • \$\begingroup\$ Can you output an exact real number, if the language natively supports such a type? \$\endgroup\$
    – A. Rex
    Jul 29, 2022 at 17:45
  • \$\begingroup\$ @A.Rex What do you mean, like outputting sqrt(n)? \$\endgroup\$
    – xnor
    Jul 29, 2022 at 23:10
  • 1
    \$\begingroup\$ @A.Rex If it's a fraction, that's fine, but not if it has square roots. \$\endgroup\$
    – xnor
    Aug 1, 2022 at 12:17

34 Answers 34

11
\$\begingroup\$

Wolfram Language (Mathematica), 20 bytes

N@*Area@*SSSTriangle

Try it online!

Built-in.


Wolfram Language (Mathematica), 22 bytes

((#.#)^2-2#.#^3)^.5/4&

Try it online!

-2 bytes by porting loopy walt's Python answer.

Takes input as a list. Using the formula \$A= \frac{1}{4}\sqrt{(a^2+b^2+c^2)^2-2(a^4+b^4+c^4)}\$.


Wolfram Language (Mathematica), 24 bytes

1##&@@(+##/2-{0,##})^.5&

Try it online!

Based on chyanog's answer to another challenge.

Using the formlula \$A=\sqrt{s(s-a)(s-b)(s-c)}\textrm{, where } s=\frac{a+b+c}{2}\$.

\$\endgroup\$
4
  • 2
    \$\begingroup\$ What an expressive name of a builtin. \$\endgroup\$
    – Bubbler
    Jul 28, 2022 at 2:07
  • 1
    \$\begingroup\$ As it is named as SSSTriangle... Is there something like SASTriangle, ASATriangle, AASTriangle, or even HLTriangle? \$\endgroup\$
    – tsh
    Jul 29, 2022 at 6:56
  • \$\begingroup\$ @tsh Try it online! \$\endgroup\$
    – alephalpha
    Jul 29, 2022 at 7:01
  • 1
    \$\begingroup\$ @tsh AASTriangle, ASATriangle, SASTriangle, SSSTriangle, Triangle. \$\endgroup\$
    – alephalpha
    Jul 29, 2022 at 7:08
7
\$\begingroup\$

Dyalog APL, 16 15 bytes

-1 thanks to @Bubbler.

.5*⍨0∘,×.-2÷⍨+/

Attempt This Online!

┌──┼───────┐
.5 *⍨  ┌───┼────┐
      0∘, ×.- ┌─┼──┐
              2 ÷⍨ +/

    0∘,          left  argument: input with 0 prepended     0 a b c
          2÷⍨+/  right argument: sum of input divided by 2  (a+b+c)/2 = s
       ×.-       left minus right, then take the product    (0-s)(a-s)(b-s)(c-s)
.5*⍨             square root

(0-s)(a-s)(b-s)(c-s) is equivalent to (s-0)(s-a)(s-b)(s-c) as there is an even number of items being multiplied.

\$\endgroup\$
1
  • \$\begingroup\$ You don't need after - since there are 4 items to be multiplied. \$\endgroup\$
    – Bubbler
    Jul 28, 2022 at 3:29
7
\$\begingroup\$

K (ngn/k), 13 bytes

{%*/x-/x%2}0,

Try it online!

There is! -2 bytes thanks to @ovs.

{%*/x-/x%2}0,  x: a length-3 array containing the three sides
           0,  prepend a 0
       x%2     (0; a/2; b/2; c/2)
    x-/        (0 a b c) - a/2 - b/2 - c/2
 %*/           sqrt(product of the above)

K (ngn/k), 16 bytes

{%-s*/x-s:+/x%2}

Try it online!

There must be a shorter way..?

{%-s*/x-s:+/x%2}  x: a length-3 array containing the three sides
        s:+/x%2   s: half sum of x
      x-          (a-s; b-s; c-s)
  -s*/            -s * (a-s) * (b-s) * (c-s)
 %                sqrt
\$\endgroup\$
1
  • 2
    \$\begingroup\$ there is a shorter way: {%*/x-+/x%2}0, \$\endgroup\$
    – ovs
    Jul 28, 2022 at 9:00
5
\$\begingroup\$

J, 17 16 bytes

2%:[:*/0&,-+/%2:

Try it online!

-1 thanks to Bubbler's K approach

The interesting insight (obvious when spelled out but not always when searching for a golf) is: When taking the product of an even number of elements, it is equivalent to taking the product of their negatives.

original, 17 bytes

2%:[:*/+/-:@-0,+:

Try it online!

  • 0,+: Double each input and prepend 0
  • +/...- Subtract each of those from sum of input
  • -:@ And halve each result
  • [:*/ Product
  • 2%: Root
\$\endgroup\$
4
\$\begingroup\$

Python, 47 bytes

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

Attempt This Online!

Classic boring solution. There might be a shorter way to express this formula, but I can't find it.

\$\endgroup\$
4
\$\begingroup\$

Jelly, 6 bytes

HSạŻP½

Try it online!

Don't ask me why the chaining works...

H      # Half of
 S     # The sum of the input
  ạ    # Absolute difference with
   Ż   # The input, with a 0 prepended
    P½ # Take the square root of the product
\$\endgroup\$
2
4
\$\begingroup\$

05AB1E, 8 bytes

0šDO;αPt

Try it online or verify all test cases.

Explanation:

Uses the default formula:

$$s=\frac{0+a+b+c}{2}$$ $$ A=\sqrt{abs(0-s)\times abs(a-s)\times abs(b-s)\times abs(c-s)}$$

0š        # Prepend a 0 in front of the (implicit) input-triplet
  D       # Duplicate the list
   O      # Sum the copy
    ;     # Halve the sum
     α    # Get the absolute difference between this sum and the values in the list
      P   # Take the product
       t  # Square root
          # (which is output implicitly as result)
\$\endgroup\$
2
  • \$\begingroup\$ The signed difference will work just as well as the average difference (it doesn't matter if you have (a-s) instead of (s-a) because over the 4 terms the overall result will be positive.) I'm guessing that won't make it any shorter though? \$\endgroup\$ Jul 28, 2022 at 21:43
  • \$\begingroup\$ @LevelRiverSt I know. I've indeed just used subtracts instead of absolute difference in my ported MathGolf answer for that reason. But changing the α to - indeed won't make a difference in byte-count. \$\endgroup\$ Jul 29, 2022 at 7:08
3
\$\begingroup\$

Python NumPy, 32 bytes

lambda v:((v@v-2*v*v)*v@v)**.5/4

Attempt This Online!

Previous Python NumPy, 33 bytes

lambda v:(v@v*v@v-2*v**3@v)**.5/4

Attempt This Online!

Previous Python NumPy, 36 bytes (@alephalpha)

lambda v:(v@v*v@v-2*v**2@v**2)**.5/4

Attempt This Online!

Previous Python NumPy, 37 bytes

lambda v:((v@v)**2-2*v**2@v**2)**.5/4

Attempt This Online!

Expects a numpy vector containing the three side lenghts.

\$\endgroup\$
8
  • \$\begingroup\$ (v@v)**2 -> v@v*v@v. \$\endgroup\$
    – alephalpha
    Jul 28, 2022 at 3:16
  • \$\begingroup\$ Are you allowed to leave out the import numpy statement, per meta rules? \$\endgroup\$
    – solid.py
    Jul 28, 2022 at 7:27
  • \$\begingroup\$ Yes @solid.py \$\endgroup\$
    – loopy walt
    Jul 28, 2022 at 7:32
  • \$\begingroup\$ @solid.py If you could use them without directly referencing them which looks tricky to me. \$\endgroup\$
    – loopy walt
    Jul 28, 2022 at 7:48
  • 2
    \$\begingroup\$ @solid.py Sorry, I didn't mean to be rude. Arguably, any module that defines new types that have useful functionality accessible through methods or overloaded operators would qualify. \$\endgroup\$
    – loopy walt
    Jul 28, 2022 at 13:54
3
\$\begingroup\$

R, 30 28 bytes

\(x)prod(sum(x)/2-c(0,x))^.5

Attempt This Online!

Inspired by @Kevin Cruijssen's 05AB1E answer.


R, 32 30 bytes

Edit: -2 bytes by looking at @loopywalt's answer.

\(x)((x%*%x)^2-2*x^3%*%x)^.5/4

Attempt This Online!

Takes input as a vector of sides.

Uses the formula $$ A= \frac{1}{4}\sqrt{(a^2+b^2+c^2)^2-2(a^4+b^4+c^4)}$$

with observation that sum of squares of elements from x is a dot product of x with itself. So with \$x=[a,b,c]\$ and \$y=[a^3,b^3,c^3]\$:

$$ A= \frac{1}{4}\sqrt{(x \cdot x)^2-2(y\cdot x)}$$

\$\endgroup\$
2
  • \$\begingroup\$ Note that the 28-byte answer is also essentially identical to plannapus's answer to the previous challenge from 9 years ago... \$\endgroup\$ Jul 28, 2022 at 8:35
  • \$\begingroup\$ @DominicvanEssen indeed, thanks for that reference. \$\endgroup\$
    – pajonk
    Jul 28, 2022 at 9:13
3
\$\begingroup\$

C (clang), 59 51 bytes

#define f(a,b,c)sqrt(4*a*a*b*b-(c=a*a+b*b-c*c)*c)/4

Try it online!

Saved 8 bytes thanks to jdt!!!

\$\endgroup\$
0
3
\$\begingroup\$

Fig, \$9\log_{256}(96)\approx\$ 7.408 bytes

mqr-J0xHS

Try it online!

Jelly beats me... again. Takes input as a list of the side lengths.

mqr-J0xHS
        S # Sum the lengths
       H  # Halve it
   -      # That ^ minus...
      x   # The input
    J0    # With a 0 prepended
  r       # Product
mq        # Square root
\$\endgroup\$
2
\$\begingroup\$

Vyxal, 9 8 bytes

∑½₌N-Π*√

Try it Online!

A 7 byter with -r

Outputs as a fraction representation. Try it Online! if you want decimals as output.

Takes the 3 side lengths as a list of numbers.

Quite literal implementation of Heron's formula, with some extra insight from Bubbler's answer.

Explained

∑½₌N-Π*√
∑½       # Half sum of the side lengths
  ₌N-    # Push the half sum negated, as well as each side length minus the half sum
     Π*  # Take the product of the subtracted side lengths and multiply it by the negated half sum
       √ # Take the square root of that
\$\endgroup\$
2
\$\begingroup\$

Haskell, 38 bytes

sqrt.product.(map=<<(-).(/2).sum).(0:)

Attempt This Online!


Haskell, 38 bytes

sqrt.product.(map.(-).(/2).sum<*>(0:))

Attempt This Online!

With the help of pointfree.io.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I tried to write a SML answer, but it's very annoying as I don't know of ways of doing the 0 append pointfree, or doing sum and product without defining my own functions (i don't know of builtins that do it). \$\endgroup\$
    – qwr
    Jul 30, 2022 at 2:10
2
\$\begingroup\$

MathGolf, 9 bytes

0Γ_Σ½-ε*√

I/O as decimals.

Try it online.

Explanation:

Similar approach as my 05AB1E answer, except with subtract instead of absolute difference, since with four values the negatives balance themselves out anyway.

0          # Push a 0
 Γ         # Wrap the top four items into a list (using the three implicit inputs)
  _        # Duplicate this list
   Σ       # Sum
    ½      # Halve
     -     # Subtract it from each value in the list
      ε*   # Product: reduce by multiplication
        √  # Square root
           # (after which the entire stack is output implicitly as result)
\$\endgroup\$
2
\$\begingroup\$

Factor + math.unicode, 36 35 bytes

[ dup Σ 2 / dup rot n-v Π * √ ]

Try it online!

-1 byte because I remembered is 1 byte shorter than sqrt.

        ! { 3 4 5 }
dup     ! { 3 4 5 } { 3 4 5 }
Σ       ! { 3 4 5 } 12
2       ! { 3 4 5 } 12 2
/       ! { 3 4 5 } 6
dup     ! { 3 4 5 } 6 6
rot     ! 6 6 { 3 4 5 }
n-v     ! 6 { 3 2 1 }
Π       ! 6 6
*       ! 36
√       ! 6.0
\$\endgroup\$
1
\$\begingroup\$

Burlesque, 15 bytes

0+]J++2./?-pdr@

Try it online!

A port of Kevin Cruijssen's 05AB1E answer

0+] # Prepend 0
J   # Duplicate
++  # Sum
2./ # Halve
?-  # Difference with original
pd  # Product
r@  # Square root
\$\endgroup\$
1
\$\begingroup\$

Desmos, 36 bytes

f(l)=(total(ll)^2-2l^4.total)^{.5}/4

Input is a list of the three side lengths.

Try It On Desmos!

Port of Steffan's Python answer also gives 36 bytes:

f(a,b,c)=(4aabb-(aa+bb-cc)^2)^{.5}/4
\$\endgroup\$
1
\$\begingroup\$

BQN, 14 bytes

√·×´+´∘÷⟜2-0⊸∾

Try it at BQN REPL

            0⊸∾     # each element of the argument, prepended by a zero
           -        # subtracted from
    +´∘             # the sum of
       ÷⟜2          # each element of the argument divided by 2
  ×´                # get the product (fold-multiply),
√·                  # and take the square root
\$\endgroup\$
1
\$\begingroup\$

JavaScript, 43 bytes (@Steffan)

Ported from Steffan's Python answer by him:

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

console.log(f(1, 1, 1), 0.4330)
console.log(f(3, 4, 5), 6.0000)
console.log(f(9, 3, 7), 8.7856)

JavaScript, 46 bytes (me)

Boring answer :/ but couldn't think of anything better. \$A=\sqrt{s(s-a)(s-b)(s-c)}\textrm{, where } s=\frac{a+b+c}{2}\$.

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

console.log(f(1, 1, 1), 0.4330)
console.log(f(3, 4, 5), 6.0000)
console.log(f(9, 3, 7), 8.7856)

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 43 bytes by porting my Python answer: (a,b,c)=>(4*a*a*b*b-(a*a+b*b-c*c)**2)**.5/4 \$\endgroup\$
    – naffetS
    Jul 30, 2022 at 22:18
1
\$\begingroup\$

x86 32-bit machine code, 33 bytes

6A 03 59 D9 E8 D9 EE DC E1 DA 04 8C E2 FB D9 FD 6A 03 59 D9 C0 DA 2C 8C DE CA E2 F7 DE C9 D9 FA C3

Try it online!

Uses the cdecl calling convention, taking three 32-bit integers on the stack and returning a value on the FPU register stack.

In assembly:

f:  push 3; pop ecx     # Set ECX to 3.
    fld1                # Push 1 onto the FPU register stack.
    fldz                # Push 0 onto the FPU register stack.
    fsubr st(1), st(0)  # Change the 1 to 0-1=-1.
l0: fiadd DWORD PTR [esp+4*ecx] # Add an argument to the top value.
    loop l0                     # Loop 3 times, making the top value a+b+c.
    fscale              # Multiply the top value by 2^(value below)=2^-1=1/2.
    push 3; pop ecx     # Set ECX to 3 again.
l1: fld st(0)                   # Duplicate the top value, which is s.
    fisubr DWORD PTR [esp+4*ecx]# Change the top value to a-s or b-s or c-s.
    fmulp st(2), st(0)          # Multiply the third-from-top value
                                # (which was -1) by that and pop it.
    loop l1                     # Loop 3 times.
                        # The FPU register stack is now -(a-s)(b-s)(c-s), s.
    fmulp st(1), st(0)  # Multiply those values and pop, leaving the product.
    fsqrt               # Take the square root.
    ret                 # Return.

I had another version using SIMD instructions to do multiple calculations at once, but it was longer, at 48 bytes:

5A 6A 00 89 E1 F8 C5 F8 5B 01 0F 59 C0 C5 FB 7C C8 C5 F3 7C C9 F3 0F 11 09 D9 01 F5 72 EC D8 C0 D9 C1 DE CA DE E9 D9 FA 58 6A 04 DA 31 58 FF E2
f:  pop edx
    push 0
    mov ecx, esp
    clc
    vcvtdq2ps xmm0, [ecx]
r:  mulps xmm0, xmm0
    vhaddps xmm1, xmm0, xmm0
    vhaddps xmm1, xmm1, xmm1
    movss [ecx], xmm1
    fld DWORD PTR [ecx]
    cmc
    jc r
    fadd st(0), st(0)
    fld st(1)
    fmulp st(2), st(0)
    fsubp
    fsqrt
    pop eax
    push 4
    fidiv DWORD PTR [ecx]
    pop eax
    jmp edx
\$\endgroup\$
1
\$\begingroup\$

Knight, 50 bytes

;=x=s-**4=a^P2=b^P2^+a-b^P2 2;W>x=x/+x/s x 2xO/x 4

Try it online!

This is the elusive "triple Heron" answer:

  • Because of the limitations of Knight, this only works for Heronian triangles (triangles with integer sides and area)
  • It uses Heron's formula for the area of the triangle
  • Because Knight doesn't have square root, I implemented it using Heron's method.

(It doesn't work in the TIO because it hasn't implemented the no-op.) It turns out I just misread the spec.

Here's the expanded code:

;=a^P2
;=b^P2
;=c^P2
;=s (-(*(*4a) b)(^(+a(-b c)) 2))
;=x s
;WHILE >x (=x(/+x(/s x) 2)) 
  x
OUTPUT /x 4
\$\endgroup\$
6
  • \$\begingroup\$ For a no-op, you can just use 1 or something. It will work on TIO. Also, : is treated as whitespace, so it doesn't take up the whole while block. \$\endgroup\$
    – naffetS
    Aug 3, 2022 at 21:03
  • \$\begingroup\$ @Steffan I can't use a number in this case because it would get parsed with the 2. Is : actually completely equivalent to whitespace? \$\endgroup\$ Aug 3, 2022 at 21:05
  • \$\begingroup\$ Yes, : is equivalent to whitespace. It's documented in the spec. You can also use one of NTF, but it will be grouped with O \$\endgroup\$
    – naffetS
    Aug 3, 2022 at 21:06
  • \$\begingroup\$ The spec says that it "can (usually) be considered whitespace", not that it's always the same as whitespace. \$\endgroup\$ Aug 3, 2022 at 21:12
  • 1
    \$\begingroup\$ Actually, you're right. But this code is still invalid. : takes an argument, and it will consume O/x 4 for that argument. And it is implemented in TIO. In this code, it is equivalent to whitespace. It is only not equivalent at the end of a program. \$\endgroup\$
    – naffetS
    Aug 3, 2022 at 21:14
1
\$\begingroup\$

Raku, 27 bytes

{sqrt [*] @_.sum/2 X-0,|@_}

Try it online!

@_ is the array of arguments to the function: a, b, and c. @_.sum / 2 is half the sum of the arguments, what the problem statement calls s. X- subtracts the numbers 0 and |@_, the flattened arguments, from that number, producing the numbers s, s - a, s - b, and s - c. Then [*] multiplies them together and sqrt takes the square root.

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

TI-Basic, 14 bytes

√(sum(Ans)/2prod(sum(Ans)/2-Ans

or

.25√(sum(Ans)prod(sum(Ans)-2Ans

Takes input in Ans as a list.

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

JavaScript, 43 bytes

Tried to beat 43 bytes but got a different form :)

$$ \sqrt{s(s-a)(s-b)(s-c)} $$

where \$s=\frac{a + b + c}{2}\$ is equal to:

$$ \frac{1}{4}\sqrt{4abd - d^2} $$

where \$d=(a + b)^2 - c^2\$

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

Try it:

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

;[
  [1, 1, 1], // 0.4330
  [3, 4, 5], // 6.0000
  [9, 3, 7], // 8.7856
].forEach(([a,b,c])=>console.log(f(a,b,c)))

\$\endgroup\$
0
\$\begingroup\$

lin, 25 bytes

.+ \+ `/2/.~0' - \* `/.5^

Try it here!

For testing purposes (use -i flag if running locally):

[1 1 1] ;
.+ \+ `/2/.~0' - \* `/.5^

Explanation

Prettified code:

.+ \+ `/ 2/.~ 0' - \* `/ .5^
  • .+ \+ `/ 2/ duplicate, half-sum of input
  • .~ 0' swap, append 0
  • - \* `/ .5^ vector subtract, product, square root
\$\endgroup\$
0
\$\begingroup\$

Charcoal, 11 bytes

I₂Π⁻⊘Σθ⊞Oθ⁰

Try it online! Link is to verbose version of code. Takes input as an array. Explanation:

      θ     Input array
     Σ      Summed
    ⊘       Halved
   ⁻        Vectorised subtract
          ⁰ Literal integer `0`
       ⊞O   Appended to
         θ  Input array
  Π         Take the product
 ₂          Take the square root
I           Cast to string
            Implicitly print
\$\endgroup\$
0
\$\begingroup\$

Ruby, 44 bytes

->a,b,c{(4*a*a*b*b-(a*a+b*b-c*c)**2)**0.5/4}

Try it online!

Ruby, 45 bytes

->a{a.inject(s=a.sum/2.0){|p,i|p*(s-i)}**0.5}

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Perl 5 -MList::Util=product,sum -pal, 37 bytes

$_=sqrt product map{sum(@F)/2-$_}0,@F

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Pyth, 14 13 bytes

@*F-LcsQ2+QZ2

Try it online!

\$\endgroup\$
0
\$\begingroup\$

C# (Visual C# Interactive Compiler), 52 bytes

(a,b,c)=>Math.Sqrt((a-(a=(a+b+c)/2))*(b-a)*(c-a)*-a)

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ 49 bytes \$\endgroup\$
    – jdt
    Sep 16, 2022 at 14:39

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.