给定一个正整数的列表,找出我们可以形成的三角形的数目,这样它们的边长由输入列表的三个不同的条目表示。
(灵感来自CR。)
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])
等都被认为是相同的三角形。在在网上试试!上可以找到一个小的测试程序
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]
(length n
)的输入,这是A000292。
发布于 2019-08-27 19:45:27
([]%)
[c,b,a]%l|a+b>c=1
p%(h:l)=(h:p)%l+p%l
_%_=0
递归生成l
的所有子序列(反向),并检查哪个长度-3 1构成三角形.
f l=sum[1|[a,b,c]<-filter(>0)<A8gt;mapM(:[0])l,a+b>c]
同样的想法,使用mapM
生成子序列,方法是将l
中的每个值映射到自身(包括)或0
(排除)。
([]%)
p%(b:t)=sum[1|c<-t,a<-p,a+b>c]+(b:p)%t
_%_=0
尝试每个分区点以接受中间元素b
。
f(a:t)=f t+sum[1|b:r<-scanr(:)[]t,c<-r,a+b>c]
f _=0
函数q=scanr(:)[]
生成后缀列表。很多麻烦来自于需要考虑是否包含相同的元素,正确的次数。
q=scanr(:)[]
f l=sum[1|a:r<-q l,b:s<-q r,c<-s,a+b>c]
助手函数q=scanr(:)[]
生成后缀列表。
import Data.List
f l=sum[1|[a,b,c]<-subsequences l,a+b>c]
发布于 2019-08-27 20:38:59
+*.combinations(3).flat.grep(*+*>*)
这是一个任何代码,也就是lambda函数的简明表示法(只在非常简单的情况下起作用)。每个*
都是一个参数的占位符。因此,我们取长度列表(出现在第一个*
中),使所有三个元素的组合(它们总是以与原始列表相同的顺序出现,这意味着组合也是排序的),平平列表,然后取列表3乘3,然后筛选(grep
)只满足*+*>*
的三重奏,即前两个参数之和大于第三个参数。这就给出了所有的三胞胎,最后我们用一个+
强制数字上下文来计算它们。
(当然,我们只需要对“两个较小的和>最大和”的情况进行测试。如果这是成立的,另一个小保持,如果这不是,三重奏不表示正确的三角形长度,我们不需要进一步研究。)
https://codegolf.stackexchange.com/questions/190949
复制相似问题