¿Cuáles son mis dimensiones?

18

Tarea: Dado el área de un triángulo, encuentre un triángulo heroniano con esa área. Se permite cualquier triángulo heroniano con el área especificada.

Un triángulo heroniano es un triángulo con lados enteros y área entera . Por la fórmula de Heron, un triángulo con lados de longitud a,b,ctiene área

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

donde s=(a+b+c)/2es la mitad del perímetro del triángulo. Esto también se puede escribir como

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

Si no existe tal triángulo, salida con un valor de falsey consistente.

Entrada: Un entero positivo único que representa el área del triángulo.

Salida: Cualquier longitud de tres lados para tal triángulo O un valor falso.

Ejemplos:

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

Se aplican lagunas estándar

Este es el código de golf, la respuesta más corta en bytes gana.

Neil A.
fuente
66
¿Puedes escribir una definición relativamente concisa de un triángulo heroniano en tu desafío?
Okx
1
@Okx: ¿No está claro que es un triángulo con lados enteros y área entera?
Neil A.
@Okx: Esa es la idea. Todo lo que necesita hacer es encontrar un ejemplo para el área dada si existe.
Neil A.
Desde el enlace de Wikipedia: "Un triángulo heroniano es un triángulo que tiene longitudes laterales y área que son todos enteros".
Neil A.
55
¿Podría explicar qué es confuso acerca de la definición en la pregunta?
Neil A.

Respuestas:

6

Jalea , 17 16 bytes

-1 byte gracias a Erik el outgolfer (utiliza el rápido, ¥)

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

Aplicación de fuerza bruta de la fórmula de Heron.

Pruébalo en línea! (alcanza el tiempo de espera de 60 para el caso de 114 pruebas. Toma 3m 30s localmente - comprueba 114 3 = 1,481,544 triples)

¿Cómo?

Una verdadera solución de golf: dado un área adonde encuentra todas las tuplas de tres enteros entre 1y a(incluso con triángulos repetidos y sin área), obtiene su área y filtros para aquellos con el área deseada (ni siquiera se detiene tan pronto se encuentra uno, los atraviesa a todos y aparece el primer resultado después). Cede 0si no existe ninguno.

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
fuente
Me imaginé que alguien trataría de forzarlo, ¡genial!
Neil A.
@NeilA. Me imagino que la mayoría de las presentaciones de golf serán una fuerza bruta para este desafío, pero algunas pueden jugar golf mientras son menos ridículas e ineficientes que esta.
Jonathan Allan
Se puede reemplazar çcon Ç⁼¥y retire la segunda línea por completo.
Erik the Outgolfer
@EriktheOutgolfer Oh, gracias, me preguntaba cómo hacerlo ...
Jonathan Allan
5

JavaScript (ES7), 109 102 100 98 bytes

Devuelve una matriz de 3 enteros o false. Al igual que la respuesta de Jelly , esta es la fuerza bruta que obliga a la 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 prueba


Versión recursiva, 83 bytes.

Devuelve una matriz de 3 enteros o arroja un error de recursión. Lamentablemente, solo funciona para entradas pequeñas.

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)

Manifestación

Arnauld
fuente
4

Haskell , 69 bytes

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

Pruébalo en línea!

Produce un singleton de una lista de tres lados triangulares como [[3.0,4.0,5.0]]. Las entradas imposibles dan []. Técnicamente solo Falsees Falsey para Haskell, pero debido a que Haskell requiere que todas las salidas posibles sean del mismo tipo, no se puede usar. Si se pudiera utilizar un error como Falsey, [...]!!0se ahorrarían 3 bytes take 1[..].

Intenta todos los triples tde posibles longitudes laterales, cada uno desde 1el área a. La fórmula de Heron se usa para verificar si el área coincide con (s-0)(s-x)(s-y)(s-z)==a*adonde s=(x+y+z)/2está sum t/2. El producto (s-0)(s-x)(s-y)(s-z)se expresa como un productelemento tomado de 0:t, es decir, el triple y el 0.

xnor
fuente
+1 para cara sonriente, incluso si es una especie de noop
Julian Wolf
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))

Pruébalo en línea!

"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))

Si no se encuentran resultados, el programa fallará. Si esto no se desea, tengo que reemplazar List.findcon List.filter(+2 bytes) que producirá una lista vacía en caso de que no se encuentre nada o List.tryFind(+3 bytes), devolviendo Ninguno en caso de que no se encuentre ningún triángulo.

Siempre encuentro que una versión F # de golf sigue siendo razonablemente legible.

Brunner
fuente
1
No sé F #, pero me imagino que podría prescindir del System.Math.Sqrty comparar el valor resultante con A * A?
Sean
@Sean ¡Por supuesto! Gracias por el consejo :)
Brunner
Sustitución 1.0..A [...] 1.0..A [...] 1.0..Acon 1.0..A [...] a..A [..] b..Aque debe guardar un par de bytes y que la velocidad un poco (si funciona, no tengo muy mínima experiencia # F).
CAD97
@ CAD97 ¡Lo hace! Gracias por señalar eso.
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

Pruébalo en línea!

Si bien esto también funciona en CPython, PyPy es mucho más rápido y puede calcular el triángulo para 114 en el límite de tiempo en TIO.

Tiempos de mi 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
fuente
1

Pyth - 23 bytes

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

Que imprime un valor verdadero / falso, o

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

que imprime todas las soluciones posibles y es terriblemente lento para entradas grandes. Ponga 'h' al principio para imprimir solo uno.

Explicación:

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

Intentalo

Maria
fuente
1

Perl 6 , 54 bytes

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

Búsqueda de fuerza bruta de todos los lados posibles hasta uno menos que ael área de entrada.

  • ^aes el rango de números del 0 al a - 1.
  • [X] ^a xx 3reduce, por producto cruzado, tres copias de ese rango, produciendo todos los trillizos de (0, 0, 0)a (a - 1, a - 1, a - 1).
  • Buscamos el firsttriplete de manera que el área del triángulo con esos lados sea igual a, usando la fórmula de Heron .

Dentro del bloque de código dado a first:

  • $_es el triplete Llámalo (x, y, z)aquí.
  • (0,|$_)es el mismo triplete pero con 0antepuesto: (0, x, y, z).
  • .sum / 2es la mitad del perímetro (una cantidad que se nombra sen la expresión habitual de la fórmula de Heron).
  • .sum / 2 «-« (0, |$_)es la resta del hiperoperador sa la izquierda y (0, x, y, z)a la derecha, dando (s - 0, s - x, s - y, s - z).
  • [*] luego reduce ese cuadruplete con multiplicación, dando el cuadrado del área.
  • a * a == busca un área cuadrada igual al cuadrado del área dada.

Si no se encuentra un triplete, Nil(que es falsey) se devuelve.

Sean
fuente
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]

Esto genera una lista de listas que contienen todos los tamaños integrales posibles que generan el área correcta mediante la fuerza bruta (generando la lista vacía si no hay ninguna). La advertencia es que los genera como dobles debido a esa división en el medio, pero su parte fraccionaria siempre es 0.

Si por alguna razón no puedes soportar eso,

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]

Esto generará las respuestas como una lista de listas enteras para 89 77 bytes en total o 13 1 bytes adicionales. (Gracias a Neil)

Si necesita / desea solo el primer elemento que acaba de poner !!0al final le dará solo el primer elemento si hay números que se aplican y un error si no hay ninguno para 3 bytes más y take 1al principio tomará el primer elemento sin error para 6 bytes más.

Pruébalo en línea!

El sargento Escondido
fuente
Si quieres evitar los dobles, ¿no puedes simplemente multiplicar la ecuación por 4 en 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
/

Muestra las tres longitudes laterales si hay un triángulo, arroja un error de sintaxis si no lo hay (gracias al /final).

-1 byte gracias al comentario de Sean sobre una respuesta diferente

pizzapants184
fuente
0

Mathematica, 77 bytes

con la resolución de Mathica

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

fuerza 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
fuente
1
¿Mathematica no tiene una construcción? Sorprendente.
Neil A.
@ovs también puedes guardar un byte en eso Area@SSSTriangle[a,b,c].
numbermaniac
0

En realidad , 22 bytes

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

Pruébalo en línea!

Explicación:

;╗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
fuente
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

Solución estándar de fuerza bruta. 122 bytes para el código, 1 byte para especificar ncomo parámetro.

numbermaniac
fuente