นับจำนวนสามเหลี่ยม


22

ให้รายการของจำนวนเต็มบวกหาจำนวนของสามเหลี่ยมที่เราสามารถสร้างขึ้นเพื่อให้ความยาวด้านของพวกมันถูกแสดงด้วยสามรายการที่แตกต่างของรายการอินพุต

(แรงบันดาลใจมาจากCR )

รายละเอียด

  • สามเหลี่ยมสามารถเกิดขึ้นถ้าทุกพีชคณิตในสามของความยาวด้านตอบสนองความเข้มงวดความไม่เท่าเทียมกันสามเหลี่ยม(ซึ่งหมายถึง ,และต้องถือไว้ทั้งหมด)a,b,c+ B > C
    a+b>c.
    a+b>ca+c>bb+c>a
  • ความยาวทั้งสามด้านต้องปรากฏในตำแหน่งที่แตกต่างกันในรายการ แต่ไม่จำเป็นต้องแยกกันเป็นสองเท่าa,b,
  • ลำดับของตัวเลขสามตัวในรายการอินพุตไม่สำคัญ หากเราพิจารณารายการ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ตัวเลข Fibonacci ( A000045 ) นี่คือA000004


4
ฉันคิดว่าความท้าทายอาจชัดเจนกว่าว่าอะไรนับว่าเป็นรูปสามเหลี่ยมที่แตกต่างกัน จากลิงก์A000292ฉันสามารถ[1,1,1,1]อนุญาตให้ใช้รูปสามเหลี่ยมสามแบบ "ที่แตกต่างกัน" ทั้งหมด[1,1,1]เพื่อเลือกโดยใช้สามใน 1 ใดก็ได้ แต่ไม่ใช่ 24 เพราะเลือก 1 อันที่ไม่มีการเรียงลำดับนั่นคือชุดย่อยของสามดัชนีแทนที่จะเป็นรายการที่เรียงลำดับ?
xnor

2
@ xnor ที่ต้องการชี้ให้เห็นว่าทุกอย่างถูกต้อง - ฉันเพิ่งเพิ่มจุดในรายละเอียด ฉันหวังว่าจะทำให้ชัดเจนยิ่งขึ้นในขณะนี้
ข้อบกพร่อง

คำตอบ:


10

R , 62 52 40 34 ไบต์

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

ลองออนไลน์!

วิธีการแก้ปัญหาระดับแปดเสียงของ Port of Luis Mendo

เนื่องจากสภาพสามเหลี่ยมเทียบเท่ากับa<=b<=c ถูกจับชัดถ้อยชัดคำโดยผลิตภัณฑ์แมทริกซ์ซึ่งเป็นชุดที่ 3 ของอาร์เรย์การป้อนข้อมูลa+b-c>0a+b-c[1,1,-1] * XX

มีคำแนะนำมากมายสำหรับการปรับปรุงที่ทำโดยคน 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 ไบต์
Robin Ryder

4
ที่จริงให้ที่45 ไบต์ ขออภัยสำหรับความคิดเห็นหลาย!
Robin Ryder

1
@RobinRyder [นามแฝงนั้นเนียนจริงๆทำความสะอาดวิธีการ
อาชญากรคน


9

Stax , 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 loop เพื่อเพิ่มผลการกรอง การเพิ่มเป็นหนึ่งในการดำเนินการที่ไม่ต้องเลือกเมื่อมีเพียงองค์ประกอบเดียวเท่านั้น
เรียกซ้ำ

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]

ลองออนไลน์!

ฟังก์ชั่นตัวช่วยq=scanr(:)[]สร้างรายการของคำต่อท้าย

57 ไบต์

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

ลองออนไลน์!


4

Brachylogขนาด 11 ไบต์

{⊇Ṫ.k+>~t}ᶜ

ลองออนไลน์!

ฉันอาจลืมใช้ประโยชน์จากอินพุตที่เรียงลำดับในโซลูชันเก่าของฉัน:

Brachylog , 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-by-3 และตัวกรอง ( grep) เฉพาะสามคู่ที่ตอบสนอง*+*>*นั่นคือผลรวมของสองข้อโต้แย้งแรกมีค่ามากกว่าอันดับสาม +ที่ช่วยให้แฝดทั้งหมดและในที่สุดเราก็นับพวกเขาด้วยการบังคับให้บริบทที่เป็นตัวเลขด้วย

(แน่นอนว่าเราจำเป็นต้องทดสอบเฉพาะในกรณีของ "ผลรวมของสองที่เล็กกว่า> ที่ใหญ่ที่สุด" ถ้านี่ถืออีกอันหนึ่งถือเล็กน้อยถ้าไม่เช่นนั้น triplet จะไม่แสดงความยาวสามเหลี่ยมที่ถูกต้องและเราไม่ ต้องดูเพิ่มเติม)


4

เรติน่า , 55 ไบต์

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

ลองออนไลน์! ลิงก์มีกรณีทดสอบ แต่ด้วยค่าในกรณีที่ 5 ลดลงเพื่อให้เสร็จสมบูรณ์ในวันนี้ ถือว่าอินพุตเรียงลำดับ คำอธิบาย: Regexes ไม่ชอบจับคู่มากกว่าหนึ่งสิ่ง regex ปกติจะสามารถหาค่าทั้งหมดที่อาจเป็นขาสั้นที่สุดของรูปสามเหลี่ยม vตัวเลือกของ Retina ไม่ได้ช่วยอะไรที่นี่ยกเว้นการหลีกเลี่ยง lookahead อย่างไรก็ตามwตัวเลือกของ Retina มีประโยชน์มากกว่าเล็กน้อยเนื่องจากสามารถหาทั้งขาที่สั้นและยาวที่สุดในเวลาเดียวกัน ยังไม่เพียงพอสำหรับความท้าทายนี้เนื่องจากอาจมีหลายขากลาง

\d+
*

แปลงอินพุตเป็น unary

L$`_+

สำหรับแต่ละหมายเลขอินพุท ...

$<'

... สร้างบรรทัดที่อาร์เรย์ดั้งเดิมถูกตัดทอนเพื่อเริ่มต้นที่หมายเลขนั้น $'ปกติหมายถึงสตริงหลังจากที่การแข่งขัน แต่<ปรับเปลี่ยนมันจะหมายถึงสตริงหลังจากที่คั่นก่อนหน้านี้หลีกเลี่ยงการสูญเสีย 2 $&ไบต์บน แต่ละบรรทัดจึงแสดงวิธีแก้ปัญหาที่เป็นไปได้ทั้งหมดโดยใช้หมายเลขนั้นเป็นขาที่สั้นที่สุด

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

สำหรับแต่ละบรรทัดเหล่านั้นค้นหาขากลางและยาวที่สุดเท่าที่จะเป็นไปได้ทั้งหมด แต่ให้แน่ใจว่าความแตกต่างนั้นน้อยกว่าขาแรก เอาท์พุต a _สำหรับการรวมกันของขาแต่ละอัน

_

นับจำนวนสามเหลี่ยมทั้งหมดที่พบ




3

05AB1E , 12 10 9 ไบต์

ครั้งแรกของฉันที่ใช้ 05AB1E! ขอบคุณ [Grimy] สำหรับ -1!

3.Æʒ`α›}g

ลองออนไลน์! หรือชุดทดสอบ

พอร์ตโดยตรงของคำตอบ Stax ของฉัน รับการรวมกันทั้งหมดของสามรายการและนับรวมที่อาจเป็นรูปสามเหลี่ยม มันเป็นส่วนที่นับที่ทำให้ฉันได้จริงๆ ฉันใช้ไบต์ที่นั่น ถูกผูกไว้กับความผิดพลาดมือใหม่มี

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
Kevin Cruijssen



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 แต่ใช้ได้
Taylor Scott

โอ้และเฮ้คุณสามารถเลื่อนออกได้อีกโดยแทนที่ if line ด้วยr=r-(a+b>c)*(b+c>a)*(c+a>b)
Taylor Scott

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

Pyth , 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 ไบต์ขอบคุณ @ Quack quack ใช้^แทน(?!)การล้มเหลวและย้อนกลับ

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

หรือ

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

TIO


สามารถ(?!)เป็น^?
Kritixi Lithos

ขอบคุณมันล้มเหลว / ย้อนรอยได้ดี
Nahuel Fouilleul

1

เยลลี่ขนาด 9 ไบต์

œc3+>ƭ/€S

ลองออนไลน์!

ลิงก์ monadic ที่ใช้รายการเรียงลำดับจำนวนเต็มเป็นอาร์กิวเมนต์และส่งคืนจำนวนสามเหลี่ยม

คำอธิบาย

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

ทางเลือก 9s:

œ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

ลองออนไลน์!

Brute force O(n3)อัลกอริทึม 0จะเข้าเป็นบรรทัดใหม่รายการแยกและผลจำนวนรูปสามเหลี่ยมหรือบรรทัดว่างสำหรับ สิ่งนี้อาจใช้ได้เนื่องจาก SNOBOL ใช้สตริงที่ว่างเปล่า0สำหรับการคำนวณเชิงตัวเลข


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.