Quali sono le mie dimensioni?


18

Compito: data l'area di un triangolo, trova un triangolo Heronian con quell'area. È consentito qualsiasi triangolo heroniano con l'area specificata.

Un triangolo heroniano è un triangolo con lati interi e area intera . Con la formula di Heron, un triangolo con lunghezze laterali a,b,cha un'area

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

dove s=(a+b+c)/2è metà del perimetro del triangolo. Questo può anche essere scritto come

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

Se non esiste un triangolo del genere, emettere un valore di falso coerente.

Input: un singolo numero intero positivo che rappresenta l'area del triangolo.

Output: qualsiasi lunghezza di tre lati per un triangolo del genere O un valore errato.

Esempi:

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

Si applicano scappatoie standard

Questo è il codice golf, vince la risposta più breve in byte.


6
Puoi scrivere una definizione relativamente concisa di un triangolo heroniano nella tua sfida?
Okx,

1
@Okx: non è chiaro che si tratta di un triangolo con lati interi e area intera?
Neil A.

@Okx: questa è l'idea. Tutto quello che devi fare è trovare uno di questi esempi per l'area data se esiste.
Neil A.

Dal link Wikipedia: "Un triangolo heroniano è un triangolo che ha lunghezze laterali e area che sono tutti numeri interi".
Neil A.

5
Potresti spiegare cosa confonde la definizione nella domanda?
Neil A.

Risposte:


6

Gelatina , 17 16 byte

-1 byte grazie a Erik the outgolfer (usa il rapido ¥)

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

Applicazione della forza bruta della formula di Airone.

Provalo online! (raggiunge il timeout degli anni '60 per il caso di test 114. Prende 3m 30s localmente - controlla 114 3 = 1.481.544 triple)

Come?

Una vera soluzione da golf - data un'area ache trova tutte le tuple di tre numeri interi tra 1e a(anche con triangoli ripetuti e quelli senza area), ottiene la loro area e filtri per quelli con l'area desiderata (non si ferma nemmeno appena ne viene trovato uno, li attraversa tutti e fa scattare il primo risultato in seguito). Resa 0se non esiste.

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)

Ho pensato che qualcuno avrebbe provato a forzare questa forza, bello!
Neil A.

@NeilA. Immagino che la maggior parte dei contributi per il golf sarà una forza bruta per questa sfida, ma alcuni potrebbero riuscire a giocare a golf pur essendo meno ridicolmente inefficienti di questo.
Jonathan Allan,

È possibile sostituire çcon Ç⁼¥e rimuovere la seconda linea del tutto.
Erik the Outgolfer,

@EriktheOutgolfer Oh, grazie, mi stavo chiedendo come procedere ...
Jonathan Allan,

5

JavaScript (ES7), 109 102 100 98 byte

Restituisce una matrice di 3 numeri interi o false. Come la risposta di Jelly , questa è la forza bruta che costringe la formula di 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

Casi test


Versione ricorsiva, 83 byte

Restituisce un array di 3 numeri interi o genera un errore di ricorsione. Purtroppo, funziona solo per piccoli input.

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)

dimostrazione


4

Haskell , 69 byte

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

Provalo online!

Emette un singleton di un elenco di tre lati triangolari come [[3.0,4.0,5.0]]. Gli input impossibili danno []. Tecnicamente Falseè solo Falsey per Haskell, ma poiché Haskell richiede che tutti gli output possibili siano dello stesso tipo, non può essere utilizzato. Se un errore potesse essere usato come Falsey, [...]!!0si risparmierebbe 3 byte take 1[..].

Cerca tutte le triple tdi possibili lunghezze laterali ciascuna che vanno 1dall'area a. La formula di Heron viene utilizzata per verificare se l'area corrisponde tramite (s-0)(s-x)(s-y)(s-z)==a*adove si s=(x+y+z)/2trova sum t/2. Il prodotto (s-0)(s-x)(s-y)(s-z)è espresso come productcon elementi presi da 0:t, cioè il triplo e lo 0.


+1 per la faccina, anche se è una specie di noop
Julian Wolf

2

F #, 170 156 152 byte

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

Provalo 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 non vengono trovati risultati, il programma si guasta. Se questo non è desiderato, devo sostituirlo List.findcon List.filter(+2 byte) che produrrà un elenco vuoto nel caso in cui non venga trovato nulla o List.tryFind(+3 byte), restituendo Nessuno nel caso in cui non sia stato trovato alcun triangolo.

Trovo sempre che una versione F # giocata a golf sia ancora ragionevolmente leggibile.


1
Non conosco F #, ma immagino che potresti rinunciare a System.Math.Sqrte confrontare il valore risultante con A * A?
Sean,

@Sean Certo! Grazie per la punta :)
Brunner,

La sostituzione 1.0..A [...] 1.0..A [...] 1.0..Acon 1.0..A [...] a..A [..] b..Adovrebbe farti risparmiare un paio di byte e velocizzarti un po '(se funziona; ho un'esperienza F # minima).
CAD97,

@ CAD97 Lo fa! Grazie per la segnalazione.
Brunner,

2

Python 2 (PyPy) , 131 123 118 byte

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

Provalo online!

Mentre questo funziona anche su CPython, PyPy è molto più veloce ed è in grado di calcolare il triangolo per 114 nel limite di tempo su TIO.

Tempi dalla mia macchina:

$ 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

1

Pyth - 23 byte

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

Che stampa un valore di verità / falsità, o

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

che stampa tutte le possibili soluzioni ed è orribilmente lento per input di grandi dimensioni. Metti 'h' all'inizio per stamparne solo uno.

Spiegazione:

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

Provalo


1

Perl 6 , 54 byte

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

Ricerca della forza bruta di tutti i lati possibili fino a uno in meno adell'area di input.

  • ^aè l'intervallo di numeri da 0 a a - 1.
  • [X] ^a xx 3riduce, per prodotto incrociato, tre copie di quella gamma, producendo tutte le terzine da (0, 0, 0)a (a - 1, a - 1, a - 1).
  • Cerchiamo la firsttripletta in modo tale che l'area del triangolo con quei lati sia uguale a, usando la formula di Airone .

All'interno del blocco di codice assegnato a first:

  • $_è la tripletta. Chiamalo (x, y, z)qui.
  • (0,|$_)è lo stesso, ma con tripletta 0preposto: (0, x, y, z).
  • .sum / 2è la metà del perimetro (una quantità che è chiamata snella solita espressione della formula di Airone).
  • .sum / 2 «-« (0, |$_)è l'iperoperatore di sottrazione con sa sinistra e (0, x, y, z)a destra, dando (s - 0, s - x, s - y, s - z).
  • [*] quindi riduce quel quadruplo con moltiplicazione, dando il quadrato dell'area.
  • a * a == cerca un'area quadrata uguale al quadrato di una determinata area.

Se non viene trovata alcuna terzina, Nilviene restituito (che è falso).


1

Haskell , 76 byte

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]

Questo genera un elenco di elenchi contenenti tutte le possibili dimensioni integrali che generano l'area corretta tramite la forza bruta (producendo un elenco vuoto se non ce ne sono). L'avvertenza è che li emette come doppi a causa di quella divisione nel mezzo ma la loro parte frazionaria è sempre 0.

Se per qualche motivo non puoi accettarlo,

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]

Questo produrrà le risposte come un elenco di elenchi di numeri interi per 89 77 byte totali o 13 1 byte extra. (Grazie a Neil)

Se hai bisogno / desideri solo il primo elemento che mette !!0alla fine ti darà solo il primo elemento se ci sono numeri che si applicano e un errore se non ce ne sono per altri 3 byte e take 1all'inizio prenderà il primo elemento senza errori per 6 byte in più.

Provalo online!


Se vuoi evitare i doppi non puoi semplicemente moltiplicare l'equazione per 4 su ciascun lato?
Neil,

0

TI-Basic, 70 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
/

Visualizza le tre lunghezze laterali se è presente un triangolo, genera un errore di sintassi in caso contrario (grazie alla /fine).

-1 byte grazie al commento di Sean su una risposta diversa


0

Mathematica, 77 byte

con il sollievo di matematica

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 byte

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

1
Mathematica non ha un builtin? Sorprendente.
Neil A.

@ovs puoi anche salvare un byte su quello Area@SSSTriangle[a,b,c].
numbermaniac,

0

In realtà , 22 byte

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

Provalo online!

Spiegazione:

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

0

Casio Basic, 123 byte

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

Soluzione standard di forza bruta. 122 byte per il codice, 1 byte da specificare ncome parametro.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.