Порахуйте кількість трикутників


22

Давши список натуральних чисел, знайдіть кількість трикутників, які ми можемо сформувати так, щоб їх бічні довжини були представлені трьома різними записами вхідного списку.

(Натхнення надходить від CR .)

Деталі

  • Трикутник можна утворити, якщо всі перестановки трьох бічних довжин задовольняють суворій нерівності трикутника(Це означає, що , і мають утримувати всі.)а,б,c
    а+б>c.
    а+б>cа+c>бб+c>а
  • Три сторони довжини повинні міститись у різних положеннях у списку, але не обов'язково повинні бути розрізненими попарно.а,б,c
  • Порядок трьох чисел у вхідному списку значення не має. Якщо ми розглянемо список aі три числа a[i], a[j], a[k](де i,j,kпопарно різні), то (a[i],a[j],a[k]), (a[i],a[k],a[j]), (a[j], a[i], a[k])і т. Д. Всі вважаються одним і тим же трикутником.
  • Можна вважати, що список вхідних даних містить щонайменше 3 записи.
  • Можна припустити, що вхідний список сортується у порядку зростання.

Приклади

Невелику програму тестування можна знайти тут на « Спробуйте онлайн»!

Input, Output:
[1,2,3]  0
[1,1,1]  1
[1,1,1,1] 4
[1,2,3,4] 1
[3,4,5,7] 3
[1,42,69,666,1000000] 0
[12,23,34,45,56,67,78,89] 34
[1,2,3,4,5,6,7,8,9,10] 50

Для [1,2,3,...,n-1,n]цього є A002623 .

Для вводу [1,1,...,1](довжини n) це A000292 .

Для введення перших nчисел Фібоначчі ( A000045 ) це A000004 .


4
Я думаю, що виклик міг би бути зрозумілішим щодо того, що вважається виразним трикутником. З посилання на A000292 , я вважаю, що це [1,1,1,1]дозволяє вибрати 4 "різні" трикутники, [1,1,1]використовуючи будь-які три з 1-х? Але це не 24, тому що три "1" обрані не упорядкованими, тобто це підмножина з трьох індексів, а не упорядкований список?
xnor

2
@xnor Thatnks за вказівку на це, що все здається правильним - я просто додав крапку в деталях. Я сподіваюся, що це стане зрозумілішим зараз.
недолік

Відповіді:


10

R , 62 52 40 34 байт

sum(c(1,1,-1)%*%combn(scan(),3)>0)

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

Рішення Октава Порта Луїса Мендо

Оскільки a<=b<=cумова трикутника еквівалентна a+b-c>0. a+b-cЛаконічно захоплений матриці продукту [1,1,-1] * X, де Xє 3-комбінації вхідного масиву.

У коментарях було багато пропозицій щодо покращень, внесених 3-ма різними людьми:

R , 40 байт

y=combn(scan(),3);sum(y[3,]<y[1,]+y[2,])

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



3
x[3]<x[1]+x[2]еквівалентно 2*x[3]<sum(x): 51 байт
Робін Райдер

4
Власне, зробіть це 45 байт . Вибачте за кілька коментарів!
Робін Райдер

1
@RobinRyder Цей [псевдонім стрункий , дійсно очищає підхід.
Кримінально-


9

Стакс , 8 7 байт

Завдяки рекурсивному для -1!

é═rê÷┐↨

Запустіть і налагоджуйте його на staxlang.xyz!

Розпаковано (8 байт) та пояснення:

r3SFE+<+
r           Reverse
 3S         All length-3 combinations
   F        For each combination:
    E         Explode: [5,4,3] -> 3 4 5, with 3 atop the stack
     +        Add the two shorter sides
      <       Long side is shorter? 0 or 1
       +      Add result to total

Це акуратний трюк. Якщо у вас є послідовність інструкцій, яка завжди призведе до 0 або 1, і вам потрібно буде порахувати елементи з масиву, що дає результат "truthy" в кінці програми, F..+байт коротший, ніж {..f%.

Припускає, що початковий список відсортований за зростанням. Без цього припущення, дотримуватися oна початку для 8 байт.


1
r3SFE+<+пакети до 7. Для додавання результатів фільтра використовується цикл foreach. Додавання - це одна з операцій, яка неоперативна, коли присутній лише один елемент.
рекурсивний

6

Haskell , 49 байт

([]%)
[c,b,a]%l|a+b>c=1
p%(h:l)=(h:p)%l+p%l
_%_=0

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

Рекурсивно генерує всі підрядки l(перевернуті) і перевіряє, які довжини-3 утворюють трикутники.

50 байт

f l=sum[1|[a,b,c]<-filter(>0)<$>mapM(:[0])l,a+b>c]

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

Та ж сама ідея, що генерує піддані mapM, шляхом відображення кожного значення lабо в себе (включати), або 0(виключати).

50 байт

([]%)
p%(b:t)=sum[1|c<-t,a<-p,a+b>c]+(b:p)%t
_%_=0

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

Спробуйте кожну точку розділу, щоб взяти середній елемент b.

51 байт

f(a:t)=f t+sum[1|b:r<-scanr(:)[]t,c<-r,a+b>c]
f _=0

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

Функція q=scanr(:)[]генерує список суфіксів. Багато клопоту виникає з необхідності врахувати правильне включення рівних елементів.

52 байти

q=scanr(:)[]
f l=sum[1|a:r<-q l,b:s<-q r,c<-s,a+b>c]

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

Функція helper q=scanr(:)[]формує список суфіксів.

57 байт

import Data.List
f l=sum[1|[a,b,c]<-subsequences l,a+b>c]

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


4

Брахілог , 11 байт

{⊇Ṫ.k+>~t}ᶜ

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

Можливо, я забув скористатися відсортованим входом у своєму старому рішенні:

Брахілог , 18 17 15 байт

{⊇Ṫ¬{p.k+≤~t}}ᶜ

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

{            }ᶜ    The output is the number of ways in which
 ⊇                 a sublist of the input can be selected
  Ṫ                with three elements
   ¬{       }      such that it is not possible to show that
     p             for some permutation of the sublist
       k+          the sum of the first two elements
         ≤         is less than or equal to
      .   ~t}      the third element.

4

Perl 6 , 35 байт

+*.combinations(3).flat.grep(*+*>*)

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

Пояснення

Це код, який би не був, тобто стислий позначення лямбда-функцій (який працює лише у дуже простих випадках). Кожен *є заповнювачем для одного аргументу. Отже, ми беремо список довжин (який з’являється спочатку *), робимо всі комбінації з 3-х елементів (вони завжди виходять у тому ж порядку, що і в початковому списку, так що це означає, що комбінації теж сортуються), сплющуємо список, а потім візьміть список 3 на 3 і відфільтруйте ( grep) лише ті трійки, які задовольняють *+*>*, тобто сума перших двох аргументів більша за третю. Це дає всі трійки, і ми, нарешті, підраховуємо їх примусовим числовим контекстом з a +.

(Звичайно, нам потрібно перевірити його лише на випадок "сума двох менших> найбільших". Якщо це справедливо, інша тривіально, якщо цього немає, триплет не позначає правильних трикутників і ми не потрібно дивитись далі.)


4

Сітківка , 55 байт

\d+
*
L$`_+
$<'
%L$w`(,_+)\b.*\1(_*)\b(?<=^_+\2,.*)
_
_

Спробуйте в Інтернеті! Посилання включає тестові випадки, але зі значеннями у 5-му випадку зменшено, щоб дати можливість закінчитися сьогодні. Передбачає відсортований вхід. Пояснення: Реджекси не дуже люблять збігати більше ніж одне. Звичайний регулярний вираз міг би знайти всі значення, які могли б бути найкоротшою ніжкою трикутника. vТут не допомагає варіант Retina , за винятком того, щоб уникнути пошуку. Однак wваріант Retina є дещо кориснішим, оскільки він зможе знайти як найкоротшу, так і найдовшу ногу одночасно. Це недостатньо для цього виклику, оскільки може бути кілька середніх ніг.

\d+
*

Перетворити вхід в одинаковий.

L$`_+

Для кожного номера введення ...

$<'

... створити рядок, який є початковим масивом, усіченим для початку з цього числа. $'зазвичай означає рядок після збігу, але <модифікує його, щоб означати рядок після попереднього роздільника, уникаючи витрачання 2 байтів на $&. Тому кожен рядок представляє всі потенційні рішення, використовуючи це число як найкоротшу ногу.

%L$w`(,_+)\b.*\1(_*)\b(?<=^_+\2,.*)
_

Для кожного з цих рядків знайдіть усі можливі середні та найдовші ноги, але переконайтесь, що різниця менша, ніж у першої ноги. Виведіть a _для кожної комбінації ніжок.

_

Порахуйте загальну кількість знайдених трикутників.




3

05AB1E , 12 10 9 байт

Я вперше використовую 05AB1E! Дякую [Гримі] за -1!

3.Æʒ`α›}g

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

Прямий порт моєї відповіді Стакса. Отримайте всі комбінації з трьох записів і порахуйте ті, які могли б утворити трикутники. Саме ця частина рахунку насправді отримала мене. Я витрачаю там багато байтів. Там має бути якась помилка новачка.

3.Æʒ`α›}g
3.Æ          List of length-3 combinations
   ʒ   }g    Count truthy results under operation:
    `          Push the two shorter sides, then the long one
     α         Absolute difference (negated subtraction in this case)
      ›        Remaining short side is longer?

2
Я впевнений, що Grimy придумає щось коротше, оскільки він зазвичай робить мої відповіді. ;) Але ваша відповідь виглядає досить схоже на те, що я мав на увазі. Різниця полягає лише в тому, що я використовував ì(перевертати кожен) перед фільтром замість Š(потрійний своп) всередині фільтра. Крім того, ви також можете використовувати ε...}Oзамість ʒ...}g, але кількість байтів залишається такою ж. PS: Ваш кількість байтів 10 і TIO правильні, але у вашої фактичної відповіді все ще є непотрібне явне, yяке можна видалити. :) Хоча приємна перша відповідь, тому +1 від мене.
Kevin Cruijssen

Вибачте, що розчарував @KevinCruijssen, все, що я маю 3.ÆʒRÆd_}g, це той самий облік.
Grimmy

2
@KevinCruijssen О, власне, я думаю, 3.Æʒ`α›}gце 9.
Grimmy

@Grimy Haha, знав це. xD Досить прямого гольфу тепер, коли я це бачу .. Але зазвичай вам краще придумати такі види гольфів (або гольфи взагалі ..), як я вже згадував у своєму першому коментарі. ; p
Кевін Круїссен



2

Zsh , 66 байт

for a;z=$y&&for b (${@:2+y++})for c (${@:3+z++})((t+=c<a+b))
<<<$t

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

Відносно просто, скориставшись відсортованим введенням та збільшенням у forзаголовку (приріст відбувається один раз у батьківському циклі).

for a;{
  z=$y
  for b (${@:2+y++});{   # subarray starting at element after $a
    for c (${@:3+z++})   # subarray starting at element after $b
      ((t+=c<a+b))
  }
}

2

Excel VBA, 171 164 152 байт

-26 байт завдяки TaylorScott

Sub z
t=[A:A]
u=UBound(t)
For i=1To u-2
For j=i+1To u-1
For k=j+1To u
a=t(i,1):b=t(j,1):c=t(k,1)
r=r-(a+b>c)*(b+c>a)*(c+a>b)
Next k,j,i
Debug.?r
End Sub

Введення знаходиться в діапазоні A:Aактивного аркуша. Вихід - до безпосереднього вікна.

Оскільки це враховує кожну комбінацію кожної комірки у стовпчику, яка становить 2 20 комірок (що майже 2 60 комбінацій), цей код ... не швидкий. Можна зробити це набагато швидше, але за рахунок байтів.


Ви можете опустити ()в підзаголовок, пробіл Debug.? rі можна Next:Next:Nextперейти до Next k,j,i. окрім цього - добре його все ще роблять 2 ** 60 комбінацій, але це працює
Тейлор Скотт

О, ага, ви можете вийти ще трохи, замінивши рядок if наr=r-(a+b>c)*(b+c>a)*(c+a>b)
Тейлор Скотт

1

Вугілля деревне , 17 байт

IΣ⭆θ⭆…θκ⭆…θμ›⁺νλι

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Передбачає відсортований вхід. Пояснення:

   θ                Input array
  ⭆                 Map over elements and join
      θ             Input array
     …              Truncated to length
       κ            Outer index
    ⭆               Map over elements and join
          θ         Input array
         …          Truncated to length
           μ        Inner index
        ⭆           Map over elements and join
              ν     Innermost value
             ⁺      Plus
               λ    Inner value
            ›       Is greater than
                ι   Outer value
 Σ                  Take the digital sum
I                   Cast to string for implicit print




1

Піт , 14 байт

*1sm>sPded.cQ3

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

          .cQ3  # All combinations of length 3 from Q (input), sorted in ascending order
   m            # map over that lambda d:
     sPd        #   sum(d[:-1])
    >   ed      #     > d[-1]
  s             # sum all of those (uses the fact that True = 1)
*1              # multiply by 1 so it doesn't output True if there's only one triangle

Альтернативно (також 14 байт):

lfTm>sPded.cQ3

1

Perl 5 ( -p), 55 52 байти

використовуючи зворотне відстеження regex, -3 байти завдяки красуню @Cows, використовуючи ^замість того, (?!)щоб вийти з ладу і відхилити.

$d='(\d++)';$_=/$d.* $d.* $d(?{$n++if$1+$2>$3})^/+$n

або

$_=/(\d++).* (\d++).* (\d++)(?{$n++if$1+$2>$3})^/+$n

ТІО


Може (?!)бути ^?
Kritixi Lithos

дякую, це не вдається / добре
відхилився

1

Желе , 9 байт

œc3+>ƭ/€S

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

Монадична посилання, яка бере в якості аргументу відсортований список цілих чисел і повертає кількість трикутників.

Пояснення

œc3       | Combinations of length 3
     ƭ/€  | Reduce each using each of the following in turn:
   +      | - Add
    >     | - Greater than
        S | Sum (counts the 1s)

Альтернатива 9-х років:

œc3Ṫ€<§ƊS
œc3Ṫ<SƊ€S



0

SNOBOL4 (CSNOBOL4) , 181 байт

	S =TABLE()
R	X =X + 1
	S<X> =INPUT	:S(R)
I	I =J =K =I + 1	LT(I,X)	:F(O)
J	J =K =J + 1	LT(J,X)	:F(I)
K	K =K + 1	LT(K,X - 1)	:F(J)
	T =T + 1 GT(S<I> + S<J>,S<K>)	:(K)
O	OUTPUT =T
END

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

Груба сила О(н3)алгоритм. Приймає введення у вигляді списку, розділеного новим рядком, і виводить кількість трикутників або порожній рядок для 0. Можливо, це можливо, оскільки SNOBOL обробляє порожній рядок як 0для числових обчислень.


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