我的尺寸是多少?


18

任务:给定一个三角形的面积,找到一个具有该面积的Heronian三角形。允许使用具有指定区域的任何Heronian三角形。

Heronian三角形是具有整数边和整数面积的三角形。根据Heron的公式,边长为三角形的三角形a,b,c具有面积

sqrt(s*(s-a)*(s-b)*(s-c))

哪里s=(a+b+c)/2是三角形周长的一半。这也可以写成

sqrt((a+b+c)*(-a+b+c)*(a-b+c)*(a+b-c)) / 4

如果不存在这样的三角形,则输出具有一致的假值。

输入:代表三角形面积的单个正整数。

输出:这样的三角形或错误值的任意三个边长。

例子:

Input -> Output
6 -> 3 4 5
24 -> 4 15 13
114 -> 37 20 19
7 -> error

适用标准漏洞

这是代码高尔夫,最短答案以字节为单位。


6
您可以在挑战中为Heronian三角形写一个相对简洁的定义吗?
Okx

1
@Okx:不清楚它是一个具有整数边和整数面积的三角形吗?
尼尔·

@Okx:就是这个主意。您需要做的就是为给定区域找到一个这样的示例(如果存在)。
尼尔·

在Wikipedia链接中:“一个Heronian三角形是一个边长和面积均为整数的三角形。”
尼尔·A,

5
您能否解释一下问题中有关定义的困惑?
尼尔·

Answers:


6

果冻17 16 字节

-1字节感谢外来专家Erik(使用quick ¥

SHð;_P
ṗ3Ç⁼¥Ðf²Ḣ

苍鹭公式的蛮力应用。

在线尝试!(在114个测试用例中达到了60秒超时。在本地花费3m 30秒-它确实检查了114 3 = 1,481,544个三元组)

怎么样?

真正的高尔夫解决方案-给定一个面积,a它会找到和之间的三个整数的所有元组(即使有重复的三角形且没有面积),获取其面积并过滤具有所需面积的对象(它甚至不会立即停止)找到一个,它将全部翻耕,然后弹出第一个结果)。如果不存在,则产量。1a0

SHð;_P - Link 1, get the square of the area of a triangle: list of sides
S      - sum the sides (get the perimeter)
 H     - halve
  ð    - dyadic chain separation (call that p)
    _  - subtraction (vectorises) =    [p-side1,  p-side2,  p-side3]
   ;   - concatenate              = [p, p-side1,  p-side2,  p-side3]
     P - product                  =  p*(p-side1)*(p-side2)*(p-side3)
                                  = the square of Heron's formula = area squared

ṗ3Ç⁼¥Ðf²Ḣ - Main link: number a (area)
ṗ3        - third Cartesian power (all triples of [1,area] : [[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,1],[2,1,2],[2,2,1],[2,2,2], ... ,[a,a,a]]
       ²  - square a
     Ðf   - filter keep if:
    ¥     -   last two links as a dyad:
  Ç       -     call last link (1) as a monad f(list of sides)
   ⁼      -     left (that result) equals right (square of a)?
        Ḣ - head - get the first one (an empty list yields 0, perfect for the falsey case)

我想有人会尝试蛮力的,太好了!
尼尔·

@NeilA。我想大多数高尔夫选手都将是挑战的野蛮力量-但有些选手可能会设法打高尔夫球,而效率却不如这低。
乔纳森·艾伦

您可以替换çÇ⁼¥并完全删除第二行。
暴民埃里克(Erik the Outgolfer)'17年

@EriktheOutgolfer哦,谢谢,我想知道该怎么做...
Jonathan Allan

5

的JavaScript(ES7),109个 102 100 98字节

返回3个整数或的数组false。就像果冻的答案一样,这是蛮力迫使苍鹭的公式。

A=>[...Array(A**3)].some((_,a)=>A*A/(r=[b=a/A%A|0,c=a/A/A|0,a%=A],p=a+b+c>>1)/(p-a)/(p-b)==p-c)&&r

测试用例


递归版本,83字节

返回3个整数的数组或引发递归错误。可悲的是,它仅适用于少量输入。

f=(A,n)=>A*A/(r=[a=n%A,b=n/A%A|0,c=n/A/A|0],p=a+b+c>>1)/(p-a)/(p-b)==p-c?r:f(A,-~n)

演示版


4

Haskell,69个字节

f a=take 1[t|t<-mapM(\_->[1..a])":-)",a*a==product[sum t/2-x|x<-0:t]]

在线尝试!

输出清单中的三个三角形边的单例[[3.0,4.0,5.0]]。不可能的输入会给[]。从技术False上讲,对于Haskell而言,它仅是Falsey,但是由于Haskell要求所有可能的输出都具有相同的类型,因此无法使用它。如果错误可以用作Falsey,[...]!!0则将节省3个字节take 1[..]

尝试所有t可能的边长的三倍,每边的长度从1到范围不等a。海伦公式是用来检查区域通过匹配的(s-0)(s-x)(s-y)(s-z)==a*a地方s=(x+y+z)/2sum t/2。乘积(s-0)(s-x)(s-y)(s-z)表示为a product,元素取自0:t,即三元组以及0。


+1代表笑脸,即使这有点像傻瓜
朱利安·沃尔夫

2

F#,170个 156 152字节

let f(a,b,c)=
 let s=(a+b+c)/2.0
 s*(s-a)*(s-b)*(s-c)
let g A=[for a in 1.0..A do for b in a..A do for c in b..A do yield a,b,c]|>List.find(f>>(=)(A*A))

在线尝试!

“无高尔夫球”

let calculateArea (a, b, c) =
    let s = (a+b+c)/2.0
    s*(s-a)*(s-b)*(s-c)

let getTriangle A =
    [  for a in 1.0..A do
       for b in a..A do
       for c in b..A do yield a,b,c
    ]
    |> List.find(calculateArea>>(=)(A * A))

如果没有找到结果,程序将出错。如果不希望这样做,我必须替换List.findList.filter(+2字节),如果找不到任何内容,则将生成一个空列表,或者替换为List.tryFind(+3字节),如果未找到三角形,则返回None。

我总是发现打高尔夫球的F#版本仍然合理清晰。


1
我不知道F#,但我想您可以省去System.Math.Sqrt并将结果值与进行比较A * A
肖恩

@Sean当然!感谢您的提示:)
布鲁纳

替换1.0..A [...] 1.0..A [...] 1.0..A1.0..A [...] a..A [..] b..A可以为您节省几个字节,并使您的速度有所提高(如果可行,我对F#的经验非常少)。
CAD97

@ CAD97确实如此!感谢您指出了这一点。
布鲁纳

2

Python 2中(PyPy) 131个 123 118字节

n=input()
t=n*3;r=i=c=0
while c<t:
 i+=1;a,b,c=i%t,i/t%t,i/t/t;s=a+b+c>>1
 if(s-a)*s*(s-b)*(s-c)==n**2:r=a,b,c
print r

在线尝试!

虽然这也适用于CPython,但PyPy的速度要快得多,并且能够在TIO的时间限制内计算出114个三角形。

我机器上的时间:

$ echo 114 | time pypy2 d.py
        0.55 real         0.52 user         0.02 sys
$ echo 114 | time python2 d.py
       52.46 real        51.76 user         0.27 sys

1

Pyth-23个字节

/mu*G-/sd2Hd/sd2^UQ3^Q2

哪个显示真实/虚假值,或者

fq^Q2u*G-/sT2HT/sT2^UQ3

它打印出所有可能的解决方案,并且对于大输入量来说非常慢。在开头加上“ h”,只打印一个。

说明:

fq^Q2u*G-/sT2HT/sT2^UQ3
                    UQ    # List of numbers from 0 to input-1
                   ^  3   # All triples of these numbers
f                         # Filter this by the following test (on variable T, based on Hero's formula)
     u*G-/sT2HT/sT2       # s*(s-a)*(s-b)*(s-c), where s is the sum of the triple over 2 (calclated as /sT2 )
 q^Q2                     # Test if equal to input ^2

尝试一下


1

Perl 6、54个字节

->\a{first {a*a==[*] .sum/2 «-«(0,|$_)},[X] ^a xx 3}

蛮力搜索所有可能的边小于a输入区域一。

  • ^a是从0到的数字范围a - 1
  • [X] ^a xx 3通过叉积减少该范围的三个副本,从而产生从(0, 0, 0)到的所有三胞胎(a - 1, a - 1, a - 1)
  • 我们使用Heron公式寻找first三元组,以使三角形的那些边相等。a

在提供给的代码块中first

  • $_是三胞胎。(x, y, z)在这里打电话。
  • (0,|$_)是相同的三元组,但带有0::(0, x, y, z)
  • .sum / 2是周长的一半(此量s在Heron公式的常用表达式中被命名)。
  • .sum / 2 «-« (0, |$_)是减法超级算子,s在左侧和(0, x, y, z)右侧,给出(s - 0, s - x, s - y, s - z)
  • [*] 然后乘以该四倍体,得到面积的平方。
  • a * a == 寻找等于给定面积平方的平方面积。

如果未找到三元组,Nil则返回(是false)。


1

Haskell,76个字节

f s=[[a,b,c]|a<-[1..s],b<-[1..a],c<-[1..b],a*a*c*c-(a*a+c*c-b*b)^2/4==4*s*s]

这将输出包含所有可能的整数大小的列表的列表,这些列表会通过蛮力生成正确的区域(如果没有,则输出空列表)。需要注意的是,由于中间的除法,它们将它们输出为两倍,但它们的小​​数部分始终为0。

如果您出于某种原因不能接受,

f s=[[a,b,c]|a<-[1..s],b<-[1..a],c<-[1..b],4*a*a*c*c-(a*a+c*c-b*b)^2==16*s*s]

这将以整数列表的形式输出答案,总共89 77个字节或额外的13 1个字节。(感谢尼尔)

如果您只需要将第一个元素放在!!0末尾,则在有编号适用的情况下只会给您第一个元素;如果没有3个字节,则只给您一个错误;而take 1在开始时会带上第一个元素而不会出错还有6个字节。

在线尝试!


如果要避免双打,是否可以只将方程式的每一边乘以4?
尼尔

0

TI-Basic,70岁 69字节

Prompt A
For(B,1,A
For(C,1,B
For(D,1,C
(B+C+D)/2
If A2=Ansprod(Ans-{B,C,D
Then
Disp B,C,D
Return
End
End
End
End
/

如果有三角形,则显示三个边的长度,如果没有,则显示语法错误(由于 /末尾)。

-1个字节,感谢肖恩对另一个答案的评论


0

Mathematica,77个字节

与mathematica的求解

s=(a+b+c)/2;d=Sqrt[s(s-a)(s-b)(s-c)];Solve[d==#&&0<a<b<c<#,{a,b,c},Integers]&

Mathematica,117个字节

蛮力

s=(a+b+c)/2;l="error";(For[a=1,a<#,a++,For[b=1,b<a,b++,For[c=1,c<b,c++,If[Sqrt[s(s-a)(s-b)(s-c)]==#,l={a,b,c}]]]];l)&

1
Mathematica没有内置功能?奇怪。
尼尔A.17年

@ovs也可以在其上保存一个字节Area@SSSTriangle[a,b,c]
numbermaniac

0

实际上,22个字节

;╗R3@∙⌠;Σ½;)♀-π*╜²=⌡░F

在线尝试!

说明:

;╗R3@∙⌠;Σ½;)♀-π*╜²=⌡░F  (implicit input: A)
;╗                      store a copy of A in register 0
  R                     range(1, A+1)
   3@∙                  ternary Cartesian product (all triples with values in [1, A])
      ⌠;Σ½;)♀-π*╜²=⌡░   filter: take triples where function returns truthy
       ;Σ½                make a copy of the triple, compute s = (a+b+c)/2
          ;)              make a copy of s, move it to the bottom of the stack
            ♀-            subtract each value in the triple from s
              π*          product of those values and s (s*(s-a)*(s-b)*(s-c))
                ╜²        A*A
                  =       compare equality (does area of triangle with given dimensions equal input?)
                     F  take first triple that satisfies the filter (or empty list if none)

0

Casio Basic,123字节

For 1⇒a To n
For 1⇒b To n
For 1⇒c To n
If(s*(s-a)*(s-b)*(s-c)|s=(a+b+c)/2)=n^2
Then
Print{a,b,c}
Stop
IfEnd
Next:Next:Next

标准蛮力解决方案。代码为122字节,指定n为1字节作为参数。


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.