Avalie a proporção de um triângulo

35

Dados três comprimentos laterais de um triângulo, avalie sua razão de aspecto AR, de acordo com a seguinte fórmula:

insira a descrição da imagem aqui

Onde

insira a descrição da imagem aqui

Quanto mais próximo da equilateridade um triângulo estiver, mais próximo de 1sua proporção. A proporção é maior ou igual a 1triângulos válidos.

Entradas

A entrada são três números positivos reais que podem ser encapsulados em uma lista ou algo semelhante, se necessário.

Seu programa deve gerar o mesmo valor, independentemente da ordem em que os três comprimentos laterais são inseridos.

Esses três números será sempre sidelengths válidas de um triângulo (triângulos degenerados como uma com sidelengths 1, 1e 2não vai ser dada como entrada). Você não precisa se preocupar com imprecisões de ponto flutuante quando os valores se tornam extremamente próximos a um triângulo degenerado (por exemplo, é aceitável que seu programa tenha erro division by 0ao inserir [1, 1, 1.9999999999999999]).

A entrada pode ser fornecida através de STDIN, como argumento de função, ou qualquer coisa semelhante.

Saídas

A saída é um número real maior ou igual à 1precisão padrão aceitável no seu idioma.

A saída pode ser impressa STDOUT, retornada de uma função ou qualquer coisa semelhante.

Casos de teste

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

Pontuação

Isso é , então a resposta mais curta em bytes vence.

Fatalizar
fonte
s deve ser (a + b + c) / 3 ?
Costrom 28/11
3
@costrom Não, a fórmula está correta. s é o semiperímetro do triângulo . sua fórmula seria indefinida para um triângulo equilátero.
Fatalize
Posso obter apenas floats para entrada ou preciso obter números inteiros também?
Erik the Outgolfer
@ErikGolfer acceptable リ ッ ク ゴ ル ァ É aceitável inserir em 42.0vez de 42.
Fatalize
@Fatalize Obrigado. Além disso, todas as entradas podem ser 0?
Erik the Outgolfer

Respostas:

19

Gelatina , 6 bytes

Esta resposta é baseada na resposta 05AB1E de Emigna . Muito obrigado a Dennis e Lynn por sua ajuda na definição desta resposta. Sugestões de golfe são bem-vindas! Experimente online!

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
fonte
4
6 bytes e você ainda quer sugestões de golfe? :-D
Luis Mendo
11
@LuisMendo Se for possível, com certeza: D #
Sherlock9 /
11
"Push" não é uma terminologia muito correta; A geléia não é baseada em pilha. Em vez disso, ⁸÷é extraído da cadeia como uma unidade e deve ser lido como dividir o argumento inicial de esquerda por isso ou algo assim.
Lynn
11
@ Lynn Estou jogando golfe há vários meses. A terminologia baseada em pilha está firmemente inserida no meu cérebro: D Deve ser corrigido agora.
Sherlock9
56

Geléia , 7 bytes

SH_÷@HP

Experimente online!

Explicação

insira a descrição da imagem aqui

Vamos ler esta cadeia:

  • O argumento implícito é uma lista [a, b, c].

  • Primeiro lemos S. Isso leva a soma: a + b + c.

  • Então, lemos H. Este metades que: (a + b + c)/2. (Isso é s.)

  • Em seguida, lemos uma díade _(subtrair), seguida por outra díade. Isso é um gancho : falta um argumento correto, então ele recebe o argumento dessa cadeia, [a, b, c]nos dando [s-a, s-b, s-c]. (Este é o quinto padrão de cadeia na tabela aqui .)

  • Então, lemos o par díade-mônada ÷@H. Isso é uma bifurcação : ÷@é uma divisão com os argumentos invertidos e Hé dividido pela metade, então nosso valor de trabalho recebe Ho argumento dessa cadeia ÷por ele. Isso vetoriza; nos resta [(a/2)/(s-a), (b/2)/(s-b), (c/2)/(s-c)]. (Este é o segundo padrão de cadeia na tabela aqui .)

  • Finalmente, levamos o produto Ppara nós abc/(8(s-a)(s-b)(s-c)).

Veja um gráfico em forma de árvore de como os links se encaixam.

Lynn
fonte
8
As imagens estão ótimas! Bom toque!
DavidC
2
Eu mesma diminuí a imagem superior e transformei a segunda em um link (sem trocadilhos).
Lynn
Vi a imagem e pensei imediatamente: "Legal, Lynn!" antes de olhar para que ela postou ;-)
ETHproductions
7
Melhor explicação que eu já vi sobre um programa Jelly. Eu ainda não entendo, mas mais perto!
Sparr
Executei a amostra no caso de teste ´6.0,12.0,14.0` e deu -0,8888888888888888´ em vez de 1,575, como mostrado nos casos de teste. Há algum problema nos casos de teste ou no seu código?
MBaas
13

Gelatina , 6 bytes

S÷_2Pİ

Experimente online!

Como funciona

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
fonte
Ahh, e eu tentei usar ³⁴⁵como argumentos ...
Erik the Outgolfer
11

JavaScript, 38 bytes

Este é um lambda (com curry ):

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

(Se você o atribuir a uma variável, fprecisará chamá-lo como f(3)(4)(5))

flawr
fonte
Me derrote por alguns segundos :) Importe-se em explicar como a fórmula funciona de maneira semelhante à fornecida pela pergunta?
Kritixi Lithos
Plugue @KritixiLithos Apenas no s = 1/2(a+b+c)na fórmula e simplificar: D (por exemplo s-a = .5*b+.5*c-.5*a, e os três factores de .5cancelar com 8)
flawr
5
(a,b,c)=>é o mesmo comprimento, e custa menos bytes a chamada;)
ETHproductions
4
Mas eu amo curry: D
flawr
9

05AB1E , 11 7 bytes

05AB1E usa a codificação CP-1252 .

O¹·-¹/P

Experimente online!

Explicação

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

MATL , 8 7 bytes

tsGE-/p

Experimente online!

Explicação

Vamos usar a entrada [3 4 5]como um exemplo

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
fonte
8

R, 34 29 bytes

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

Lê a entrada da entrada padrão e armazenar como o R-vector x. Então faça uso da vetorização de R para formar o denominador.

Billywob
fonte
7

Haskell, 36 bytes

Isso define a função #que recebe três argumentos.

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

Você deve chamá-lo da seguinte maneira: (3#4)5

Um pouco mais, mas talvez mais jogável:

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

MATLAB, 64 38 25 bytes

Essa é uma função anônima que implementa a fórmula conforme fornecida:

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

Assume que a entrada seja uma lista de três valores, por exemplo [3,4,5]. Este exemplo é usado na seguinte explicação:

             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
fonte
6

Mathematica, 20 bytes

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

Recebe a entrada como uma lista de três valores, que são referidos como #dentro da função. Tr@é a maneira mais curta de somar uma lista (obter 2s) e 1##&@@(...)multiplica os três fatores i/(2s-2i)para iin a, b, c.

Se as entradas forem números inteiros ou números racionais, você obterá um resultado exato.

Martin Ender
fonte
5

OCaml, 51 bytes

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

Sim, operadores separados para carros alegóricos ...

shooqie
fonte
5

Maravilha , 48 bytes

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

DESCANSE EM PAZ

Uso:

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

Explicação

As chamadas de função são caras no Wonder, quando comparadas aos operadores de infix em outros idiomas. Por causa disso, eu conti todos os termos em uma matriz e obtive o produto do resultado em vez de multiplicar cada termo. O código seria equivalente a algo como:

(a,b,c)=>product([a,b,c,1/(b+c-a),1/(a+c-b),1/(a+b-c)])
Mama Fun Roll
fonte
11
Hmm, por que "RIP"?
Luis Mendo
É muito mais do que / necessário esperar
Mama Fun rolo
5

Na verdade , 10 8 bytes

Essa resposta é baseada na excelente resposta de Dennis à geléia . Sugestões de golfe são bem-vindas! Experimente 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
fonte
5

Minecraft 1.8, 1607 bytes + 85 blocos = 1692 blytes

Aviso: Não joga golfe. Golfed vai demorar até 1 / 3 menos blytes.

Aqui está uma captura de tela comentada:

insira a descrição da imagem aqui

  • As entradas são a, b, e c, e a saída éfin

  • fin, e todas as outras variáveis ​​no Minecraft são números inteiros; portanto, a precisão padrão do Minecraft é 0 ponto decimal

  • A borda verde: os blocos de comando à esquerda serão ativados após os da direita, que são apenas inicializações variáveis.

  • A alavanca (retângulo cinza-marrom no canto inferior direito) é o gatilho da engenhoca

  • É preciso muito por causa da maneira como o Minecraft lida com variáveis . Uma visão geral muito simplificada:

    • /scoreboard objectives add name dummycria uma nova variável chamada " name"

    • /scoreboard players set @p name numberdefine a variável namepara number. O número deve ser um número real, não uma variável.

    • /scoreboard players operation @p name += @p name2incrementa nameem name2. name2deve ser uma variável, não um número.

      • -=, /=, *=, =E mais podem ser utilizados em vez +=de decremento, multiplicar, divisão, etc.
  • Não vou postar todos os 43 comandos aqui. Ajudaria a jogar isso, mas também me deixaria louco de copypasting

  • Se 1.9 blocos de comando fossem usados, a solução usaria (pelo menos) 42 blocos a menos. Se variáveis ​​de uma letra fossem usadas, quase 200 bytes seriam salvos.

RudolfJelin
fonte
4

Java, 38 bytes

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

Testando e não-destruído

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));
  }
}

Teste-o!

Saída

1.0
1.25
6.947606226693615
1.575
1.575
1.09375
Olivier Grégoire
fonte
Eu sinto que (a,b,c)está meio que trapaceando aqui, porque não contém informações de tipo. Na IMO, a interface lambda implícita (no seu caso F) deve contar na soma total de bytes.
F. George
4
@ mEQ5aNLrK3lqs3kfSa5HbvsTWe0nIu Lambdas são altamente recomendados. Além disso, a maioria das entradas do Java 8 funciona assim sem nenhuma observação. Se você não concorda e considera que trapaceou, convido você a perguntar formalmente na meta se essa notação é aceita ou não. Enquanto isso, alinhar-me às respostas anteriores do Java 8.
Olivier Grégoire
4

Água-viva , 17 16 bytes

Agradecemos ao Zgarb por economizar 1 byte.

p%/*-)/+i
    2%

Experimente online!

Explicação

Isso se baseia na mesma fórmula recíproca da resposta de Dennis .

Na notação funcional mais tradicional, o programa acima é o seguinte:

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

Onde iestá a lista de entrada. Observe que fold(multiply, ...)apenas calcula o produto e fold(add, ...)a soma, para que possamos simplificar ainda mais isso:

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

O sum(i) / ié implementado através do gancho, )/+que define uma nova função unária para executar as duas etapas ao mesmo tempo.

Martin Ender
fonte
Salve um byte com um gancho .
Zgarb
4

Dyalog APL , 10 9 bytes

×/⊢÷+/-+⍨

Este é um trem de funções anônimas (no topo de um garfo de um garfo de um garfo), o que significa que todas as subfunções são aplicadas ao argumento, dentro da seguinte estrutura:

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

TryAPL online!

×/ o produto de

os argumentos

÷ dividido por

+/ a soma dos argumentos

- menos

+⍨ os argumentos dobraram (lit. adicionados a si mesmos)

Formação matemática.

ngn raspou um byte.

Adão
fonte
Olá Adám, pls. lembre-me de perguntar sobre ´ next´ na próxima semana, se eu esquecer :-)
MBaas 1/16/16
Não sei como o link "background" supostamente se refere a essa resposta, porque não vejo nenhum algoritmo lá. Além disso, você pode adicionar algumas informações sobre a ordem das operações? Tentei reproduzir esta resposta em alguns idiomas diferentes, com ordem variável de operações, mas sempre recebo uma resposta diferente daquela da pergunta.
gato
@cat Bem, não se pretendia dar o algoritmo, apenas para explicar qual é a proporção, pois não existe tal página na Wikipedia. APL é da direita para a esquerda, o que significa que toda função aceita o que está à sua direita como argumento. Portanto, pode ser lido da esquerda para a direita, como na explicação.
Adám 4/16/16
3

dc, 49 bytes

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

Uma implementação direta da fórmula fornecida. Solicita as três entradas na chamada em três linhas separadas e gera um valor de ponto flutuante com 5 dígitos após o ponto decimal para a próxima linha.

Explicação

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
fonte
3

TI-Basic, 11 bytes

A entrada deve estar na forma de uma lista, como {A B C}.

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

Talvez esse visual ajude (lembre-se disso 2s = a+b+c):

      abc abc abc prod (Ans)
---------------- = --------------------- = ----------- -------- = -------------------
8 (sa) (sb) (sc) (2s-2a) (2s-2b) (2s-2c) (a + b + c) (1-2 {a, b, c}) prod (soma (Ans) -2Ans)
Timtech
fonte
2

Perl 6 , 44 bytes

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

Python, 55 bytes

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

Crédito para Dennis . Acabei de portar. Em Python, uma linguagem muito negligenciada.

Erik, o Outgolfer
fonte
2

Quarto, 83 bytes

Assume que os parâmetros de ponto flutuante iniciam na pilha de ponto flutuante. Deixa o resultado na pilha de ponto flutuante. O uso da pilha para parâmetros / retorno é o padrão para a 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* ;

Experimente online - contém todos os casos de teste

Usa a fórmula a*b*c * 1/ ( -(a+b-c) * -(b+c-a) * (a+c-b) ). Praticamente todo o programa está usando apenas a pilha de ponto flutuante. A excepção é o 3no 3 fpick. Este programa requer um intérprete que suporte fpick(Ideone funciona, repl.it não).

Explicação: um pouco menos de golfe

\ 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
fonte
2

ised : 19 bytes

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

Chame-o como ised --l 'inputfile.txt' '@*$1/@*{@+$1-2.*$1}' onde inputfile.txtpode ser um arquivo com matriz separada por espaço ou- para receber do pipe / stdin.

Versão Unicode (o mesmo número de bytes, mas 3 caracteres a menos):

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

Infelizmente, iseddesperdiça muitos caracteres por sua sintaxe de argumento de entrada.

orion
fonte
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

Ligue com

? r (3,4,5)

ou no excel com

= r (5,12,13)

SeanC
fonte
Você iria salvar 6 bytes com @ SuperJedi224 's algoritmo: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));

Uso:

ar(42, 42, 3.14);
WeskerTyrant
fonte
2

k, 19 bytes

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

Avalia da direita para a esquerda - divida a lista x por 2, some o resultado e subtraia-o do x original. Negar a resposta e obter o produto do resultado e 8. O resultado é o denominador, o numerador é o produto da lista.

Paul Kerrigan
fonte
1

Lua, 45 bytes

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

Fortemente baseado na resposta JavaScript.

Eu fiz
fonte