Kích thước của tôi là gì?


18

Nhiệm vụ: Cho diện tích của một hình tam giác, tìm một hình tam giác Heronia với diện tích đó. Bất kỳ tam giác Heronia với khu vực được chỉ định đều được cho phép.

Một tam giác Heronia là một tam giác có các cạnh nguyên và diện tích nguyên . Theo công thức của Heron, một hình tam giác với các cạnh dài a,b,ccó diện tích

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

trong đó s=(a+b+c)/2một nửa chu vi của tam giác. Điều này cũng có thể được viết là

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

Nếu không có tam giác như vậy tồn tại, đầu ra với giá trị falsey nhất quán.

Dữ liệu vào: Một số nguyên dương duy nhất biểu thị diện tích của tam giác.

Đầu ra: Bất kỳ độ dài ba cạnh nào cho một tam giác như vậy HOẶC giá trị sai.

Ví dụ:

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

Áp dụng sơ hở tiêu chuẩn

Đây là mã golf, câu trả lời ngắn nhất trong byte thắng.


6
Bạn có thể viết một định nghĩa tương đối súc tích về một tam giác Heronia trong thử thách của bạn không?
Okx

1
@Okx: Không rõ đó có phải là tam giác với các cạnh nguyên và diện tích nguyên không?
Neil A.

@Okx: Đó là ý tưởng. Tất cả bạn cần làm là tìm một ví dụ như vậy cho khu vực nhất định nếu nó tồn tại.
Neil A.

Từ liên kết Wikipedia: "Một tam giác Heronia là một tam giác có độ dài cạnh và diện tích là tất cả các số nguyên."
Neil A.

5
Bạn có thể vui lòng giải thích những gì khó hiểu về định nghĩa trong câu hỏi?
Neil A.

Câu trả lời:


6

Thạch , 17 16 byte

-1 byte nhờ Erik outgolfer (sử dụng nhanh, ¥)

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

Áp dụng vũ lực của công thức Heron.

Hãy thử trực tuyến! (hết thời gian 60 giây cho trường hợp thử nghiệm 114. Mất khoảng 30 giây tại địa phương - nó kiểm tra 114 3 = 1,481,544 bộ ba)

Làm sao?

Một giải pháp golf thực sự - với một khu vực, anó tìm thấy tất cả các bộ ba số nguyên nằm giữa 1a(ngay cả với các hình tam giác lặp lại và không có diện tích), có được khu vực và bộ lọc cho những người có diện tích mong muốn (thậm chí nó không dừng lại ngay khi một cái được tìm thấy, nó cày qua tất cả chúng và hiện ra kết quả đầu tiên sau đó). Sản lượng 0nếu không tồn tại.

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)

Tôi hình dung ai đó sẽ cố gắng vũ phu điều này, tốt đẹp!
Neil A.

@NeilA. Tôi tưởng tượng hầu hết các bài nộp golf sẽ là sức mạnh vũ phu cho thử thách này - nhưng một số người có thể xoay sở để được chơi golf trong khi kém hiệu quả hơn so với bài này.
Jonathan Allan

Bạn có thể thay thế çbằng Ç⁼¥và loại bỏ hoàn toàn dòng thứ hai.
Erik the Outgolfer

@EriktheOutgolfer Ồ, cảm ơn, tôi đã tự hỏi làm thế nào để đi về điều đó ...
Jonathan Allan

5

JavaScript (ES7), 109 102 100 98 byte

Trả về một mảng gồm 3 số nguyên hoặc false. Giống như câu trả lời của Jelly , đây là vũ phu buộc công thức của 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

Các trường hợp thử nghiệm


Phiên bản đệ quy, 83 byte

Trả về một mảng gồm 3 số nguyên hoặc đưa ra lỗi đệ quy. Đáng buồn thay, nó chỉ hoạt động cho đầu vào nhỏ.

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)

Bản giới thiệu


4

Haskell , 69 byte

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

Hãy thử trực tuyến!

Xuất ra một singleton của một danh sách ba cạnh tam giác như thế nào [[3.0,4.0,5.0]]. Đầu vào không thể cho []. Về mặt kỹ thuật chỉ Falselà Falsey cho Haskell, nhưng vì Haskell yêu cầu tất cả các đầu ra có thể phải cùng loại, nên không thể sử dụng nó. Nếu một lỗi có thể được sử dụng như Falsey, [...]!!0sẽ tiết kiệm được 3 byte take 1[..].

Thử tất cả các bộ ba tchiều dài có thể mỗi chiều từ 1khu vực a. Công thức Heron được sử dụng để kiểm tra xem khu vực này phù hợp qua (s-0)(s-x)(s-y)(s-z)==a*anơi s=(x+y+z)/2sum t/2. Sản phẩm (s-0)(s-x)(s-y)(s-z)được thể hiện dưới dạng a productvới các yếu tố được lấy từ 0:t, tức là bộ ba cũng như 0.


+1 cho khuôn mặt cười, ngay cả khi nó là một 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))

Hãy thử trực tuyến!

"Bị đánh cắp"

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

Nếu không tìm thấy kết quả, chương trình sẽ bị lỗi. Nếu điều này là không mong muốn, tôi phải thay thế List.findbằng List.filter(+2 byte) sẽ tạo ra một danh sách trống trong trường hợp không tìm thấy gì hoặc List.tryFind(+3 byte), trả về Không trong trường hợp không tìm thấy tam giác.

Tôi luôn thấy rằng một phiên bản F # được đánh golf vẫn còn hợp lý dễ đọc.


1
Tôi không biết F #, nhưng tôi tưởng tượng bạn có thể phân phối với System.Math.Sqrtvà so sánh giá trị kết quả với A * A?
Sean

@ Tất nhiên rồi! Cảm ơn vì tiền boa :)
Brunner

Việc thay thế 1.0..A [...] 1.0..A [...] 1.0..Abằng 1.0..A [...] a..A [..] b..Asẽ giúp bạn tiết kiệm một vài byte và tăng tốc cho bạn một chút (nếu nó hoạt động; tôi có kinh nghiệm F # rất tối thiểu).
CAD97

@ CAD97 Nó làm được! Cảm ơn đã chỉ ra rằng.
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

Hãy thử trực tuyến!

Mặc dù điều này cũng hoạt động trên CPython, PyPy nhanh hơn rất nhiều và có thể tính toán tam giác cho 114 trong thời gian giới hạn trên TIO.

Thời gian từ máy của tôi:

$ 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

Mà in một giá trị trung thực / giả, hoặc

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

trong đó in ra tất cả các giải pháp có thể, và chậm kinh khủng cho các đầu vào lớn. Đặt 'h' ở đầu để chỉ in một.

Giải trình:

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

Thử nó


1

Perl 6 , 54 byte

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

Tìm kiếm lực lượng vũ trang của tất cả các bên sở hữu ít hơn một, ít hơn akhu vực đầu vào.

  • ^alà phạm vi số từ 0 đến a - 1.
  • [X] ^a xx 3 giảm, bằng sản phẩm chéo, ba bản sao của phạm vi đó, tạo ra tất cả các bộ ba từ (0, 0, 0) đến (a - 1, a - 1, a - 1).
  • Chúng tôi tìm firstbộ ba sao cho diện tích của tam giác với các cạnh đó bằng nhau a, sử dụng công thức của Heron .

Trong khối mã được cung cấp cho first:

  • $_là bộ ba. Gọi nó đi(x, y, z) ở đây.
  • (0,|$_)là cùng một bộ ba nhưng có 0trước:(0, x, y, z) .
  • .sum / 2 là một nửa chu vi (một đại lượng được đặt tên s biểu thức thông thường của công thức Heron).
  • .sum / 2 «-« (0, |$_)là siêu phẫu thuật trừ với sbên trái và (0, x, y, z)bên phải, cho(s - 0, s - x, s - y, s - z) .
  • [*] sau đó giảm bộ tứ đó với phép nhân, cho bình phương của diện tích.
  • a * a == tìm kiếm một diện tích bình phương bằng với bình phương của khu vực nhất định.

Nếu không có bộ ba được tìm thấy, Nil(đó là falsey) được trả lại.


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]

Điều này đưa ra một danh sách các danh sách chứa tất cả các kích thước tích phân có thể tạo ra khu vực chính xác thông qua lực lượng vũ phu (xuất ra danh sách trống nếu không có). Sự cảnh báo là nó tạo ra chúng gấp đôi vì sự phân chia ở giữa nhưng phần phân số của chúng luôn là 0.

Nếu bạn vì một số lý do không thể lấy điều đó,

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]

Điều này sẽ đưa ra các câu trả lời dưới dạng một danh sách các danh sách số nguyên cho tổng số 89 77 byte hoặc 13 1 byte bổ sung. (Cảm ơn Neil)

Nếu bạn chỉ muốn / chỉ muốn phần tử đầu tiên đặt !!0ở cuối sẽ chỉ cung cấp cho bạn phần tử đầu tiên nếu có số áp dụng và lỗi nếu không có thêm 3 byte nào và take 1ở đầu sẽ lấy phần tử đầu tiên mà không bị lỗi Thêm 6 byte.

Hãy thử trực tuyến!


Nếu bạn muốn tránh nhân đôi, bạn có thể nhân phương trình với 4 cho mỗi bên không?
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
/

Hiển thị độ dài ba cạnh nếu có hình tam giác, sẽ xuất hiện lỗi cú pháp nếu không có (nhờ /vào cuối).

-1 byte nhờ nhận xét của Sean về một câu trả lời khác


0

Toán học, 77 byte

với toán học của 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]&

Toán học, 117 byte

lực lượng vũ phu

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 không có nội dung? Thật ngạc nhiên.
Neil A.

@ovs bạn cũng có thể lưu một byte trên đó Area@SSSTriangle[a,b,c].
numbermaniac

0

Trên thực tế , 22 byte

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

Hãy thử trực tuyến!

Giải trình:

;╗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 cơ bản, 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

Giải pháp vũ phu tiêu chuẩn. 122 byte cho mã, 1 byte để chỉ định nlàm tham số.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.