Оценить соотношение сторон треугольника

35

Учитывая три длины стороны треугольника, оцените его соотношение сторон AR, используя следующую формулу:

введите описание изображения здесь

где

введите описание изображения здесь

Чем ближе к равносторонности треугольник, тем ближе к 1его аспектному соотношению. Соотношение сторон больше или равно 1для правильных треугольников.

входные

Входные данные представляют собой три действительных положительных числа, которые могут быть включены в список или что-либо подобное, если это необходимо.

Ваша программа должна выводить одно и то же значение независимо от того, в каком порядке введены три длины сторон.

Эти три номера всегда будут действительны sidelengths треугольника (вырожденные треугольники , как один с sidelengths 1, 1и 2не будет передан в качестве вклада). Вам не нужно беспокоиться о неточностях с плавающей запятой, когда значения становятся очень близко к вырожденному треугольнику (например, допустимо, что ваша программа выдаст ошибку division by 0при вводе [1, 1, 1.9999999999999999]).

Входные данные могут быть переданы через STDINаргумент функции или что-либо подобное.

Выходы

Вывод представляет собой действительное число, большее или равное 1стандартной точности, приемлемой для вашего языка.

Вывод может быть распечатан STDOUT, возвращен из функции или чем-то подобным.

Контрольные примеры

Inputs                   Output

  1      1      1         1
  3      4      5         1.25
 42     42   3.14         ≈ 6.9476
 14      6     12         1.575
  6     12     14         1.575
0.5    0.6    0.7         ≈ 1.09375

счет

Это , поэтому выигрывает самый короткий ответ в байтах.

Fatalize
источник
должно быть s (a + b + c) / 3 ?
Costrom
3
@costrom Нет, формула верна. s - полупериметр треугольника . Ваша формула будет неопределенной для равностороннего треугольника.
Fatalize
Могу ли я просто получить числа с плавающей запятой для ввода или мне нужно также получить целые числа?
Эрик Outgolfer
@ErikGolfer acceptable リ ッ ク ゴ ル フ ァ acceptable Допускается ввод 42.0вместо 42.
Fatalize
@Fatalize Спасибо. Кроме того, все ли входы могут быть 0?
Эрик Outgolfer

Ответы:

19

Желе , 6 байт

Этот ответ основан на ответе Эминьи 05AB1E . Большое спасибо Деннису и Линн за помощь в выяснении этого ответа. Предложения по игре в гольф приветствуются! Попробуйте онлайн!

S_Ḥ⁸÷P

Ungolfing

           Implicit argument [a, b, c].
S          Take the sum, a+b+c or 2*s
  Ḥ        Take the double, [2*a, 2*b, 2*c].
 _         Vectorized subtract, giving us [2*(s-a), 2*(s-b), 2*(s-c)].
   ⁸÷      Vectorized divide the initial left argument, the input [a, b, c],
             by [2*(s-a), 2*(s-b), 2*(s-c)].
     P     Take the product giving us the aspect ratio, abc/8(s-a)(s-b)(s-c).
Sherlock9
источник
4
6 байт, и вы все еще хотите предложения по игре в гольф? :-D
Луис Мендо
1
@LuisMendo Если это вообще возможно, обязательно: D
Sherlock9
1
«Толчок» не совсем правильная терминология; Желе не основано на стеке. Скорее, ⁸÷он отключается от цепочки как единое целое и должен читаться как деление начального левого аргумента на это или что-то еще.
Линн
1
@ Линн Я играю в гольф на самом деле уже несколько месяцев. Основанная на стеке терминология прочно вклинивается в мой мозг: D Нужно исправить сейчас.
Sherlock9
56

Желе , 7 байт

SH_÷@HP

Попробуйте онлайн!

объяснение

enter image description here

Давайте прочитаем эту цепочку:

  • Неявный аргумент - это список [a, b, c].

  • Сначала мы читаем S. Это берет сумму: a + b + c.

  • Затем мы читаем H. Это вдвое меньше (a + b + c)/2. (Это s.)

  • Затем мы читаем диаду _(вычитаем), а затем еще одну диаду. Это хук : ему не хватает правильного аргумента, поэтому он получает аргумент для этой цепочки [a, b, c], давая нам [s-a, s-b, s-c]. (Это пятая цепочка в таблице здесь .)

  • Затем мы читаем пару диада-монада ÷@H. Это разветвление : ÷@это деление с перевернутыми аргументами, и Hоно Hделится пополам , так что наше рабочее значение получает от него аргумент этой цепочки ÷. Это векторизация; мы остались с[(a/2)/(s-a), (b/2)/(s-b), (c/2)/(s-c)] . (Это второй шаблон цепочки в таблице здесь .)

  • Наконец, мы берем продукт P, получая нас abc/(8(s-a)(s-b)(s-c)).

Просмотрите древовидный график того, как ссылки сочетаются друг с другом.

Линн
источник
8
Изображения выглядят великолепно! Приятное прикосновение!
DavidC
2
Я сам уменьшил верхнее изображение и превратил второе в ссылку (без каламбура).
Линн
Я увидел изображение и сразу подумал: «Хорошая, Линн!» прежде чем смотреть, кто это опубликовал ;-)
ETHproductions
7
Лучшее объяснение, которое я видел в программе Jelly. Я до сих пор не понимаю, но ближе!
Спарр
Я проверил выборку по контрольному случаю «6,0,12,0,14,0», и он дал «-0,8888888888888888» вместо 1,575, как показано в контрольных примерах. Это проблема с тест-кейсами или вашим кодом?
MBaas
13

Желе , 6 байт

S÷_2Pİ

Попробуйте онлайн!

Как это работает

S÷_2Pİ  Main link. Argument: [a, b, c]

S       Sum; compute 2s := a + b + c.
 ÷      Divide; yield [2s ÷ a, 2s ÷ b, 2s ÷ c].
  _2    Subtract 2; yield [2s ÷ a - 2, 2s ÷ b - 2, 2s ÷ c - 2].
    P   Product; yield (2s ÷ a - 2)(2s ÷ b - 2)(2s ÷ c - 2).
     İ  Invert; yield 1 ÷ (2s ÷ a - 2)(2s ÷ b - 2)(2s ÷ c - 2).
Деннис
источник
Ааа, и я попытался использовать в ³⁴⁵качестве аргументов ...
Эрик Outgolfer
11

JavaScript, 38 байт

Это ( карри ) лямбда:

a=>b=>c=>a*b*c/(b+c-a)/(a+c-b)/(a+b-c)

(Если вы назначите его переменной, fвам нужно будет вызвать его как f(3)(4)(5))

flawr
источник
Ударь меня в этом на несколько секунд :) Не могли бы вы объяснить, как работает формула, аналогичная приведенной в вопросе?
Kritixi Lithos
@KritixiLithos Просто подключитесь s = 1/2(a+b+c)к формуле и упростите: D (например s-a = .5*b+.5*c-.5*a, и три фактора .5отмены с помощью 8)
flawr
5
(a,b,c)=>такой же длины и стоит меньше байтов для вызова;)
ETHproductions
4
Но я люблю карри: D
flawr
8

MATL , 8 7 байт

tsGE-/p

Попробуйте онлайн!

объяснение

Давайте использовать вход [3 4 5]в качестве примера

t    % Take input implicitly. Duplicate
     % STACK: [3 4 5], [3 4 5]
s    % Sum of array
     % STACK: [3 4 5], 12
G    % Push input again
     % STACK: [3 4 5], 12, [3 4 5]
E    % Multiply by 2, element-wise
     % STACK: [3 4 5], 12, [6 8 10]
-    % Subtract, element-wise
     % STACK: [3 4 5], [6 4 2]
/    % Divide, element-wise
     % STACK: [0.5 1 2.5]
p    % Product of array. Implicitly display
     % STACK: 1.25
Луис Мендо
источник
8

R, 34 29 байт

x=scan();prod(x/(sum(x)-2*x))

Считывает ввод из stdin и сохраняет как R-вектор x. Затем используйте векторизацию R для формирования знаменателя.

Billywob
источник
7

Haskell, 36 байт

Это определяет функцию, #которая принимает три аргумента.

(a#b)c=a*b*c/(b+c-a)/(a+c-b)/(a+b-c)

Вы должны назвать это следующим образом: (3#4)5

Чуть дольше, но, возможно, более пригодный для игры в гольф:

p=product
f v=p v/p((sum v-).(2*)<$>v)
Flawr
источник
6

MATLAB, 64 38 25 байт

Это функция anyonmous, которая реализует формулу, как указано ниже:

@(v)prod(v./(sum(v)-2*v))

Предполагается, что входные данные являются списком из трех значений, например [3,4,5]. Этот пример используется в следующем объяснении:

             sum(v)        = 3+4+5 = 12
             sum(v)-2*v    = 12 - 2*[3,4,5] = 12 - [6,8,10] = [6,4,2]
         v./(sum(v)-2*v))  = [3,4,5] ./ [6,4,2] = [0.5,1,2.5]
    prod(v./(sum(v)-2*v))  = 0.5 * 1 * 2.5 = 1.25
Flawr
источник
6

Mathematica, 20 байтов

1##&@@(#/(Tr@#-2#))&

Принимает ввод как список из трех значений, который упоминается как #внутри функции. Tr@кратчайший способ суммировать список (чтобы получить 2s) и 1##&@@(...)умножает три фактора i/(2s-2i)на iв a, b, c.

Если входными данными являются целые или рациональные числа, вы получите точный результат.

Мартин Эндер
источник
5

OCaml, 51 байт

fun a b c->a*.b*.c/.(b+.c-.a)/.(a+.c-.b)/.(a+.b-.c)

Ууу, отдельные операторы для поплавков ...

shooqie
источник
5

Чудо , 48 байт

@@@prod[#0#1#2/1- +#1#0#2/1- +#2#0#1/1- +#2#1#0]

ПОКОЙСЯ С МИРОМ

Использование:

(((@@@prod[#0#1#2/1* * - +#1#0#2- +#2#0#1- +#2#1#0])3)4)5

объяснение

Вызовы функций в Wonder обходятся дороже по сравнению с инфиксными операторами на других языках. Из-за этого я содержал все термины в массиве и получал произведение результата вместо умножения каждого отдельного члена. Код будет эквивалентен чему-то вроде:

(a,b,c)=>product([a,b,c,1/(b+c-a),1/(a+c-b),1/(a+b-c)])
Mama Fun Roll
источник
1
Хм, а почему "RIP"?
Луис Мендо
Это намного дольше, чем необходимо / ожидалось
Mama Fun Roll
5

На самом деле , 10 8 байт

Этот ответ основан на превосходном ответе Дениса на желе . Предложения по игре в гольф приветствуются! Попробуйте онлайн!

;Σ♀/♂¬πì

Ungolfing

     Implicit input [a, b, c].
;    Duplicate [a, b, c].
Σ    sum() to get twice the semiperimeter, 2*s.
♀/   Vectorized divide 2*s by [a, b, c] to get [2*s/a, 2*s/b, 2*s/c].
♂¬   Vectorized subtract 2 to get [2*s/a-2, 2*s/b-2, 2*s/c-2].
π    Get the product of the above to get 8*(s/a-1)*(s/b-1)*(s/c-1).
     This is the same as 8(s-a)(s-b)(s-c)/abc.
ì    Invert to get the aspect ratio, abc/8(s-a)(s-b)(s-c).
     Implicit return.
Sherlock9
источник
5

Minecraft 1.8, 1607 байт + 85 блоков = 1692 байт

Предупреждение: не гольф. Golfed будет принимать до 1 / 3 меньше blytes.

Вот прокомментированный скриншот:

введите описание изображения здесь

  • Входы a , bи c, и выходfin

  • finи все остальные переменные в Minecraft являются целыми числами, поэтому стандартная точность Minecraft равна 0 десятичных знаков

  • Зеленая граница: блоки команд слева активируются после блоков справа, которые являются просто инициализацией переменных.

  • Рычаг (серо-коричневый прямоугольник внизу справа) является спусковым механизмом

  • Это занимает так много из-за того, как Minecraft обрабатывает переменные . Очень упрощенный обзор:

    • /scoreboard objectives add name dummy создает новую переменную с именем "name "

    • /scoreboard players set @p name numberустанавливает переменную nameв number. Число должно быть действительным числом, а не переменной.

    • /scoreboard players operation @p name += @p name2увеличивается nameна name2. name2должна быть переменной, а не числом.

      • -=, /=, *=, =И многое другое можно использовать вместо , +=чтобы декремент, умножить, разделить и т.д.
  • Я не собираюсь публиковать здесь все 43 команды. Это помогло бы в игре в гольф, но также помогло бы свести меня с ума.

  • Если бы использовались командные блоки 1.9, решение (как минимум) использовало бы на 42 блока меньше. Если бы использовались однобуквенные переменные, было бы сохранено почти 200 байтов.

RudolfJelin
источник
4

Java, 38 байт

(a,b,c)->a*b*c/(b+c-a)/(a-b+c)/(a+b-c)

Тестирование и разгул

public class Pcg101234 {
  interface F {
    double f(double a, double b, double c);
  }
  public static void main(String[] args) {
    F f = (a,b,c)->a*b*c/(b+c-a)/(a-b+c)/(a+b-c);

    System.out.println(f.f(1,1,1));
    System.out.println(f.f(3,4,5));
    System.out.println(f.f(42,42,3.14));
    System.out.println(f.f(14,6,12));
    System.out.println(f.f(6,12,14));
    System.out.println(f.f(0.5,0.6,0.7));
  }
}

Попробуй это!

Выход

1.0
1.25
6.947606226693615
1.575
1.575
1.09375
Оливье Грегуар
источник
Я чувствую, что (a,b,c)это что-то вроде обмана, потому что в нем нет информации о типах. IMO неявный лямбда-интерфейс (в вашем случае F) должен учитываться в общей байтовой сумме.
Ф. Джордж
4
@ mEQ5aNLrK3lqs3kfSa5HbvsTWe0nIu Лямбды настоятельно рекомендуются. Кроме того, большинство записей Java 8 работают без каких-либо замечаний. Если вы не согласны и считаете, что я обманул, я приглашаю вас официально спросить в мета, принята ли эта запись или нет. Между тем, я выравниваю на предыдущих ответах Java 8.
Оливье Грегуар
4

Медузы , 17 16 байт

Спасибо Zgarb за сохранение 1 байта.

p%/*-)/+i
    2%

Попробуйте онлайн!

объяснение

Это основано на той же формуле взаимности и ответ Денниса. .

В более традиционных функциональных обозначениях вышеприведенная программа выглядит следующим образом:

print(
  1 / fold(
    multiply,
    fold(add, i) / i - 2
  )
)

Где iнаходится список ввода. Обратите внимание, что fold(multiply, ...)просто вычисляется произведение и fold(add, ...)сумма, поэтому мы можем еще больше упростить это до:

print(1 / product(sum(i) / i - 2))

sum(i) / iОсуществляется с помощью крючка , )/+который определяет новую унарную функцию , чтобы сделать оба шага сразу.

Мартин Эндер
источник
Сохраните байт с помощью крючка .
Згарб
4

Dyalog APL , 10 9 байтов

×/⊢÷+/-+⍨

Это последовательность анонимных функций (поверх разветвления разветвления разветвления), означающая, что каждая подфункция применяется к аргументу внутри следующей структуры:

 ┌─┴─┐          
×/ ┌─┼───┐      
    ÷ ┌─┼──┐  
      +/ - +⍨

Попробуй APL онлайн!

×/ продукт

аргументы

÷ деленное на

+/ сумма аргументов

- минус

+⍨ аргументы удвоились (лит. добавил к себе)

Математическое обоснование.

Нгн побрил байт.

Адам
источник
Привет Адам, пожалуйста. напомни мне спросить тебя о ´⊢´ на следующей неделе, если я забуду это :-)
MBaas
Я не знаю, как ссылка «фон» предположительно относится к этому ответу, потому что я не вижу там никакого алгоритма. Кроме того, вы можете добавить информацию о порядке операций? Я пытался воспроизвести этот ответ на нескольких разных языках с различным порядком операций, но я всегда получаю ответ, отличный от ответа на вопрос.
кошка
@cat Ну, это не было предназначено, чтобы дать алгоритм, только чтобы объяснить, каково соотношение сторон, так как в Википедии нет такой страницы. APL справа налево, что означает, что каждая функция принимает в качестве аргумента все, что находится справа. Поэтому его можно прочитать слева направо, как в пояснении.
Адам
3

постоянный ток, 49 байт

5k?dsa?dsb?dsc++2/sslalblc**lsla-lslb-lslc-8***/p

Прямая реализация приведенной формулы. Запрашивает три входа при вызове в трех отдельных строках и выводит значение с плавающей запятой с 5 цифрами после десятичной точки на следующую строку.

объяснение

5k                                                # Set the output precision to 5 digits after the decimal
  ?dsa                                            # Prompt for first input value on first line, duplicate it, and then store it in register `a`
      ?dsb                                        # Prompt for second input, duplicate it, and store it in register `b`
          ?dsc                                    # Prompt for third input, duplicate it, and store it in register `c`
              ++2/ss                              # Sum up the 3 values on the main stack, then divide sum by 2 and store the result in register `s`
                    lalblc**                      # Copy all three values from registers `a`,`b`,`c` onto the main stack, find their product, and push result to top of main stack
                            lsla-                 # Copy value from register `s` onto main stack, subtract register `a`'s value from it, and push result to main stack
                                 lslb-            # Copy value from register `s` onto main stack, subtract register `b`'s value from it, and push result to main stack
                                      lslc-       # Copy value from register `s` onto main stack, subtract register `c`'s value from it, and push result to main stack
                                           8***   # Find the product of the top three values and 8 and then push the result to main stack
                                               /p # Divide the second to top value (a*b*c) by the top of stack value (8*(s-a)*(s-b)*(s-c)), push the result to the main stack, and then output the result to STDOUT
Р. Кап
источник
3

TI-Basic, 11 байт

Ввод должен быть в виде списка, вроде {A B C}.

prod(Ans)/prod(sum(Ans)-2Ans

Может быть, этот визуальный поможет (помните, что 2s = a+b+c ):

      ABC ABC ABC прод (Ans)
---------------- = --------------------- = ----------- знак равно
8 (sa) (sb) (sc) (2s-2a) (2s-2b) (2s-2c) (a + b + c) (1-2 {a, b, c}) prod (сумма (Ans) -2Ans)
Timtech
источник
2

Perl 6 , 44 байта

->\a,\b,\c{a*b*c/(b+c -a)/(a+c -b)/(a+b -c)}
Брэд Гилберт b2gills
источник
2

Python, 55 байт

def f(x,y,z):s=x+y+z;return 1/((s/x-2)*(s/y-2)*(s/z-2))

Кредит Деннису . Я просто портировал. В Python очень забытый язык.

Эрик Аутгольфер
источник
2

Далее 83 байта

Предполагается, что параметры с плавающей запятой начинаются со стека с плавающей запятой. Оставляет результат в стеке с плавающей запятой. Использование стека для параметров / возврата является стандартом для Forth.

: p 3 fpick ;
: T p p p ;
: f 0 s>f T f- f+ f- T f+ f- f* T f- f- f* 1/f f* f* f* ;

Попробуйте онлайн - содержит все контрольные примеры

Использует формулу a*b*c * 1/ ( -(a+b-c) * -(b+c-a) * (a+c-b) ). Практически вся программа использует только стек с плавающей запятой. Исключением является 3в 3 fpick. Эта программа требует переводчика, который поддерживает fpick(Ideone работает, repl.it нет).

Пояснение: чуть меньше в гольф

\ 3 fpick takes the 3rd element (0-indexed) and pushes a copy
\ Used to copy parameters on the stack over another number 'x' ( a b c x -> a b c x a b c )
: f3p 3 fpick 3 fpick 3 fpick ;

: f                     \ define a function f
0 s>f f3p f- f+ f-      \ push a zero, copy params, compute 0-(a+b-c)
                        \ the zero allows me to copy (I need an 'x' to jump over)
f3p f+ f- f*            \ copy params and compute -(b+c-a), multiply by previous result
                        \ the negatives miraculously cancel
f3p f- f- f*            \ copy and compute (a+c-b), multiply by previous result
1/f f* f* f* ;          \ take the reciprocal and multiply by a*b*c
                        \ the result is left on the floating point stack
mbomb007
источник
2

ised : 19 байт

@*$1/@*{@+$1-2.*$1}

Назовите его как ised --l 'inputfile.txt' '@*$1/@*{@+$1-2.*$1}' где inputfile.txtможет быть файл с массивом, разделенным пробелом, или -для получения из pipe / stdin.

Версия Unicode (та же bytecount, но на 3 знака меньше):

Π$1/Π{Σ$1-2.*$1}

К сожалению, isedтратит много символов на синтаксис входного аргумента.

Орион
источник
2

VBA, 76

Function r(a,b,c)
s=(a+b+c)/2:r=(a*b*c)/(8*(s-a)*(s-b)*(s-c))
End Function

Позвонить с

? Г (3,4,5)

или в Excel с

= Г (5,12,13)

SeanC
источник
Вы бы сэкономили 6 байтов с помощью алгоритма @ SuperJedi224:Public Function r(a,b,c):r=a*b*c/(b+c-a)/(a-b+c)/(a+b-c):End Function
steenbergh
2

C #, 82 байта

void ar(double a,double b,double c)=>Console.Write(a*b*c/(b+c-a)/(a+c-b)/(a+b-c));

Использование:

ar(42, 42, 3.14);
WeskerTyrant
источник
2

к, 19 байт

{(*/x)%8*/-x-+/x%2}

Оценивает справа налево - разделить список x на 2, суммировать результат и вычесть его из исходного x. Откажитесь от ответа и получите произведение результата и 8. Результат - знаменатель, числитель - произведение списка.

Пол Керриган
источник
1

Луа, 45 байт

a,b,c=...print(a*b*c/(b+c-a)/(a+c-b)/(a+b-c))

Сильно основано на ответе JavaScript.

Я сделал
источник