Quelles sont mes dimensions?

18

Tâche: Étant donné l'aire d'un triangle, trouvez un triangle héronien avec cette zone. Tout triangle héronien avec la zone spécifiée est autorisé.

Un triangle héronien est un triangle avec des côtés entiers et une zone entière . Selon la formule de Heron, un triangle avec des longueurs de côtés a,b,ca une aire

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

s=(a+b+c)/2est la moitié du périmètre du triangle. Cela peut également s'écrire

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

Si aucun triangle de ce type n'existe, sortez avec une valeur de falsey cohérente.

Entrée: Un entier positif unique représentant l'aire du triangle.

Sortie: trois longueurs de côté pour un tel triangle OU une valeur erronée.

Exemples:

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

Des échappatoires standard s'appliquent

C'est le golf de code, la réponse la plus courte en octets gagne.

Neil A.
la source
6
Pouvez-vous écrire une définition relativement concise d'un triangle héronien dans votre défi?
Okx
1
@Okx: N'est-il pas clair qu'il s'agit d'un triangle avec des côtés entiers et une zone entière?
Neil A.
@Okx: C'est l'idée. Tout ce que vous devez faire est de trouver un tel exemple pour la zone donnée si elle existe.
Neil A.
Du lien Wikipedia: "Un triangle héronien est un triangle qui a des longueurs latérales et une aire qui sont tous des entiers."
Neil A.
5
Pourriez-vous expliquer ce qui prête à confusion dans la définition de la question?
Neil A.

Réponses:

6

Gelée , 17 16 octets

-1 octet grâce à Erik le outgolfer (utilisez le quick, ¥)

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

Application de force brute de la formule de Heron.

Essayez-le en ligne! (atteint le délai d'expiration des années 60 pour le cas de 114 tests. Prend 3m 30 localement - il vérifie 114 3 = 1 481 544 triplets)

Comment?

Une vraie solution de golf - étant donné une zone, ail trouve tous les tuples de trois entiers entre 1et a(même avec des triangles répétés et ceux sans zone), obtient leur zone et des filtres pour ceux avec la zone souhaitée (elle ne s'arrête même pas dès que on en trouve un, il les parcourt tous et fait apparaître le premier résultat par la suite). Cède 0s'il n'en existe pas.

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
la source
J'ai pensé que quelqu'un essaierait de forcer ça, c'est bien!
Neil A.
@NeilA. J'imagine que la plupart des soumissions de golf seront une force brute pour ce défi - mais certains peuvent réussir à jouer au golf tout en étant moins ridiculement inefficaces que celui-ci.
Jonathan Allan
Vous pouvez remplacer çparÇ⁼¥ et retirer entièrement la deuxième ligne.
Erik the Outgolfer
@EriktheOutgolfer Oh, merci, je me demandais comment s'y prendre ...
Jonathan Allan
5

JavaScript (ES7), 109 102 100 98 octets

Renvoie un tableau de 3 entiers ou false. Comme la réponse de Jelly , c'est la force brute forçant la formule 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

Cas de test


Version récursive, 83 octets

Renvoie un tableau de 3 entiers ou renvoie une erreur de récursivité. Malheureusement, cela ne fonctionne que pour les petites entrées.

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)

Démo

Arnauld
la source
4

Haskell , 69 octets

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

Essayez-le en ligne!

Sort un singleton d'une liste de trois côtés de triangle comme [[3.0,4.0,5.0]]. Les entrées impossibles donnent []. Techniquement seulementFalse Falsey pour Haskell, mais comme Haskell requiert que toutes les sorties possibles soient du même type, il ne peut pas être utilisé. Si une erreur pouvait être utilisée comme Falsey, [...]!!0elle économiserait 3 octets take 1[..].

Essaie tous les triplets tde longueurs de côtés possibles allant de 1la zone a. La formule de Heron est utilisée pour vérifier si la zone correspond via (s-0)(s-x)(s-y)(s-z)==a*as=(x+y+z)/2est sum t/2. Le produit (s-0)(s-x)(s-y)(s-z)est exprimé comme un productavec des éléments pris 0:t, c'est-à-dire le triple ainsi que 0.

xnor
la source
+1 pour le visage souriant, même si c'est en quelque sorte un noop
Julian Wolf
2

F #, 170 156 152 octets

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

Essayez-le en ligne!

"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 aucun résultat n'est trouvé, le programme sera défectueux. Si cela n'est pas souhaité, je dois remplacer List.findpar List.filter(+2 octets) qui produira une liste vide au cas où rien ne serait trouvé ou List.tryFind(+3 octets), en retournant None au cas où aucun triangle n'aurait été trouvé.

Je trouve toujours qu'une version F # golfée est toujours assez lisible.

Brunner
la source
1
Je ne connais pas F #, mais j'imagine que vous pourriez vous passer de System.Math.Sqrtet comparer la valeur résultante à A * A?
Sean
@Sean Bien sûr! Merci pour le conseil :)
Brunner
Le remplacement 1.0..A [...] 1.0..A [...] 1.0..Apar 1.0..A [...] a..A [..] b..Adevrait vous faire économiser quelques octets et vous accélérer un peu (si cela fonctionne; j'ai une expérience F # très minimale).
CAD97
@ CAD97 C'est le cas! Merci d'avoir fait remarquer cela.
Brunner
2

Python 2 (PyPy) , 131 123 118 118 octets

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

Essayez-le en ligne!

Bien que cela fonctionne également sur CPython, PyPy est beaucoup plus rapide et est capable de calculer le triangle pour 114 dans la limite de temps sur TIO.

Horaires de ma machine:

$ 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
la source
1

Pyth - 23 octets

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

Qui imprime une valeur véridique / fausse, ou

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

qui imprime toutes les solutions possibles et est horriblement lent pour les grandes entrées. Mettez 'h' au début pour n'en imprimer qu'un.

Explication:

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

Essayez-le

Maria
la source
1

Perl 6 , 54 octets

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

Recherche de force brute de tous les côtés possibles jusqu'à un de moins que ala zone d'entrée.

  • ^a est la plage de nombres de 0 à a - 1 .
  • [X] ^a xx 3réduit, par produit croisé, trois copies de cette gamme, produisant tous les triplets de (0, 0, 0)à (a - 1, a - 1, a - 1).
  • Nous recherchons le firsttriplet de telle sorte que l'aire du triangle avec ces côtés soit égale a, en utilisant la formule de Heron .

Dans le bloc de code donné à first:

  • $_est le triplet. Appeler(x, y, z) ici.
  • (0,|$_)est le même triplet mais avec 0préfixé:(0, x, y, z) .
  • .sum / 2 est la moitié du périmètre (une quantité qui est nommée s dans l'expression habituelle de la formule de Heron).
  • .sum / 2 «-« (0, |$_)est l'hyperopératrice de soustraction avec sà gauche et (0, x, y, z)à droite, donnant(s - 0, s - x, s - y, s - z) .
  • [*] réduit ensuite ce quadruplet avec multiplication, donnant le carré de la zone.
  • a * a == recherche une zone carrée égale au carré de la zone donnée.

Si aucun triplet n'est trouvé, Nil(ce qui est falsey) est retourné.

Sean
la source
1

Haskell , 76 octets

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]

Cela génère une liste de listes contenant toutes les tailles intégrales possibles qui génèrent la zone correcte via la force brute (sortie de la liste vide s'il n'y en a pas). La mise en garde étant qu'il les sort sous forme de doubles en raison de cette division au milieu, mais leur partie fractionnaire est toujours 0.

Si pour une raison quelconque, vous ne pouvez pas accepter cela,

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]

Cela produira les réponses sous forme de liste de listes entières pour 89 77 octets au total ou 13 1 octets supplémentaires. (Merci à Neil)

Si vous avez besoin / ne voulez que le premier élément en le mettant !!0à la fin, vous ne recevrez que le premier élément s'il y a des nombres qui s'appliquent et une erreur s'il n'y en a pas pendant 3 octets de plus et take 1au début prendra le premier élément sans l'erreur pour 6 octets de plus.

Essayez-le en ligne!

Sgt. Se terrer
la source
Si vous voulez éviter les doubles, ne pouvez-vous pas simplement multiplier l'équation par 4 de chaque côté?
Neil
0

TI-Basic, 70 69 octets

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
/

Affiche les trois longueurs des côtés s'il y a un triangle, lance une erreur de syntaxe s'il n'y en a pas (grâce /à la fin).

-1 octet grâce au commentaire de Sean sur une réponse différente

pizzapants184
la source
0

Mathematica, 77 octets

avec Mathve's Solve

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 octets

Force brute

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
la source
1
Mathematica n'a pas de fonction intégrée? Surprenant.
Neil A.
@ovs, vous pouvez également enregistrer un octet avec Area@SSSTriangle[a,b,c].
numbermaniac
0

En fait , 22 octets

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

Essayez-le en ligne!

Explication:

;╗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
la source
0

Casio Basic, 123 octets

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

Solution standard de force brute. 122 octets pour le code, 1 octet à spécifier ncomme paramètre.

engourdi
la source