Évaluer le format d'un triangle

35

Compte tenu de trois sidelengths d'un triangle, d' évaluer son rapport d'aspect AR donné la formule suivante:

enter image description here

enter image description here

Plus un triangle est proche de l'équilatéralité, plus 1son ratio d'aspect est proche . Le rapport hauteur / largeur est supérieur ou égal à 1pour les triangles valides.

Contributions

L'entrée consiste en trois réels nombres positifs qui peuvent être encapsulés dans une liste ou similaire si besoin est.

Votre programme doit afficher la même valeur quel que soit l’ordre dans lequel les trois longueurs latérales sont entrées.

Ces trois nombres seront toujours des longueurs latérales valides d’un triangle (les triangles dégénérés comme un triangle avec des longueurs latérales 1, 1et 2ne seront pas donnés en entrée). Vous n'avez pas à vous soucier des inexactitudes en virgule flottante lorsque les valeurs deviennent extrêmement proches d'un triangle dégénéré (par exemple, il est acceptable que votre programme commette une erreur division by 0lors de la saisie [1, 1, 1.9999999999999999]).

L'entrée peut être donnée via STDIN, en tant qu'argument de fonction ou quelque chose de similaire.

Les sorties

La sortie est un nombre réel supérieur ou égal à 1l'exactitude standard acceptable dans votre langue.

La sortie peut être imprimée sur STDOUT, renvoyée par une fonction ou similaire.

Cas de test

Inputs                   Output

  1      1      1         1
  3      4      5         1.25
 42     42   3.14         ≈ 6.9476
 14      6     12         1.575
  6     12     14         1.575
0.5    0.6    0.7         ≈ 1.09375

Notation

C'est du , donc la réponse la plus courte en octets est gagnante.

Fataliser
la source
devrait être s (a + b + c) / 3 ?
Costrom
3
@costrom Non, la formule est correcte. s est le semi - millimètre du triangle . votre formule serait indéfinie pour un triangle équilatéral.
Fataliser
Est-ce que je peux juste avoir des floats pour l'entrée ou dois-je aussi avoir des entiers?
Erik l'Outgolfer
@ErikGolfer ー ー Il est acceptable d'entrer 42.0au lieu de 42.
Fataliser
@ Fatalize Merci. Aussi, les entrées peuvent-elles toutes être 0?
Erik l'Outgolfer

Réponses:

19

Gelée , 6 octets

Cette réponse est basée sur la réponse 05AB1E d’Emigna . Un grand merci à Dennis et Lynn pour leur aide dans la résolution de cette réponse. Suggestions de golf bienvenues! Essayez-le en ligne!

S_Ḥ⁸÷P

Ungolfing

           Implicit argument [a, b, c].
S          Take the sum, a+b+c or 2*s
  Ḥ        Take the double, [2*a, 2*b, 2*c].
 _         Vectorized subtract, giving us [2*(s-a), 2*(s-b), 2*(s-c)].
   ⁸÷      Vectorized divide the initial left argument, the input [a, b, c],
             by [2*(s-a), 2*(s-b), 2*(s-c)].
     P     Take the product giving us the aspect ratio, abc/8(s-a)(s-b)(s-c).
Sherlock9
la source
4
6 octets et vous voulez toujours des suggestions de golf? :-D
Luis Mendo
1
@LuisMendo Si c'est possible, bien sûr: D
Sherlock9
1
"Push" n'est pas une terminologie tout à fait correcte; La gelée n'est pas basée sur la pile. Plutôt, ⁸÷obtient beaucoup de la chaîne en tant qu'unité, et devrait être lu comme divisant l'argument de gauche initial par ceci , ou quelque chose.
Lynn
1
@ Lynn Je joue au golf depuis plusieurs mois. La terminologie basée sur la pile est fermement ancrée dans mon cerveau: D devrait être corrigé maintenant.
Sherlock9
56

Gelée , 7 octets

SH_÷@HP

Essayez-le en ligne!

Explication

enter image description here

Lisons cette chaîne:

  • L'argument implicite est une liste [a, b, c].

  • D'abord nous lisons S. Cela prend la somme: a + b + c.

  • Ensuite, nous lisons H. Diviser par deux le: (a + b + c)/2. (Ceci est s.)

  • Ensuite, nous lisons une dyade _(soustraction), suivie d’une autre dyade. C'est un crochet : il manque un bon argument, donc il reçoit l'argument de cette chaîne, [a, b, c]nous le donne [s-a, s-b, s-c]. (Ceci est le cinquième motif de chaîne du tableau ici .)

  • Ensuite, nous lisons la paire dyade-monade ÷@H. Ceci est une fourchette : ÷@c'est une division avec les arguments retournés, et elle Hest divisée par deux, ainsi notre valeur de travail récupère Hl'argument de cette chaîne ÷. Cela vectorise; nous sommes partis avec [(a/2)/(s-a), (b/2)/(s-b), (c/2)/(s-c)]. (Ceci est le deuxième motif de chaîne dans le tableau ici .)

  • Enfin, nous prenons le produit avec Pnous abc/(8(s-a)(s-b)(s-c)).

Affichez un graphique sous forme d'arborescence montrant comment les liens s'imbriquent

Lynn
la source
8
Les images sont superbes! Belle touche!
DavidC
2
J'ai moi-même réduit l'image du haut et transformé la seconde en lien (sans jeu de mots).
Lynn
J'ai vu l'image et j'ai immédiatement pensé: "Bien joué, Lynn!" avant de regarder qui l'a posté ;-)
ETHproductions
7
La meilleure explication que j'ai vue d'un programme de gelée. Je ne comprends toujours pas, mais de plus près!
Sparr
J’ai analysé l’échantillon contre le scénario de test ´6.0,12.0,14.0` et il a donné `-0,8888888888888888’ au lieu de 1,575 comme indiqué dans les scénarios de test. Est-ce un problème avec les cas de test ou votre code?
MBaas
13

Gelée , 6 octets

S÷_2Pİ

Essayez-le en ligne!

Comment ça marche

S÷_2Pİ  Main link. Argument: [a, b, c]

S       Sum; compute 2s := a + b + c.
 ÷      Divide; yield [2s ÷ a, 2s ÷ b, 2s ÷ c].
  _2    Subtract 2; yield [2s ÷ a - 2, 2s ÷ b - 2, 2s ÷ c - 2].
    P   Product; yield (2s ÷ a - 2)(2s ÷ b - 2)(2s ÷ c - 2).
     İ  Invert; yield 1 ÷ (2s ÷ a - 2)(2s ÷ b - 2)(2s ÷ c - 2).
Dennis
la source
Ahh, et j'ai essayé d'utiliser ³⁴⁵comme arguments ...
Erik l'Outgolfer
11

JavaScript, 38 octets

C'est un lambda (au curry ):

a=>b=>c=>a*b*c/(b+c-a)/(a+c-b)/(a+b-c)

(Si vous l'assignez à une variable, fvous devrez l'appeler comme f(3)(4)(5))

flawr
la source
Battez-moi dessus quelques secondes :) Ça ne va pas vous expliquer comment la formule fonctionne de la même manière que celle fournie par la question?
Kritixi Lithos
@KritixiLithos Il suffit de vous connecter à s = 1/2(a+b+c)la formule et de simplifier: D (par exemple s-a = .5*b+.5*c-.5*a, et les trois facteurs d' .5annulation avec 8)
flawr
5
(a,b,c)=>a la même longueur et coûte moins d'octets à appeler;)
ETHproductions
4
Mais j'adore le curry: D
mardi
9

05AB1E , 11 7 octets

05AB1E utilise le codage CP-1252 .

O¹·-¹/P

Essayez-le en ligne!

Explication

O         # sum input
 ¹        # push input again
  ·       # multiply by 2
   -      # subtract from sum
    ¹/    # divide by input
      P   # product
Emigna
la source
8

MATL , 8 7 octets

tsGE-/p

Essayez-le en ligne!

Explication

Utilisons l'entrée [3 4 5]comme exemple

t    % Take input implicitly. Duplicate
     % STACK: [3 4 5], [3 4 5]
s    % Sum of array
     % STACK: [3 4 5], 12
G    % Push input again
     % STACK: [3 4 5], 12, [3 4 5]
E    % Multiply by 2, element-wise
     % STACK: [3 4 5], 12, [6 8 10]
-    % Subtract, element-wise
     % STACK: [3 4 5], [6 4 2]
/    % Divide, element-wise
     % STACK: [0.5 1 2.5]
p    % Product of array. Implicitly display
     % STACK: 1.25
Luis Mendo
la source
8

R, 34 29 bytes

x=scan();prod(x/(sum(x)-2*x))

Reads input from stdin and store as the R-vector x. Then make use of R's vectorization to form the denominator.

Billywob
la source
7

Haskell, 36 bytes

This defines the function # which takes three arguments.

(a#b)c=a*b*c/(b+c-a)/(a+c-b)/(a+b-c)

You have to call it as follows: (3#4)5

A little bit longer but perhaps more golfable:

p=product
f v=p v/p((sum v-).(2*)<$>v)
flawr
la source
6

MATLAB, 64 38 25 bytes

This is an anyonmous function that implements the formula as provided:

@(v)prod(v./(sum(v)-2*v))

It assumes the input to be a list of three values e.g. [3,4,5]. This example is used in following explanation:

             sum(v)        = 3+4+5 = 12
             sum(v)-2*v    = 12 - 2*[3,4,5] = 12 - [6,8,10] = [6,4,2]
         v./(sum(v)-2*v))  = [3,4,5] ./ [6,4,2] = [0.5,1,2.5]
    prod(v./(sum(v)-2*v))  = 0.5 * 1 * 2.5 = 1.25
flawr
la source
6

Mathematica, 20 bytes

1##&@@(#/(Tr@#-2#))&

Takes input as a list of three values, which is referred to as # inside the function. Tr@ is the shortest way to sum a list (to get 2s) and 1##&@@(...) multiplies the three factors i/(2s-2i) for i in a, b, c.

If the inputs are integers or rational numbers, you'll get an exact result.

Martin Ender
la source
5

OCaml, 51 bytes

fun a b c->a*.b*.c/.(b+.c-.a)/.(a+.c-.b)/.(a+.b-.c)

Yay, separate operators for floats...

shooqie
la source
5

Wonder, 48 bytes

@@@prod[#0#1#2/1- +#1#0#2/1- +#2#0#1/1- +#2#1#0]

RIP

Usage:

(((@@@prod[#0#1#2/1* * - +#1#0#2- +#2#0#1- +#2#1#0])3)4)5

Explanation

Function calls are costly in Wonder when compared to infix operators in other languages. Because of this, I contained all the terms in an array and got the product of the result instead of multiplying every single term. The code would be equivalent to something like:

(a,b,c)=>product([a,b,c,1/(b+c-a),1/(a+c-b),1/(a+b-c)])
Mama Fun Roll
la source
1
Hmm, why "RIP"?
Luis Mendo
It's much longer than necessary/expected
Mama Fun Roll
5

Actually, 10 8 bytes

This answer is based on Dennis's excellent Jelly answer. Golfing suggestions welcome! Try it online!

;Σ♀/♂¬πì

Ungolfing

     Implicit input [a, b, c].
;    Duplicate [a, b, c].
Σ    sum() to get twice the semiperimeter, 2*s.
♀/   Vectorized divide 2*s by [a, b, c] to get [2*s/a, 2*s/b, 2*s/c].
♂¬   Vectorized subtract 2 to get [2*s/a-2, 2*s/b-2, 2*s/c-2].
π    Get the product of the above to get 8*(s/a-1)*(s/b-1)*(s/c-1).
     This is the same as 8(s-a)(s-b)(s-c)/abc.
ì    Invert to get the aspect ratio, abc/8(s-a)(s-b)(s-c).
     Implicit return.
Sherlock9
la source
5

Minecraft 1.8, 1607 bytes + 85 blocks = 1692 blytes

Warning: Not golfed. Golfed will take up to 1/3 less blytes.

Here is a commented screenshot:

enter image description here

  • The inputs are a, b, and c,and the output is fin

  • fin, and all other variables in Minecraft are integers, so the standard Minecraft accuracy is 0 decimal points

  • The green border: the command blocks on the left will activate after the ones on the right, which are just variable initializations.

  • The lever (grey-brown rectangle in the down right) is the contraption trigger

  • It takes up so much because of the way Minecraft handles variables. A very simplified overview:

    • /scoreboard objectives add name dummy creates a new variable named "name"

    • /scoreboard players set @p name number sets the variable name to number. Number must be a real number, not a variable.

    • /scoreboard players operation @p name += @p name2 increments name by name2. name2 must be a variable, not a number.

      • -=, /=, *=, = and more can be used instead += to decrement, multiply, divide, etc.
  • I'm not going to post all the 43 commands here. It would help golfing this, but would also help drive me crazy copypasting

  • If 1.9 command blocks would be used, the solution would (at least) use 42 blocks less. If one-letter variables would be used, almost 200 bytes would be saved.

RudolfJelin
la source
4

Java, 38 bytes

(a,b,c)->a*b*c/(b+c-a)/(a-b+c)/(a+b-c)

Testing and ungolfed

public class Pcg101234 {
  interface F {
    double f(double a, double b, double c);
  }
  public static void main(String[] args) {
    F f = (a,b,c)->a*b*c/(b+c-a)/(a-b+c)/(a+b-c);

    System.out.println(f.f(1,1,1));
    System.out.println(f.f(3,4,5));
    System.out.println(f.f(42,42,3.14));
    System.out.println(f.f(14,6,12));
    System.out.println(f.f(6,12,14));
    System.out.println(f.f(0.5,0.6,0.7));
  }
}

Test it!

Output

1.0
1.25
6.947606226693615
1.575
1.575
1.09375
Olivier Grégoire
la source
I feel like (a,b,c) is kinda cheating here, because it contains no type information. IMO the implicit lambda interface (in your case F) should count in the total byte sum.
F. George
4
@mEQ5aNLrK3lqs3kfSa5HbvsTWe0nIu Lambdas are heavily recommended. Also, most of the Java 8 entries work like that without any remarks. If you disagree and consider I cheated, I invite you to ask formally in meta if this notation is accepted or not. Meanwhile, I align on previous Java 8 answers.
Olivier Grégoire
4

Jellyfish, 17 16 bytes

Thanks to Zgarb for saving 1 byte.

p%/*-)/+i
    2%

Try it online!

Explanation

This is based on the same reciprocal formula as Dennis's answer.

In more traditional functional notation, the above program reads as follows:

print(
  1 / fold(
    multiply,
    fold(add, i) / i - 2
  )
)

Where i is the input list. Note that fold(multiply, ...) just computes the product and fold(add, ...) the sum, so we can further simplify this to:

print(1 / product(sum(i) / i - 2))

The sum(i) / i is implemented via the hook )/+ which defines a new unary function to do both steps at once.

Martin Ender
la source
Save a byte with a hook.
Zgarb
4

Dyalog APL, 10 9 bytes

×/⊢÷+/-+⍨

This is an anonymous function train (an atop of a fork of a fork of a fork), meaning that every sub-function is applied to the argument, inside the following structure:

 ┌─┴─┐          
×/ ┌─┼───┐      
    ÷ ┌─┼──┐  
      +/ - +⍨

TryAPL online!

×/ the product of

the arguments

÷ divided by

+/ the sum of the arguments

- minus

+⍨ the arguments doubled (lit. added to themselves)

Mathematical background.

ngn shaved a byte.

Adám
la source
Hi Adám, pls. remind me to ask you about ´⊢´ next week if I forget it :-)
MBaas
I dunno how the "background" link supposedly pertains to this answer because I see no algorithm there at all. Also, can you add some info about order of operations? I've tried to reproduce this answer in a few different languages with varying order of operations but I always get an answer different from that in the question.
cat
@cat Well, it wasn't intended to give the algorithm, only to explain what the aspect ratio is, as there is no such page on Wikipedia. APL is right-to-left, meaning that every function takes whatever is on its right as argument. Therefore, it can be read from left to right as in the explanation.
Adám
3

dc, 49 bytes

5k?dsa?dsb?dsc++2/sslalblc**lsla-lslb-lslc-8***/p

A direct implementation of the formula given. Prompts for the three inputs upon invocation on three separate lines and outputs a floating-point value with 5 digits after the decimal point to the next line.

Explanation

5k                                                # Set the output precision to 5 digits after the decimal
  ?dsa                                            # Prompt for first input value on first line, duplicate it, and then store it in register `a`
      ?dsb                                        # Prompt for second input, duplicate it, and store it in register `b`
          ?dsc                                    # Prompt for third input, duplicate it, and store it in register `c`
              ++2/ss                              # Sum up the 3 values on the main stack, then divide sum by 2 and store the result in register `s`
                    lalblc**                      # Copy all three values from registers `a`,`b`,`c` onto the main stack, find their product, and push result to top of main stack
                            lsla-                 # Copy value from register `s` onto main stack, subtract register `a`'s value from it, and push result to main stack
                                 lslb-            # Copy value from register `s` onto main stack, subtract register `b`'s value from it, and push result to main stack
                                      lslc-       # Copy value from register `s` onto main stack, subtract register `c`'s value from it, and push result to main stack
                                           8***   # Find the product of the top three values and 8 and then push the result to main stack
                                               /p # Divide the second to top value (a*b*c) by the top of stack value (8*(s-a)*(s-b)*(s-c)), push the result to the main stack, and then output the result to STDOUT
R. Kap
la source
3

TI-Basic, 11 bytes

Input should be in the form of a list, like {A B C}.

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

Maybe this visual will help (remember that 2s = a+b+c):

      abc                    abc                   abc                prod(Ans)
---------------- = --------------------- = ------------------- = -------------------
8(s-a)(s-b)(s-c)   (2s-2a)(2s-2b)(2s-2c)   (a+b+c)(1-2{a,b,c})   prod(sum(Ans)-2Ans)
Timtech
la source
2

Perl 6, 44 bytes

->\a,\b,\c{a*b*c/(b+c -a)/(a+c -b)/(a+b -c)}
Brad Gilbert b2gills
la source
2

Python, 55 bytes

def f(x,y,z):s=x+y+z;return 1/((s/x-2)*(s/y-2)*(s/z-2))

Credit to Dennis. I just ported. In Python, a much-neglected language.

Erik the Outgolfer
la source
2

Forth, 83 bytes

Assumes the floating point parameters start on the floating point stack. Leaves the result on the floating point stack. Using the stack for params/returning is the standard for Forth.

: p 3 fpick ;
: T p p p ;
: f 0 s>f T f- f+ f- T f+ f- f* T f- f- f* 1/f f* f* f* ;

Try it online - contains all test cases

Uses the formula a*b*c * 1/ ( -(a+b-c) * -(b+c-a) * (a+c-b) ). Pretty much the entire program is using only the floating point stack. The exception is the 3 in 3 fpick. This program requires an interpreter that supports fpick (Ideone works, repl.it doesn't).

Explanation: slightly less golfed

\ 3 fpick takes the 3rd element (0-indexed) and pushes a copy
\ Used to copy parameters on the stack over another number 'x' ( a b c x -> a b c x a b c )
: f3p 3 fpick 3 fpick 3 fpick ;

: f                     \ define a function f
0 s>f f3p f- f+ f-      \ push a zero, copy params, compute 0-(a+b-c)
                        \ the zero allows me to copy (I need an 'x' to jump over)
f3p f+ f- f*            \ copy params and compute -(b+c-a), multiply by previous result
                        \ the negatives miraculously cancel
f3p f- f- f*            \ copy and compute (a+c-b), multiply by previous result
1/f f* f* f* ;          \ take the reciprocal and multiply by a*b*c
                        \ the result is left on the floating point stack
mbomb007
la source
2

ised: 19 bytes

@*$1/@*{@+$1-2.*$1}

Call it as ised --l 'inputfile.txt' '@*$1/@*{@+$1-2.*$1}' where inputfile.txt can be a file with space separated array, or - to receive from pipe/stdin.

Unicode version (same bytecount but 3 chars less):

Π$1/Π{Σ$1-2.*$1}

Unfortunately, ised wastes a lot of chars for its input argument syntax.

orion
la source
2

vba, 76

Function r(a,b,c)
s=(a+b+c)/2:r=(a*b*c)/(8*(s-a)*(s-b)*(s-c))
End Function

Call with

?r(3,4,5)

or in excel with

=r(5,12,13)

SeanC
la source
You'd save 6 bytes with @SuperJedi224 's algorithm: Public Function r(a,b,c):r=a*b*c/(b+c-a)/(a-b+c)/(a+b-c):End Function
steenbergh
2

C#, 82 bytes

void ar(double a,double b,double c)=>Console.Write(a*b*c/(b+c-a)/(a+c-b)/(a+b-c));

Usage:

ar(42, 42, 3.14);
WeskerTyrant
la source
2

k, 19 bytes

{(*/x)%8*/-x-+/x%2}

Evaluates right to left - Divide the list x by 2, sum the result and subtract it from original x. Neg the answer and get the product of the result and 8. The result is the denominator, the numerator is the product of the list.

Paul Kerrigan
la source
1

Lua, 45 bytes

a,b,c=...print(a*b*c/(b+c-a)/(a+c-b)/(a+b-c))

Heavily based on the JavaScript answer.

IDid
la source