Які мої розміри?


18

Завдання: Враховуючи площу трикутника, знайдіть трикутник Героя з цією площею. Дозволяється будь-який геройський трикутник із вказаною областю.

Геронічний трикутник - це трикутник із цілими сторонами та цілою площею . За формулою Герона трикутник із довжиною сторін a,b,cмає площу

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

де s=(a+b+c)/2половина периметра трикутника. Це також можна записати як

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

Якщо такого трикутника немає, виведіть з послідовним значенням фальси.

Введення: Одне, додатне ціле число, що представляє область трикутника.

Вихід: Будь-які три сторони довжини для такого трикутника АБО помилкове значення.

Приклади:

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

Застосовуються стандартні лазівки

Це кодовий гольф, найкоротша відповідь у виграші байтів.


6
Чи можете ви написати своє порівняльне стисле визначення геронського трикутника у своєму виклику?
Okx

1
@Okx: Чи не ясно, що це трикутник із цілими сторонами та цілою площею?
Ніл А.

@Okx: Це ідея. Все, що вам потрібно зробити - це знайти один такий приклад для даної області, якщо він існує.
Ніл А.

З посилання Вікіпедії: "Геронічний трикутник - це трикутник, який має бічні довжини та площу, які є усіма цілими числами".
Ніл А.

5
Чи можете ви поясніть, що бентежить визначення у питанні?
Ніл А.

Відповіді:


6

Желе , 17 16 байт

-1 байт завдяки Еріку перевершився (скористайтеся швидким, ¥)

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

Застосування жорстокої формули формули Герона.

Спробуйте в Інтернеті! (досягає часу 60-х для випробування з 114 тестів. Займає 3 м 30-х локально - перевіряє 114 3 = 1,481,544 трійки)

Як?

Справжнє рішення для гольфу - з огляду на область, aвона знаходить усі кортежі з трьох цілих чисел між ( 1і aнавіть з повторними трикутниками та одиницями без площі), отримує їх площу та фільтрує для тих, у кого потрібна область (вона навіть не зупиняється, як тільки один знайдений, він пронизує їх усі і виштовхує перший результат згодом). Урожайність, 0якщо такої немає.

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)

Я подумав, що хтось спробує це жорстоко спробувати!
Ніл А.

@NeilA. Я думаю, що більшість заявок на гольф стануть грубою силою для цього виклику - але деякі можуть встигнути стати в гольф, будучи менш смішно неефективними, ніж ця.
Джонатан Аллан

Ви можете замінити çз Ç⁼¥і видаліть другий рядок цілком.
Ерік Аутгольфер

@EriktheOutgolfer О, дякую, мені було цікаво, як піти з цим питанням ...
Джонатан Аллан

5

JavaScript (ES7), 109 102 100 98 байт

Повертає або масив з 3 цілих чисел, або false. Як і відповідь Джелі , це жорстока форсунка формули Герона.

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

Тестові справи


Рекурсивна версія, 83 байти

Повертає масив з 3 цілих чисел або видаляє помилку рекурсії. На жаль, він працює лише для невеликих входів.

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)

Демо


4

Haskell , 69 байт

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

Спробуйте в Інтернеті!

Виводить одинарний список із трьох сторін трикутника, як [[3.0,4.0,5.0]]. Неможливі входи дають []. Технічно це лише FalseFalsey для Haskell, але оскільки Haskell вимагає, щоб усі можливі виходи були одного типу, він не може бути використаний. Якщо помилка може бути використана як Falsey, врятується [...]!!03 байти take 1[..].

Спробує всі трійки tможливих бічних довжин, кожна починаючи від 1району a. Формула Герона використовується для перевірки, чи збігається площа з тим, (s-0)(s-x)(s-y)(s-z)==a*aде s=(x+y+z)/2знаходиться sum t/2. Продукт (s-0)(s-x)(s-y)(s-z)виражається як productз елементами, взяті з 0:t, тобто потрійним, а також 0.


+1 для усміхненого обличчя, навіть якщо це сортування noop
Джуліан Вольф

2

F #, 170 156 152 байт

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

Спробуйте в Інтернеті!

"Безголів"

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

Якщо результатів не знайдено, програма вийде з ладу. Якщо цього не потрібно, я повинен замінити List.findабо List.filter(+2 байти), що створить порожній список у випадку, якщо нічого не буде знайдено, або List.tryFind(+3 байти), повертаючи Нічого, якщо трикутник не знайдено.

Я завжди вважаю, що версія F # із гольфом все ще досить розбірлива.


1
Я не знаю F #, але я думаю, ви могли б обійтися з System.Math.Sqrtі порівняти отримане значення з A * A?
Шон

@Sean Звичайно! Дякую за пораду :)
Бруннер

Заміна 1.0..A [...] 1.0..A [...] 1.0..Aз 1.0..A [...] a..A [..] b..Aслід зберегти вам пару байтів і швидкість вас трохи (якщо він працює, у мене є дуже мінімальне F # досвід).
CAD97

@ CAD97 Це так! Дякуємо, що вказали на це.
Бруннер

2

Python 2 (PyPy) , 131 123 118 байт

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

Спробуйте в Інтернеті!

Хоча це також працює на CPython, PyPy набагато швидше і здатний обчислити трикутник на 114 у часовому обмеженні на TIO.

Час роботи моєї машини:

$ 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 байти

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

Який друкує значення "фальшива / хибна" чи

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

який друкує всі можливі рішення і страшенно повільний для великих входів. Поставте "h" на початку, щоб надрукувати лише одну.

Пояснення:

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

Спробуй це


1

Perl 6 , 54 байти

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

Швидкий примусовий пошук усіх можливих сторін на одну меншу, ніж aобласть введення.

  • ^a- діапазон чисел від 0 до a - 1.
  • [X] ^a xx 3зменшує, шляхом перехресного продукту, три екземпляри цього діапазону, створюючи всі трійки від (0, 0, 0)до (a - 1, a - 1, a - 1).
  • Шукаємо firstтриплет таким, що площа трикутника з цими сторонами дорівнює a, використовуючи формулу Герона .

У кодовому блоці надано first:

  • $_є триплетом. Зателефонуйте (x, y, z)сюди.
  • (0,|$_)одне і те ж триплет , але з 0префіксом: (0, x, y, z).
  • .sum / 2- половина периметра (величина, яка названа sу звичайному виразі формули Герона).
  • .sum / 2 «-« (0, |$_)- це віднімання гіпероператора з sліворуч і (0, x, y, z)праворуч, що дає (s - 0, s - x, s - y, s - z).
  • [*] потім зменшує цю четвертину з множенням, даючи квадрат площі.
  • a * a == шукає площу квадрата, рівну площі даної площі.

Якщо триплета не знайдено, Nil(який фальсифікується) повертається.


1

Haskell , 76 байт

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]

Це виводить список списків, що містять усі можливі цілісні розміри, які генерують правильну область за допомогою грубої сили (виводить порожній список, якщо його немає). Застереження, яке воно створює, виводить їх як подвійне через поділ посередині, але їх дробова частина завжди дорівнює 0.

Якщо ви з якихось причин не можете цього прийняти,

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]

Це дасть відповіді у вигляді списку цілих списків на загальну кількість 89 77 байт або 13 1 додаткових байтів. (Дякую Нілу)

Якщо вам потрібен / хочете лише перший елемент, просто поставлення !!0в кінці дасть вам лише перший елемент, якщо є числа, які застосовуються, і помилка, якщо немає ще 3 байти, і take 1на початку візьме перший елемент без помилок для Ще 6 байт.

Спробуйте в Інтернеті!


Якщо ви хочете уникнути подвоєнь, чи не можете ви просто помножити рівняння на 4 з кожної сторони?
Ніл

0

TI-Basic, 70 69 байт

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
/

Відображає три сторони довжини, якщо є трикутник, видає синтаксичну помилку, якщо її немає (завдяки /в кінці).

-1 байт завдяки коментарю Шона щодо іншої відповіді


0

Математика, 77 байт

з математикою Розв’язати

s=(a+b+c)/2;d=Sqrt[s(s-a)(s-b)(s-c)];Solve[d==#&&0<a<b<c<#,{a,b,c},Integers]&

Математика, 117 байт

груба сила

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 немає вбудованого? Дивно.
Ніл А.

@ovs ви можете також зберегти один байт на цьому Area@SSSTriangle[a,b,c].
numbermaniac

0

Власне , 22 байти

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

Спробуйте в Інтернеті!

Пояснення:

;╗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 байти

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

Стандартне рішення грубої сили. 122 байти для коду, 1 байт вказати nяк параметр.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.