Apa dimensi saya?

18

Tugas: Mengingat luas segitiga, temukan segitiga Heronian dengan area itu. Segitiga Heronia dengan area yang ditentukan diperbolehkan.

Segitiga Heronian adalah segitiga dengan sisi bilangan bulat dan area bilangan bulat . Dengan rumus Heron, sebuah segitiga dengan panjang sisi a,b,cmemiliki luas

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

di mana s=(a+b+c)/2setengah perimeter segitiga. Ini juga dapat ditulis sebagai

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

Jika tidak ada segitiga seperti itu, output dengan nilai falsey yang konsisten.

Input: Bilangan bulat tunggal, positif yang mewakili area segitiga.

Output: Setiap tiga sisi panjang untuk segitiga seperti itu ATAU nilai yang salah.

Contoh:

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

Celah standar berlaku

Ini adalah kode golf, jawaban terpendek dalam byte menang.

Neil A.
sumber
6
Bisakah Anda menulis definisi segitiga Heronian yang relatif ringkas dalam tantangan Anda?
Okx
1
@ Okx: Apakah tidak jelas bahwa itu adalah segitiga dengan sisi integer dan area integer?
Neil A.
@Okx: Itulah idenya. Yang perlu Anda lakukan adalah menemukan satu contoh seperti itu untuk area yang diberikan jika ada.
Neil A.
Dari tautan Wikipedia: "Segitiga Heronian adalah segitiga yang memiliki panjang sisi dan area yang semuanya bilangan bulat."
Neil A.
5
Bisakah Anda jelaskan apa yang membingungkan tentang definisi dalam pertanyaan?
Neil A.

Jawaban:

6

Jelly , 17 16 byte

-1 byte terima kasih kepada Erik the outgolfer (gunakan quick, ¥)

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

Aplikasi brute force formula Heron.

Cobalah online! (mencapai waktu 60-an untuk 114 tes. Mengambil 3m 30-an secara lokal - ini memeriksa 114 3 = 1.481.544 tiga kali lipat)

Bagaimana?

Solusi golf sejati - diberikan area ayang menemukan semua tupel dari tiga bilangan bulat di antara 1dan a(bahkan dengan segitiga berulang dan yang tidak ada area), dapatkan area mereka dan filter untuk mereka yang memiliki area yang diinginkan (bahkan tidak berhenti segera setelah satu ditemukan, itu membajak mereka semua dan muncul hasil pertama sesudahnya). Hasil 0jika tidak ada.

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
sumber
Saya pikir seseorang akan mencoba untuk memaksa ini, bagus!
Neil A.
@NeilA. Saya membayangkan sebagian besar pengiriman golf akan menjadi kekuatan kasar untuk tantangan ini - tetapi beberapa mungkin berhasil bermain golf sementara menjadi kurang efisien dari yang ini.
Jonathan Allan
Anda dapat mengganti çdengan Ç⁼¥dan menghapus baris kedua seluruhnya.
Erik the Outgolfer
@EriktheOutgolfer Oh, terima kasih, saya bertanya-tanya bagaimana caranya ...
Jonathan Allan
5

JavaScript (ES7), 109 102 100 98 byte

Mengembalikan array 3 integer atau false. Seperti jawaban Jelly , ini dengan kasar memaksa formula 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

Uji kasus


Versi rekursif, 83 byte

Mengembalikan array 3 bilangan bulat atau melempar kesalahan rekursi. Sayangnya, ini hanya berfungsi untuk input kecil.

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

Haskell , 69 byte

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

Cobalah online!

Output tunggal dari daftar tiga sisi segitiga suka [[3.0,4.0,5.0]]. Masukan yang tidak mungkin diberikan []. Secara teknis hanya FalseFalsey untuk Haskell, tetapi karena Haskell membutuhkan semua output yang mungkin dari jenis yang sama, itu tidak dapat digunakan. Jika kesalahan dapat digunakan sebagai Falsey, [...]!!0akan menghemat 3 byte take 1[..].

Mencoba semua tiga kali lipat tdari panjang sisi masing-masing mulai dari 1ke daerah a. Rumus Heron digunakan untuk memeriksa apakah daerah cocok melalui (s-0)(s-x)(s-y)(s-z)==a*amana s=(x+y+z)/2adalah sum t/2. Produk (s-0)(s-x)(s-y)(s-z)dinyatakan sebagai productdengan elemen yang diambil 0:t, yaitu rangkap tiga dan 0.

Tidak
sumber
+1 untuk wajah yang tersenyum, meskipun itu bukan 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))

Cobalah online!

"Tidak Diundang"

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

Jika tidak ada hasil yang ditemukan, program akan salah. Jika ini tidak diinginkan, saya harus mengganti List.finddengan List.filter(+2 byte) yang akan menghasilkan daftar kosong jika tidak ada yang ditemukan atau List.tryFind(+3 byte), mengembalikan None jika tidak ada segitiga yang ditemukan.

Saya selalu menemukan bahwa versi F # golf masih terbaca wajar.

Brunner
sumber
1
Saya tidak tahu F #, tapi saya kira Anda bisa membuang System.Math.Sqrtdan membandingkan nilai yang dihasilkan A * A?
Sean
@Sean Tentu saja! Terima kasih atas tipnya :)
Brunner
Mengganti 1.0..A [...] 1.0..A [...] 1.0..Adengan 1.0..A [...] a..A [..] b..Aharus menghemat beberapa byte dan mempercepat Anda sedikit (jika berhasil; Saya memiliki pengalaman F # sangat minimal).
CAD97
@ CAD97 Benar! Terima kasih telah menunjukkannya.
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

Cobalah online!

Meskipun ini juga berfungsi pada CPython, PyPy jauh lebih cepat dan mampu menghitung segitiga untuk 114 dalam batas waktu pada TIO.

Pengaturan waktu dari mesin saya:

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

Pyth - 23 byte

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

Yang mencetak nilai kebenaran / kepalsuan, atau

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

yang mencetak semua solusi yang mungkin, dan sangat lambat untuk input besar. Masukkan 'h' di awal untuk hanya mencetak satu.

Penjelasan:

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

Cobalah

Maria
sumber
1

Perl 6 , 54 byte

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

Pencarian kasar dari semua sisi yang memungkinkan hingga satu kurang dari a, area input.

  • ^aadalah rentang angka dari 0 hingga a - 1.
  • [X] ^a xx 3mengurangi, dengan produk silang, tiga salinan dari kisaran itu, menghasilkan semua kembar tiga dari (0, 0, 0)ke (a - 1, a - 1, a - 1).
  • Kami mencari firsttriplet sedemikian rupa sehingga luas segitiga dengan sisi-sisinya sama a, menggunakan rumus Heron .

Di dalam blok kode yang diberikan kepada first:

  • $_adalah triplet. Sebut di (x, y, z)sini.
  • (0,|$_)adalah triplet yang sama tetapi dengan 0prepended: (0, x, y, z).
  • .sum / 2adalah setengah perimeter (jumlah yang disebutkan sdalam ungkapan biasa rumus Heron).
  • .sum / 2 «-« (0, |$_)adalah pengurangan hiperoperator dengan sdi kiri dan (0, x, y, z)di kanan, memberi (s - 0, s - x, s - y, s - z).
  • [*] kemudian mengurangi quadruplet itu dengan multiplikasi, memberikan kuadrat area tersebut.
  • a * a == mencari area kuadrat sama dengan kuadrat area yang diberikan.

Jika tidak ada triplet yang ditemukan, Nil(yang merupakan falsey) dikembalikan.

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

Ini menampilkan daftar daftar yang berisi semua kemungkinan ukuran integral yang menghasilkan area yang benar melalui kekuatan kasar (mengeluarkan daftar kosong jika tidak ada). Peringatan itu menghasilkan mereka dua kali lipat karena pembagian di tengah tetapi bagian pecahan mereka selalu 0.

Jika Anda karena suatu alasan tidak dapat mengambil itu,

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]

Ini akan menampilkan jawaban sebagai daftar daftar bilangan bulat untuk total 89 77 byte atau 13 1 byte tambahan. (Terima kasih kepada Neil)

Jika Anda hanya perlu / ingin elemen pertama yang diletakkan !!0di bagian akhir hanya akan memberi Anda elemen pertama jika ada angka yang berlaku dan kesalahan jika tidak ada untuk 3 byte lebih dan take 1pada awalnya akan mengambil elemen pertama tanpa kesalahan untuk 6 byte lagi.

Cobalah online!

Sersan Doggo
sumber
Jika Anda ingin menghindari ganda, tidak bisakah Anda mengalikan persamaan dengan 4 di setiap sisi?
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
/

Menampilkan panjang tiga sisi jika ada segitiga, melempar kesalahan sintaksis jika tidak ada (terima kasih /pada akhirnya).

-1 byte terima kasih atas komentar Sean pada jawaban yang berbeda

pizzapants184
sumber
0

Mathematica, 77 byte

dengan matematika Menyelesaikan

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

paksaan

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
sumber
1
Mathematica tidak memiliki builtin? Mengejutkan.
Neil A.
@ovs Anda dapat menyimpan satu byte pada itu Area@SSSTriangle[a,b,c]juga.
numbermaniac
0

Sebenarnya , 22 byte

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

Cobalah online!

Penjelasan:

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

Solusi brute force standar. 122 byte untuk kode, 1 byte untuk ditentukan nsebagai parameter.

numbermaniac
sumber