计算三角形数量


22

给定一个正整数列表,找到我们可以形成的三角形数量,以使三角形的边长由输入列表的三个不同条目表示。

(灵感来自CR。)

细节

  • 如果三个边长a b c的所有排列都满足严格的三角形不等式a + b > c 则可以形成三角形(这意味着a + b > c,和必须全部成立。)a,b,c
    a+b>c.
    a+b>ca+c>bb+c>a
  • 三个边长必须出现在列表中的不同位置,但不一定必须成对地分开。a,b,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](length n)为A000292

对于第一个n斐波那契数字(A000045)的输入,这是A000004


4
我认为关于什么是一个明显的三角形,挑战可能会更加清楚。从A000292链接中,我认为[1,1,1,1]可以[1,1,1]使用1中的任意三个来选择4个“不同”的三角形,全部?但是,它不是24,因为三个1的选择是无序的,即它是三个索引的子集而不是有序列表吗?
xnor

2
@xnor Thatnks指出了这一点,这一切似乎都是正确的-我只是在细节中添加了一点。我希望现在可以使情况更清楚。
flawr

Answers:


10

R62 52 40 34字节

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

在线尝试!

路易斯·门多港口的Octave解决方案

由于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个字节
Robin Ryder

4
实际上,使该45个字节。对不起,有多个评论!
罗宾·赖德

1
@RobinRyder该[别名很漂亮,确实可以清除该方法。
刑事


9

Stax8个 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,并且需要从数组中计算出在程序末尾产生真实结果的项目,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(reverse)的,并检查哪些长度为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}ᶜ

在线尝试!

我可能已经忘记了在旧解决方案中利用排序输入的优势:

Brachylog18 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(*+*>*)

在线尝试!

说明

它是任何代码,即lambda函数的简洁表示法(仅在非常简单的情况下有效)。每个*都是一个参数的占位符。因此,我们获取一个长度列表(出现在第一个列表中*),使3个元素的所有组合(它们总是以与原始列表相同的顺序出现,这意味着这些组合也被排序了),展平该列表,然后将列表grep三乘三,然后仅过滤()满足的三元组*+*>*,即前两个自变量的总和大于第三个自变量。这样就给出了所有的三元组,最后我们通过使用+

(当然,我们只需要针对“两个较小的和>最大的和”的情况进行测试。如果成立,则另一个保持不变,如果不成立,则三元组不表示正确的三角形长度,我们不需要进一步查看。)


4

视网膜,55字节

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

在线尝试!链接包括测试用例,但第5个用例中的值已减少,可以立即完成。假定排序的输入。说明:正则表达式并不太喜欢匹配多个对象。正常的正则表达式将能够找到所有可能是三角形最短边的值。视网膜的v选项在这里无济于事,除非避免先行。但是,Retina的w选项稍有帮助,因为它可以同时找到最短和最长的腿。但是,这还不足以应对这一挑战,因为可能会有多个中腿。

\d+
*

将输入转换为一元。

L$`_+

对于每个输入数字...

$<'

...创建一行原始数组,该数组从该数字开始被截断。$'通常表示匹配后的字符串,但将其<修改为表示上一个分隔符之后的字符串,避免在上浪费2个字节$&。因此,每行代表使用该数字作为最短支路的所有潜在解决方案。

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

对于每条线,找到所有可能的中腿和最长腿,但要确保差异小于第一条腿。_为每个匹配的腿组合输出a 。

_

计算找到的三角形总数。


3

Python 3 3,73个字节

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

在线尝试!

这是我想到的第一个幼稚,蛮力的方法。如果我发现使用其他方法的更短解决方案,我将更新该帖子。请注意,由于输入已排序,因此元组一种bC 也按升序排列,因此仅检查是否 一种+b>C 持有。



3

05AB1E12 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。
凯文·克鲁伊森

很抱歉让@KevinCruijssen失望,我所拥有的是3.ÆʒRÆd_}g,这是相同的字节数。
肮脏的

2
@KevinCruijssen哦,其实我的猜测3.Æʒ`α›}g是9
Grimmy

@肮脏的哈哈,知道了。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 单元格高的列中每个单元格的每个组合(将近2 60个组合),因此此代码不是很快。你可以把它快,但在字节的费用。


您可以删除()在次声明,空间Debug.? r和可下降Next:Next:NextNext k,j,i。除此之外-以及它仍然在做2点** 60点的组合,但它的工作原理
泰勒·斯科特

哦,嘿,您可以通过将if行替换为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

果冻,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)

替代9s:

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


0

重击,123字节

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

在线尝试!

一个有趣的。


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数值计算。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.