Quais são as minhas dimensões?

18

Tarefa: Dada a área de um triângulo, encontre um triângulo heroniano com essa área. Qualquer triângulo heroniano com a área especificada é permitido.

Um triângulo heroniano é um triângulo com lados inteiros e área inteira . Pela fórmula de Heron, um triângulo com comprimentos laterais a,b,ctem área

sqrt(s*(s-a)*(s-b)*(s-c))

onde s=(a+b+c)/2é metade do perímetro do triângulo. Isso também pode ser escrito como

sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c)) / 4

Se esse triângulo não existir, imprima com um valor consistente de falsey.

Entrada: Um número inteiro positivo único que representa a área do triângulo.

Saída: Quaisquer três comprimentos laterais para um triângulo ou um valor falso.

Exemplos:

Input -> Output
6 -> 3 4 5
24 -> 4 15 13
114 -> 37 20 19
7 -> error

Aplicam-se brechas padrão

Este é o código de golfe, a resposta mais curta em bytes ganha.

Neil A.
fonte
6
Você pode escrever uma definição relativamente concisa de um triângulo heroniano em seu desafio?
Okx 20/05/19
1
@ Ok: Não está claro que é um triângulo com lados inteiros e área inteira?
Neil A.
@ Ok: Essa é a ideia. Tudo o que você precisa fazer é encontrar um exemplo para a área especificada, se ela existir.
Neil A.
No link da Wikipedia: "Um triângulo heroniano é um triângulo que tem comprimentos laterais e área todos inteiros".
Neil A.
5
Você poderia explicar o que é confuso sobre a definição da pergunta?
Neil A.

Respostas:

6

Geléia , 17 16 bytes

-1 byte graças a Erik, o outgolfer (use o quick, ¥)

SHð;_P
ṗ3Ç⁼¥Ðf²Ḣ

Aplicação de força bruta da fórmula de Heron.

Experimente online! (atinge o tempo limite dos anos 60 para o caso de testes 114. Leva 3m 30s localmente - verifica 114 3 = 1.481.544 triplos)

Quão?

Uma verdadeira solução de golfe - dada uma área, aela encontra todas as tuplas de três números inteiros entre 1e a(mesmo com triângulos repetidos e sem área), obtém sua área e filtros para aqueles com a área desejada (ela nem pára assim que um é encontrado, ele atravessa todos eles e aparece o primeiro resultado depois). Rende 0se não existir.

SHð;_P - Link 1, get the square of the area of a triangle: list of sides
S      - sum the sides (get the perimeter)
 H     - halve
  ð    - dyadic chain separation (call that p)
    _  - subtraction (vectorises) =    [p-side1,  p-side2,  p-side3]
   ;   - concatenate              = [p, p-side1,  p-side2,  p-side3]
     P - product                  =  p*(p-side1)*(p-side2)*(p-side3)
                                  = the square of Heron's formula = area squared

ṗ3Ç⁼¥Ðf²Ḣ - Main link: number a (area)
ṗ3        - third Cartesian power (all triples of [1,area] : [[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,1],[2,1,2],[2,2,1],[2,2,2], ... ,[a,a,a]]
       ²  - square a
     Ðf   - filter keep if:
    ¥     -   last two links as a dyad:
  Ç       -     call last link (1) as a monad f(list of sides)
   ⁼      -     left (that result) equals right (square of a)?
        Ḣ - head - get the first one (an empty list yields 0, perfect for the falsey case)
Jonathan Allan
fonte
Eu imaginei que alguém tentaria forçar isso, legal!
Neil A.
@NeilA. Eu imagino que a maioria dos envios de golfe será uma força bruta para esse desafio - mas alguns podem conseguir jogar golfe, sendo menos ridiculamente ineficientes do que este.
Jonathan Allan
Você pode substituir çcom Ç⁼¥e remover a segunda linha inteiramente.
Erik the Outgolfer
@EriktheOutgolfer Oh, obrigado, eu queria saber como ir sobre isso ...
Jonathan Allan
5

JavaScript (ES7), 109 102 100 98 bytes

Retorna uma matriz de 3 números inteiros ou false. Como a resposta da geléia , isso é bruto, forçando a fórmula de Heron.

A=>[...Array(A**3)].some((_,a)=>A*A/(r=[b=a/A%A|0,c=a/A/A|0,a%=A],p=a+b+c>>1)/(p-a)/(p-b)==p-c)&&r

Casos de teste


Versão recursiva, 83 bytes

Retorna uma matriz de 3 números inteiros ou gera um erro de recursão. Infelizmente, ele só funciona para pequenas entradas.

f=(A,n)=>A*A/(r=[a=n%A,b=n/A%A|0,c=n/A/A|0],p=a+b+c>>1)/(p-a)/(p-b)==p-c?r:f(A,-~n)

Demo

Arnauld
fonte
4

Haskell , 69 bytes

f a=take 1[t|t<-mapM(\_->[1..a])":-)",a*a==product[sum t/2-x|x<-0:t]]

Experimente online!

Emite um singleton de uma lista de três lados de triângulo, como [[3.0,4.0,5.0]]. Entradas impossíveis dão []. Tecnicamente, somente o FalseFalsey é para Haskell, mas como o Haskell exige que todas as saídas possíveis sejam do mesmo tipo, ele não pode ser usado. Se um erro pudesse ser usado como Falsey, [...]!!0economizaria 3 bytes take 1[..].

Tenta todos os triplos tde possíveis comprimentos laterais, variando de acordo 1com a área a. A fórmula de Heron é usada para verificar se a área corresponde a (s-0)(s-x)(s-y)(s-z)==a*aonde s=(x+y+z)/2está sum t/2. O produto (s-0)(s-x)(s-y)(s-z)é expresso como a productcom elementos retirados 0:t, ou seja, o triplo e o 0.

xnor
fonte
+1 para a cara do smiley, mesmo se é sorta um noop
Julian Lobo
2

F #, 170 156 152 bytes

let f(a,b,c)=
 let s=(a+b+c)/2.0
 s*(s-a)*(s-b)*(s-c)
let g A=[for a in 1.0..A do for b in a..A do for c in b..A do yield a,b,c]|>List.find(f>>(=)(A*A))

Experimente online!

"Ungolfed"

let calculateArea (a, b, c) =
    let s = (a+b+c)/2.0
    s*(s-a)*(s-b)*(s-c)

let getTriangle A =
    [  for a in 1.0..A do
       for b in a..A do
       for c in b..A do yield a,b,c
    ]
    |> List.find(calculateArea>>(=)(A * A))

Se não houver resultados, o programa falhará. Se isso não for desejado, eu tenho que substituir List.findpor List.filter(+2 bytes), que produzirá uma lista vazia caso nada seja encontrado ou List.tryFind(+3 bytes), retornando None, caso nenhum triângulo tenha sido encontrado.

Eu sempre acho que uma versão F # golfada ainda é razoável legível.

Brunner
fonte
1
Eu não sei F #, mas imagino que você poderia dispensar oe System.Math.Sqrtcomparar o valor resultante com A * A?
21417 Sean
@ Sean Claro! Obrigado pela dica :)
Brunner
Substituir 1.0..A [...] 1.0..A [...] 1.0..Apor 1.0..A [...] a..A [..] b..Adeve economizar alguns bytes e acelerar um pouco (se funcionar; eu tenho uma experiência F # mínima).
CAD97
@ CAD97 Sim! Obrigado por apontar isso.
Brunner
2

Python 2 (PyPy) , 131 123 118 bytes

n=input()
t=n*3;r=i=c=0
while c<t:
 i+=1;a,b,c=i%t,i/t%t,i/t/t;s=a+b+c>>1
 if(s-a)*s*(s-b)*(s-c)==n**2:r=a,b,c
print r

Experimente online!

Embora isso também funcione no CPython, o PyPy é muito mais rápido e pode calcular o triângulo para 114 no limite de tempo no TIO.

Tempos da minha máquina:

$ echo 114 | time pypy2 d.py
        0.55 real         0.52 user         0.02 sys
$ echo 114 | time python2 d.py
       52.46 real        51.76 user         0.27 sys
ovs
fonte
1

Pitão - 23 bytes

/mu*G-/sd2Hd/sd2^UQ3^Q2

Que imprime um valor verdadeiro / falso, ou

fq^Q2u*G-/sT2HT/sT2^UQ3

que imprime todas as soluções possíveis e é terrivelmente lento para entradas grandes. Coloque 'h' no início para imprimir apenas um.

Explicação:

fq^Q2u*G-/sT2HT/sT2^UQ3
                    UQ    # List of numbers from 0 to input-1
                   ^  3   # All triples of these numbers
f                         # Filter this by the following test (on variable T, based on Hero's formula)
     u*G-/sT2HT/sT2       # s*(s-a)*(s-b)*(s-c), where s is the sum of the triple over 2 (calclated as /sT2 )
 q^Q2                     # Test if equal to input ^2

Tente

Maria
fonte
1

Perl 6 , 54 bytes

->\a{first {a*a==[*] .sum/2 «-«(0,|$_)},[X] ^a xx 3}

Pesquisa por força bruta de todos os lados possíveis até um a menos que aa área de entrada.

  • ^aé o intervalo de números de 0 a a - 1.
  • [X] ^a xx 3reduz, por produto cruzado, três cópias dessa faixa, produzindo todos os trigêmeos de (0, 0, 0)até (a - 1, a - 1, a - 1).
  • Procuramos o firsttrigêmeo de forma que a área do triângulo com esses lados seja igual a, usando a fórmula de Heron .

Dentro do bloco de código fornecido para first:

  • $_é o trigêmeo. Ligue (x, y, z)aqui.
  • (0,|$_)é o mesmo trio, mas com 0prefixado: (0, x, y, z).
  • .sum / 2é metade do perímetro (uma quantidade nomeada sna expressão usual da fórmula de Heron).
  • .sum / 2 «-« (0, |$_)é o hiperoperador de subtração sà esquerda e (0, x, y, z)à direita, dando(s - 0, s - x, s - y, s - z) .
  • [*] depois reduz esse quadrupleto com multiplicação, fornecendo o quadrado da área.
  • a * a == procura uma área quadrada igual ao quadrado da área especificada.

Se nenhum trigêmeo for encontrado, Nil(que é falsey) será retornado.

Sean
fonte
1

Haskell , 76 bytes

f s=[[a,b,c]|a<-[1..s],b<-[1..a],c<-[1..b],a*a*c*c-(a*a+c*c-b*b)^2/4==4*s*s]

Isso gera uma lista de listas contendo todos os tamanhos integrais possíveis que geram a área correta por força bruta (exibindo a lista vazia, se não houver). A ressalva é que os produz como duplicados por causa dessa divisão no meio, mas sua parte fracionária é sempre 0.

Se você, por algum motivo, não aguenta isso,

f s=[[a,b,c]|a<-[1..s],b<-[1..a],c<-[1..b],4*a*a*c*c-(a*a+c*c-b*b)^2==16*s*s]

Isso produzirá as respostas como uma lista de listas inteiras para 89 77 bytes no total ou 13 1 bytes extras. (Graças a Neil)

Se você precisar / desejar apenas o primeiro elemento que acabou de colocar !!0no final, fornecerá apenas o primeiro elemento se houver números que se apliquem e um erro se não houver nenhum por mais 3 bytes e, take 1no início, pegará o primeiro elemento sem errar por Mais 6 bytes.

Experimente online!

Sgt. Doggo
fonte
Se você deseja evitar duplas, não pode simplesmente multiplicar a equação por 4 de cada lado?
Neil
0

TI-Basic, 70 69 bytes

Prompt A
For(B,1,A
For(C,1,B
For(D,1,C
(B+C+D)/2
If A2=Ansprod(Ans-{B,C,D
Then
Disp B,C,D
Return
End
End
End
End
/

Exibe os três comprimentos laterais, se houver um triângulo, gera um erro de sintaxe, se não houver (graças ao /no final).

-1 byte graças ao comentário de Sean em uma resposta diferente

pizzapants184
fonte
0

Mathematica, 77 bytes

com o Resolver do mathematica

s=(a+b+c)/2;d=Sqrt[s(s-a)(s-b)(s-c)];Solve[d==#&&0<a<b<c<#,{a,b,c},Integers]&

Mathematica, 117 bytes

força bruta

s=(a+b+c)/2;l="error";(For[a=1,a<#,a++,For[b=1,b<a,b++,For[c=1,c<b,c++,If[Sqrt[s(s-a)(s-b)(s-c)]==#,l={a,b,c}]]]];l)&
J42161217
fonte
1
O Mathematica não tem um builtin? Surpreendente.
Neil A.
@ovs você também pode economizar um byte nisso Area@SSSTriangle[a,b,c].
Numbermaniac
0

Na verdade , 22 bytes

;╗R3@∙⌠;Σ½;)♀-π*╜²=⌡░F

Experimente online!

Explicação:

;╗R3@∙⌠;Σ½;)♀-π*╜²=⌡░F  (implicit input: A)
;╗                      store a copy of A in register 0
  R                     range(1, A+1)
   3@∙                  ternary Cartesian product (all triples with values in [1, A])
      ⌠;Σ½;)♀-π*╜²=⌡░   filter: take triples where function returns truthy
       ;Σ½                make a copy of the triple, compute s = (a+b+c)/2
          ;)              make a copy of s, move it to the bottom of the stack
            ♀-            subtract each value in the triple from s
              π*          product of those values and s (s*(s-a)*(s-b)*(s-c))
                ╜²        A*A
                  =       compare equality (does area of triangle with given dimensions equal input?)
                     F  take first triple that satisfies the filter (or empty list if none)
Mego
fonte
0

Casio Basic, 123 bytes

For 1⇒a To n
For 1⇒b To n
For 1⇒c To n
If(s*(s-a)*(s-b)*(s-c)|s=(a+b+c)/2)=n^2
Then
Print{a,b,c}
Stop
IfEnd
Next:Next:Next

Solução padrão de força bruta. 122 bytes para o código, 1 byte para especificar ncomo parâmetro.

numbermaniac
fonte