Üçgen sayısını say


22

Pozitif tamsayıların bir listesi göz önüne alındığında, oluşturabilecekleri üçgen sayısını, yan uzunluklarının giriş listesinin üç ayrı girişi ile temsil edileceği şekilde bulun.

(İlham gelir CR .)

ayrıntılar

  • Eğer bir üçgen oluşturulabilir her üç yan uzunluklarının permütasyon a,b,c yerine sıkı üçgen eşitsizliği
    a+b>c.
    (Bu, a+b>c , a+c>b ve b+c>a hepsinin tutması gerektiği anlamına gelir .)
  • Üç yan uzunluk a,b,c listedeki farklı konumlarda görünmelidir, ancak mutlaka çift olarak ayrı olması gerekmez.
  • Giriş listesindeki üç sayının sırası önemli değildir. Bir liste ave üç sayının a[i], a[j], a[k]( i,j,kçift ​​olarak farklı olduğu yerlerde ) (a[i],a[j],a[k]), (a[i],a[k],a[j]), (a[j], a[i], a[k])dikkate alınması durumunda, vb. Hepsi aynı üçgen olarak kabul edilir .
  • Giriş listesinin en az 3 giriş içerdiği varsayılabilir.
  • Giriş listesinin artan düzende sıralandığını varsayabilirsiniz.

Örnekler

Küçük bir test programı burada çevrimiçi olarak bulunabilir !

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

Bunun girişi [1,2,3,...,n-1,n]için A002623 .

[1,1,...,1](Uzunluk n) girişi için bu A000292'dir .

İlk nFibonacci sayılarının girişi için ( A000045 ) bu A000004'tür .


4
Farklı bir üçgen olarak sayılan şeylerle ilgili sorunun daha net olabileceğini düşünüyorum. Gönderen A000292 bağlantısını, bunu almak [1,1,1,1]hepsi 4 "farklı" üçgenler verir [1,1,1], herhangi üç 1'lerini kullanılarak seçilecek? Fakat, 24 değil çünkü üç 1 sırasız seçildi, yani sıralı bir listeden ziyade üç endeksin alt kümesi mi?
xnor

2
@xnor Bu konuya dikkat çekti, hepsi doğru görünüyor - Ben sadece ayrıntılara bir nokta ekledim. Umarım bu şimdi daha açık hale getirir.
kusur

Yanıtlar:


10

R , 62 52 40 34 bayt

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

Çevrimiçi deneyin!

Luis Mendo Limanı'nın Octave çözümü

Çünkü a<=b<=c, üçgen koşulu eşdeğerdir a+b-c>0. a+b-cÖz matris ürün tarafından yakalanır [1,1,-1] * X, Xgirdi dizisinin 3-kombinasyonlarıdır.

Yorumlarda 3 farklı kişi tarafından yapılan iyileştirmeler için birçok öneri vardı:

R , 40 bayt

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

Çevrimiçi deneyin!



3
x[3]<x[1]+x[2]eşittir 2*x[3]<sum(x): 51 bayt
Robin Ryder

4
Aslında, bu 45 baytı yapın . Birden fazla yorum için üzgünüm!
Robin Ryder

1
@RobinRyder Bu [takma ad kaygandır, yaklaşımı gerçekten temizler.
CriminallyVulgar


9

Stax , 8 7 bayt

-1 için özyinelemeye teşekkürler !

é═rê÷┐↨

Koşun ve staxlang.xyz de hata ayıklayın!

Ambalajsız (8 bayt) ve açıklama:

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

Bu temiz bir numara. Her zaman 0 veya 1 ile sonuçlanacak bir dizi talimatınız varsa ve programınızın sonunda gerçek sonuç veren bir diziden öğeleri saymanız gerekiyorsa, F..+bayttan kısadır {..f%.

İlk listenin artan olarak sıralandığını varsayar. Bu varsayım olmadan, o8 bayt için başında bir sopa .


1
r3SFE+<+7'ye paketlenir. Filtre sonuçlarını eklemek için bir foreach döngüsü kullanır. Ekleme, yalnızca tek bir öğe olduğunda işlem yapılmayan işlemlerden biridir.
özyinelemeli

6

Haskell , 49 bayt

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

Çevrimiçi deneyin!

Ardışık olarak l(ters) tüm alt gruplarını oluşturur ve uzunluğu -3 olanların üçgen oluşturduğunu kontrol eder.

50 bayt

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

Çevrimiçi deneyin!

Aynı fikir, mapMher değeri lkendi içinde (dahil) veya 0(hariç) ile eşleyerek alt dizileri oluşturmak .

50 bayt

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

Çevrimiçi deneyin!

Her bölüm noktasını orta öğeyi almaya çalışır b.

51 bayt

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

Çevrimiçi deneyin!

İşlev q=scanr(:)[], son eklerin listesini oluşturur. Eşit elemanların doğru sayıda dahil edilmesini dikkate almak zorunda kalmaktan büyük sıkıntı geliyor.

52 bayt

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

Çevrimiçi deneyin!

Yardımcı fonksiyon q=scanr(:)[] , son eklerin listesini oluşturur.

57 bayt

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

Çevrimiçi deneyin!


4

Brachylog , 11 bayt

{⊇Ṫ.k+>~t}ᶜ

Çevrimiçi deneyin!

Eski çözümümdeki sıralanmış girişten yararlanmayı unutmuş olabilirim:

Brachylog , 18 17 15 bayt

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

Çevrimiçi deneyin!

{            }ᶜ    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 bayt

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

Çevrimiçi deneyin!

açıklama

Bu bir Whatever kodu, yani lambda işlevleri için kısa bir gösterim (sadece çok basit durumlarda işe yarar). Her *biri bir argüman için bir yer tutucudur. Böylece uzunlukların listesini alırız (ilk sırada görünür *), 3 öğenin tüm kombinasyonlarını yaparlar (her zaman orijinal listedekiyle aynı sırada çıkarlar, böylece kombinasyonlar da sıralanır), listeyi düzleştirir, ve sonra 3'e 3'lük listeyi alın ve filter ( grep) yalnızca tatmin edici *+*>*olan üçüzleri , yani ilk iki argümanın toplamının üçte birinden daha büyük olduğunu söyleyin. Bu tüm üçüzleri verir ve nihayet sayısal bağlamı a ile zorlayarak onları sayarız +.

(Tabii ki, sadece "en küçük iki toplam> en büyüğü" durumunda test etmemiz gerekir. daha fazla bakmak gerekiyor.)


4

Retina , 55 bayt

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

Çevrimiçi deneyin! Link, test durumlarını içerir ancak 5. durumdaki değerler bugün bitmesine izin vermek için azaltılmıştır. Sıralanmış girişi varsayar. Açıklama: Regex'ler birden fazla şeyi eşleştirmekten hoşlanmıyor. Normal bir regex, bir üçgenin en kısa ayağı olabilecek tüm değerleri bulabilir. Retina'nın vseçeneği burada bir bakıştan kaçınmaktan başka işe yaramıyor. Ancak Retina'nın wseçeneği, aynı anda hem en kısa hem de en uzun bacağını bulabildiğinden biraz daha faydalıdır. Bu zorluk için bu yeterli değil, çünkü birçok orta bacak olabilir.

\d+
*

Girişi unary'ye dönüştürün.

L$`_+

Her giriş numarası için ...

$<'

... bu numaradan başlamak üzere kesilen orijinal dizinin oluşturduğu bir çizgi oluşturun. $'normal olarak maçtan sonraki dize anlamına gelir, ancak <onu önceki bayttan sonraki dize olarak değiştirerek 2 baytlık boşa harcamayı önler $&. Bu nedenle, her satır bu numarayı en kısa ayak olarak kullanan tüm olası çözümleri temsil eder.

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

Bu çizgilerin her biri için mümkün olan tüm orta ve en uzun bacakları bulun, ancak farkın ilk bacağından daha az olmasını sağlayın. _Eşleşen her bacak kombinasyonu için bir çıktı .

_

Bulunan toplam üçgen sayısını sayın.


3

Python 3 , 73 bayt

lambda l:sum(a+b>c for a,b,c in combinations(l,3))
from itertools import*

Çevrimiçi deneyin!

Bu benim aklıma gelen ilk saf, kaba kuvvet yaklaşımı. Farklı bir yaklaşım kullanarak daha kısa bir çözüm bulursam yazıyı güncelleyeceğim. Giriş sıralandığından beri(bir,b,c) Ayrıca artan düzende olduğundan, yalnızca kontrol edilip edilmediğini kontrol etmek yeterlidir. bir+b>c tutar.



3

05AB1E , 12 10 9 bayt

İlk kez 05AB1E kullanıyorum! -1 için [Grimy] 'e teşekkürler!

3.Æʒ`α›}g

Çevrimiçi deneyin! veya test takımı

Stax cevabımın doğrudan portu. Üç girişin tüm kombinasyonlarını alın ve üçgen oluşturabilecek olanları sayın. Beni gerçekten etkileyen kısmı sayıyor. Orada bir sürü bayt harcıyorum. Orada çaylak hatası yapılması gerekiyor.

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
Eminim Grimy daha kısa bir şey bulur, çünkü genellikle cevaplarımı verir. ;) Fakat cevabınız aklımdaki ile oldukça benzer görünüyor. Tek fark, ìfiltrenin içindeki Š(üçlü değiştirme) yerine filtreden önce kullandığım (her birini tersine çevirdiğim) . Alternatif olarak, ε...}Oyerine de kullanabilirsiniz ʒ...}g, ancak bayt sayısı aynı kalır. Not: 10 ve TIO bayt sayınız doğru, ancak gerçek cevabınız hala ykaldırılabilecek gereksiz bir açıklığa sahip. :) Güzel ilk cevap olsa da, benden +1.
Kevin Cruijssen

@KevinCruijssen'i hayal kırıklığına uğrattığım için üzgünüm, tek sahip olduğum şey 3.ÆʒRÆd_}gaynı bayt.
Grimmy,

2
@KevinCruijssen Oh sanırım 3.Æʒ`α›}g9
yaşında

@ Grimy Haha, bunu biliyordu. xD Gördüğüm gibi şimdi oldukça yalındır golf .. Ama ilk yorumumda bahsettiğim gibi, genellikle bu tür golflerle (ya da genel olarak golflerle ...) gelmekte daha iyi olursunuz. ; p
Kevin Cruijssen



2

Zsh , 66 bayt

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

Çevrimiçi deneyin!

Nispeten basit, sıralanmış giriş yararlanarak, ve artan for(artış başına bir kez olur başlığının üst döngü).

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 bayt

TaylorScott sayesinde -26 bayt

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

Giriş, A:Aaktif sayfa aralığında . Çıktı hemen pencereye.

Bu, 20 hücrenin yüksekliğinde (yaklaşık 2 60 kombinasyon olan) bir sütundaki her hücrenin her kombinasyonuna baktığından , bu kod hızlı değildir. Bunu yapabiliriz çok daha hızlı ancak bayt pahasına.


Sen bırak ()içinde, alt açıklamada uzay Debug.? rve bırak Next:Next:Nextiçin Next k,j,i. Bunun dışında - hala hala 2 ** 60 kombinasyon yapıyor ama işe yarıyor
Taylor Scott

Oh ve hey, if çizgisini değiştirerek biraz daha düşebilirsinizr=r-(a+b>c)*(b+c>a)*(c+a>b)
Taylor Scott

1

Kömür , 17 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Sıralanmış girişi varsayar. Açıklama:

   θ                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

Pyth , 14 bayt

*1sm>sPded.cQ3

Çevrimiçi deneyin!

          .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

Alternatif (ayrıca 14 bayt):

lfTm>sPded.cQ3

1

Perl 5 ( -p), 55 52 bayt

regex backtracking işlevini kullanarak, @Cows quack özelliği sayesinde başarısızlık ve geri izleme ^yerine kullanarak -3 bayt (?!).

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

veya

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

TIO


Can (?!)olmak ^?
Kritixi Lithos

teşekkürler / başarısızlık / geri dönüş iyi
Nahuel Fouilleul 11

1

Jöle , 9 bayt

œc3+>ƭ/€S

Çevrimiçi deneyin!

Sıralı bir tamsayı listesini argüman olarak alan ve üçgen sayısını döndüren bir tek renkli bağlantı.

açıklama

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

Alternatif 9'lar:

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


0

Bash , 123 bayt

for a;do for((i=2;i<=$#;i++)){ b=${!i};for((j=$[i+1];j<=$#;j++)){ c=${!j};T=$[T+(a<b+c&b<a+c&c<a+b)];};};shift;done;echo $T

Çevrimiçi deneyin!

Eğlenceli bir tane.


0

SNOBOL4 (CSNOBOL4) , 181 bayt

	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

Çevrimiçi deneyin!

Kaba kuvvet O(n3)algoritması. Girdiyi yeni satır ayrılmış liste olarak alır ve üçgen sayısını veya için boş bir satırı çıkarır 0. SNOBOL boş dizgeyi 0sayısal hesaplamalar için değerlendirdiği için buna izin verilir .


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.