Was sind meine Dimensionen?

18

Aufgabe: Finden Sie für die Fläche eines Dreiecks ein heronisches Dreieck mit dieser Fläche. Jedes heronische Dreieck mit der angegebenen Fläche ist zulässig.

Ein Heronianisches Dreieck ist ein Dreieck mit ganzzahligen Seiten und einer ganzzahligen Fläche . Nach der Formel von Heron hat ein Dreieck mit Seitenlängen a,b,ceine Fläche

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

wo s=(a+b+c)/2ist der halbe Umfang des Dreiecks. Dies kann auch als geschrieben werden

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

Wenn kein solches Dreieck vorhanden ist, wird mit einem konsistenten Falsey-Wert ausgegeben.

Eingabe: Eine einzelne positive Ganzzahl, die die Fläche des Dreiecks darstellt.

Ausgabe: Beliebige drei Seitenlängen für ein solches Dreieck ODER ein falscher Wert.

Beispiele:

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

Es gelten Standardlücken

Dies ist Code Golf, die kürzeste Antwort in Bytes gewinnt.

Neil A.
quelle
6
Können Sie eine relativ präzise Definition eines heronischen Dreiecks in Ihrer Herausforderung schreiben?
Ok,
1
@Okx: Ist nicht klar, dass es sich um ein Dreieck mit ganzzahligen Seiten und ganzzahligem Bereich handelt?
Neil A.
@Okx: Das ist die Idee. Alles was Sie tun müssen, ist ein solches Beispiel für den gegebenen Bereich zu finden, falls es existiert.
Neil A.
Aus dem Wikipedia-Link: "Ein heronisches Dreieck ist ein Dreieck mit Seitenlängen und einer Fläche, die alle ganze Zahlen sind."
Neil A.
5
Können Sie bitte erläutern, was an der Definition in der Frage verwirrend ist?
Neil A.

Antworten:

6

Jelly , 17 16 Bytes

-1 Byte danke an Erik den Outgolfer (benutze den Quick, ¥)

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

Brute-Force-Anwendung der Heron-Formel.

Probieren Sie es online! (Erreicht das 60er-Zeitlimitfür den 114-Testfall. Nimmt 3m 30s vor Ort inAnspruch- überprüft 114 3 = 1.481.544 Dreifache)

Wie?

Eine echte Golflösung - in einem bestimmten Gebiet afindet sie alle Tupel mit drei ganzen Zahlen zwischen 1und a(auch bei wiederholten Dreiecken und solchen ohne Fläche), erhält ihre Fläche und filtert sie nach denjenigen mit der gewünschten Fläche (es hört nicht einmal auf, sobald Wenn eines gefunden wird, pflügt es durch alle und zeigt das erste Ergebnis an. Renditen, 0wenn keine vorhanden sind.

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
quelle
Ich dachte mir, dass jemand versuchen würde, dies zu brutal erzwingen, nett!
Neil A.
@NeilA. Ich stelle mir vor, dass die meisten Golf-Einsendungen für diese Herausforderung brachial sein werden - aber manche schaffen es vielleicht, Golf zu spielen, obwohl sie weniger lächerlich ineffizient sind als diese.
Jonathan Allan
Sie können ersetzen çmit Ç⁼¥und die zweite Zeile vollständig entfernen.
Erik der Outgolfer
@EriktheOutgolfer Oh, danke, ich habe mich gefragt, wie ich das anstellen soll ...
Jonathan Allan
5

JavaScript (ES7), 109 102 100 98 Byte

Gibt entweder ein Array mit 3 Ganzzahlen oder zurück false. Wie die Gelee-Antwort zwingt dies Herons Formel brachial.

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

Testfälle


Rekursive Version, 83 Bytes

Gibt ein Array mit 3 Ganzzahlen zurück oder löst einen Rekursionsfehler aus. Leider funktioniert es nur bei kleinen Eingaben.

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
quelle
4

Haskell , 69 Bytes

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

Probieren Sie es online!

Gibt einen Singleton aus einer Liste von drei Dreieckseiten wie aus [[3.0,4.0,5.0]]. Unmögliche Eingaben geben []. Nur technischFalse ist Falsey nur für Haskell, aber da Haskell alle möglichen Ausgaben des gleichen Typs benötigt, kann es nicht verwendet werden. Wenn ein Fehler als Falsey verwendet werden könnte, [...]!!0würden über 3 Bytes gespart take 1[..].

Versucht alle dreifachen tmöglichen Seitenlängen von 1bis zum Bereich a. Die Formel von Heron wird verwendet, um zu überprüfen, ob der Bereich über " (s-0)(s-x)(s-y)(s-z)==a*awhere s=(x+y+z)/2is" übereinstimmt sum t/2. Das Produkt (s-0)(s-x)(s-y)(s-z)wird als productmit Elementen aus ausgedrückt 0:t, dh das Dreifache sowie 0.

xnor
quelle
+1 für Smiley-Gesicht, auch wenn es ein bisschen Noop ist
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))

Probieren Sie es 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))

Wenn keine Ergebnisse gefunden werden, schlägt das Programm fehl. Wenn dies nicht gewünscht ist, muss ich List.findentweder ersetzenList.filter (+2 Bytes) was eine leere Liste erzeugt, falls nichts gefunden wird, oderList.tryFind (+3 Bytes), und None zurückgeben, falls kein Dreieck gefunden wurde.

Ich finde immer, dass eine Golf-F # -Version noch vernünftig lesbar ist.

Brunner
quelle
1
Ich kenne F # nicht, aber ich stelle mir vor, Sie könnten auf das verzichten System.Math.Sqrtund den resultierenden Wert mit vergleichen A * A.
Sean
@ Sean Natürlich! Danke für den Tipp :)
Brunner
Das Ersetzen 1.0..A [...] 1.0..A [...] 1.0..Adurch 1.0..A [...] a..A [..] b..Asollte Ihnen ein paar Bytes sparen und Sie ein wenig beschleunigen (wenn es funktioniert; ich habe nur sehr wenig F # -Erfahrung).
CAD97
@ CAD97 Das tut es! Vielen Dank für den Hinweis.
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

Probieren Sie es online!

Dies funktioniert zwar auch mit CPython, PyPy ist jedoch viel schneller und kann das Dreieck für 114 im Zeitlimit von TIO berechnen.

Timings von meiner Maschine:

$ 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
quelle
1

Pyth - 23 Bytes

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

Womit ein wahrer / falscher Wert ausgegeben wird, oder

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

Das druckt alle möglichen Lösungen aus und ist für große Eingaben furchtbar langsam. Setzen Sie 'h' an den Anfang, um nur eines zu drucken.

Erläuterung:

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

Versuch es

Maria
quelle
1

Perl 6 , 54 Bytes

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

Brute-Force-Suche aller möglichen Seiten bis zu einer Seite weniger als adem Eingabebereich.

  • ^aist der Zahlenbereich von 0 bis a - 1.
  • [X] ^a xx 3reduziert durch Kreuzprodukt drei Kopien dieses Bereichs und erzeugt alle Tripletts von (0, 0, 0)bis (a - 1, a - 1, a - 1).
  • Wir suchen das firstTriplett so, dass die Fläche des Dreiecks mit diesen Seiten anach der Formel von Heron gleich ist .

Innerhalb des Codeblocks gegeben an first:

  • $_ist das Triplett. Nennen Sie es (x, y, z)hier.
  • (0,|$_)ist die gleiche Triplett aber mit 0vorangestellt: (0, x, y, z).
  • .sum / 2ist die Hälfte des Umfangs (eine Größe, die sim üblichen Ausdruck der Heronschen Formel genannt wird).
  • .sum / 2 «-« (0, |$_)ist der Subtraktions-Hyperoperator mit slinks und (0, x, y, z)rechts, der gibt (s - 0, s - x, s - y, s - z).
  • [*] Dann wird das Quadruplett durch Multiplikation reduziert, wobei das Quadrat der Fläche erhalten wird.
  • a * a == Sucht nach einer quadratischen Fläche, die dem Quadrat der angegebenen Fläche entspricht.

Wird kein Triplett gefunden, wird Nil(was falsch ist) zurückgegeben.

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

Dies gibt eine Liste von Listen mit allen möglichen Integralgrößen aus, die den korrekten Bereich durch Brute Force erzeugen (Ausgabe der leeren Liste, falls keine vorhanden sind). Die Einschränkung ist, dass sie aufgrund dieser Unterteilung in der Mitte als Doppel ausgegeben werden, ihr Bruchteil jedoch immer 0 ist.

Wenn Sie aus irgendeinem Grund das nicht ertragen können,

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]

Dies wird Ausgang die Antworten als eine Liste von Listen für die ganze Zahl 89 77 Bytes insgesamt oder 13 1 zusätzliches Byte. (Danke an Neil)

Wenn Sie nur das erste Element brauchen / wollen !!0, erhalten Sie nur das erste Element, wenn es Zahlen gibt, die zutreffen, und einen Fehler, wenn es keine für 3 weitere Bytes gibt, und take 1am Anfang wird das erste Element genommen, ohne dass ein Fehler auftritt 6 weitere Bytes.

Probieren Sie es online!

Sgt. Doggo
quelle
Wenn Sie Doppel vermeiden möchten, können Sie die Gleichung nicht einfach mit 4 auf jeder Seite multiplizieren?
Neil
0

TI-Basic, 70 bis 69 Byte

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
/

Zeigt die drei Seitenlängen an, wenn ein Dreieck vorhanden ist, und gibt einen Syntaxfehler aus, wenn dies nicht der Fall ist (dank der / am Ende).

-1 Byte dank Seans Kommentar zu einer anderen Antwort

Pizzapants184
quelle
0

Mathematica, 77 Bytes

mit der mathematischen Lösung

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

rohe Gewalt

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
quelle
1
Mathematica hat kein eingebautes? Überraschend.
Neil A.
Mit @ovs können Sie auch ein Byte speichern Area@SSSTriangle[a,b,c].
numbermaniac
0

Eigentlich 22 Bytes

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

Probieren Sie es online!

Erläuterung:

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

Standard-Brute-Force-Lösung. 122 Byte für den Code, 1 Byte nals Parameter anzugeben .

numbermaniac
quelle