三角形面积


16

您面临的另一个简单挑战。

你的任务

编写一个包含输入的程序或函数,其中包含3对x坐标和y坐标,并计算在其中形成的三角形的面积。对于那些不记得如何计算的人,可以在这里找到它。

例:

1,2,4,2,3,7       # input as x1,y1,x2,y2,x3,y3
7.5               # output

Wolfram Alpha上看到

一些注意事项:

  • 输入将是六个以10为底的正整数。
  • 您可以假定输入采用任何合理的格式
  • 这些点将始终形成有效的三角形。
  • 您可以假定输入已经存储在诸如的变量中t
  • 以字节为单位的最短代码胜出!

编辑:为了避免造成任何混乱,我简化了如何处理输入而不损害任何当前代码。

请记住,您的程序/函数必须输出有效区域,因此它不能给出负数作为输出


1
回复:您的编辑。这是否意味着我可以在中拥有实际的成对阵列(例如[[1, 2], [4, 2], [3, 7]]T
丹尼斯

4
我还是很困惑。该帖子仍然说“ 3对”和“ 6 ...整数”。请注意,删除任何一个都将使某些答案无效。
xnor

1
我不喜欢在发布和回答后看到问题的变化。但是这次我可以再保存2个字节,所以没关系
edc65

1
如果我们可以将它们分为三对,那么可以将它们作为多维数组吗?也就是说,[1 2;4 2;3 7](使用Julia语法)?
Glen O

2
@YiminRong根据定义,三角形的面积不能为负。点的顺序无关紧要
。– Rainbolt

Answers:


16

CJam,18个16字节

T(f.-~(+.*:-z.5*

CJam解释器中在线尝试。

理念

维基百科所述,三角形的面积[[0 0] [x y] [z w]]可以计算为|det([[x y] [z w]])| / 2 = |xw-yz| / 2

对于普通三角形[[a b] [c d] [e f]],我们可以将其第一个顶点转换为原点,从而获得三角形[[0 0] [c-a d-b] [e-a f-b]],其面积可以通过上述公式计算。

T                  e# Push T.
                   e# [[a b] [c d] [e f]]
   (               e# Shift out the first pair.
                   e# [[c d] [e f]] [a b]
    f.-            e# For [c d] and [e f], perform vectorized
                   e# subtraction with [a b].
                   e# [[c-a d-b] [e-a f-b]]
       ~           e# Dump the array on the stack.
                   e# [c-a d-b] [e-a f-b]
        (+         e# Shift and append. Rotates the second array.
                   e# [c-a d-b] [f-b e-a]
          .*       e# Vectorized product.
                   e# [(c-a)(f-b) (d-b)(e-a)]
            :-     e# Reduce by subtraction.
                   e# (c-a)(f-b) - (d-b)(e-a)
              z    e# Apply absolute value.
                   e# |(c-a)(f-b) - (d-b)(e-a)|
               .5* e# Multiply by 0.5.
                   e# |(c-a)(f-b) - (d-b)(e-a)| / 2

10

Mathematica,27个字节

Area@Polygon@Partition[t,2]

17
我喜欢它如何使用内置函数,并且比cjam答案还要长。
Carcigenicate

2
@Carcigenicate的实际问题是Partition[t,2],对应2/于CJam中的。;)
Martin Ender 2015年

10

JavaScript(ES6)42 .44。

编辑输入格式更改,我可以保存2个字节

以数组为参数并返回计算值的匿名函数。

(a,b,c,d,e,f)=>(a*(d-f)+c*(f-b)+e*(b-d))/2

测试在符合EcmaScript 6的浏览器中运行以下代码段的方法。

f=(a,b,c,d,e,f)=>(a*(d-f)+c*(f-b)+e*(b-d))/2

function test()
{
  var v=I.value.match(/\d+/g)
  I.value = v
  R.innerHTML=f(...v)
}
<input id=I onchange="test()"><button onclick="test()">-></button><span id=R></span>


1
您不能只是将这些值用作标准参数并在创建数组时为自己节省2个字符吗?
Mwr247

挑战说@ Mwr247The input will be a vector with six base 10 positive integers.
edc65

啊哈 最初,我将其解释为意味着每对构成一个坐标矢量(例如Wolfram示例),而不是将输入本身限制为数组,因此可以使用其他格式。现在更有意义。
Mwr247

@ Mwr247现在您说对了
edc65

8

朱莉娅,32个字节

abs(det(t[1:2].-t[[3 5;4 6]]))/2

构造一个叉积的适当项的矩阵,用于det获取结果值,将绝对值用于处理负数,然后将其除以2,因为它是三角形而不是平行四边形。


7

Matlab /八度,26字节

我到目前为止还不知道这个内置的)

polyarea(t(1:2:5),t(2:2:6))

6

Java,79 88字节

float f(int[]a){return Math.abs(a[0]*(a[3]-a[5])+a[2]*(a[5]-a[1])+a[4]*(a[1]-a[3]))/2f;}

只是使用基本公式,没什么特别的。

编辑:忘记采取绝对值:(


您不需要使其可运行吗?
downrep_nation 2015年

3
该示例仅显示了一个函数调用,这是相对正常的默认值。
Geobits,2015年

2
对于每个问题,•您可以假定输入已经存储在变量中,例如't'。因此,return(t[0]*(t[3]...足够了吗?
AdmBorkBork 2015年

@TimmyD感觉很可疑,但是可以其减少到62个字节。嗯……至少到现在为止,我将保持原样。
Geobits,2015年

5

Minkolang 0.8,34个字节

ndndn0g-n1g-n0g-n0g-1R*1R*-$~2$:N.

有人要鸡蛋n0g吗?

说明

非常简单。使用公式|(x2-x1)(y3-y1) - (x3-x1)(y2-y1)|/2

nd      x1, x1
nd      x1, x1, y1, y1
n0g-    x1, y1, y1, x2-x1
n1g-    x1, y1, x2-x1, y2-y1
n0g-    y1, x2-x1, y2-y1, x3-x1
n0g-    x2-x1, y2-y1, x3-x1, y3-y1
1R*     y3-y1, x2-x1, (y2-y1)(x3-x1)
1R*     (y2-y1)(x3-x1), (y3-y1)(x2-x1)
-       (y2-y1)(x3-x1) - (y3-y1)(x2-x1)
$~      |(y2-y1)(x3-x1) - (y3-y1)(x2-x1)|
2$:     |(y2-y1)(x3-x1) - (y3-y1)(x2-x1)|/2 (float division)
N.      Output as integer and quit.

3

JayScript,58个字节

声明一个匿名函数:

function(a,b,c,d,e,f){return (a*(d-f)+c*(f-b)+e*(b-d))/2};

例:

var nFunct = function(a,b,c,d,e,f){return (a*(d-f)+c*(f-b)+e*(b-d))/2};
print(nFunct(1,2,4,2,3,7));

g是做什么的?
级圣河

@steveverrill没什么,我只是个白痴。固定...
mınxomaτ


3

PHP – 68 88 89字节

感谢Martjin的出色指导!

<?=.5*abs(($t[1]-$t[5])*($t[4]-$t[2])-($t[1]-$t[3])*($t[6]-$t[2]))?>

要使用它,请创建一个area.php具有此内容的文件,额外的一行符合假定数据已保存在t规格的可变部分中的要求,并且末尾的adds添加了回车符,因此输出很漂亮且分开:

<?php $t = $argv; ?>
<?=.5*abs(($t[1]-$t[5])*($t[4]-$t[2])-($t[1]-$t[3])*($t[6]-$t[2]))?>
␍

然后在命令行上提供坐标x₁ y₁ x₂ y₂ x₃ y₃,例如

$ php area.php 1 2 4 2 3 7
7.5

“您可以假定输入已经存储在诸如之类的变量中t。” $a-> $t,删除$a=$argv;保存的9个字节
Martijn

之后,您可以替换<?php echo<?=,再保存7个字节
Martijn 2015年

您可以说这是PHP4.1,register_globals=On在您的php.ini文件中(默认)。在php.net/manual/en/security.globals.php上
Ismael Miguel


2

R,37个字节

cat(abs(det(rbind(matrix(t,2),1))/2))

将坐标向量转换为矩阵并在1的行上固定。
计算行列式并除以2。
返回绝对结果。如果顺序始终是顺时针方向,则abs不需要。

> t = c(1,2,4,2,3,7)
> cat(det(rbind(matrix(t,2),1))/2)
7.5

2

Python 2,48 47 50字节

很简单的; 遵循标准方程式:

lambda a,b,c,d,e,f:abs(a*(d-f)+c*(f-b)+e*(b-d))/2.

其他类似的简单方法则更长:

def a(a,b,c,d,e,f):return abs(a*(d-f)+c*(f-b)+e*(b-d))/2. # 57
lambda t:abs(t[0]*(t[3]-t[5])+t[2]*(t[5]-t[1])+t[4]*(t[1]-t[3]))/2. # 67
def a(t):return abs(t[0]*(t[3]-t[5])+t[2]*(t[5]-t[1])+t[4]*(t[1]-t[3]))/2. # 74

Python通过numpy访问确定函数。

感谢1个字节的muddyfishxnor捕获错误。


您可以02.0离开删除2.
蓝色

真的,@ muddyfish,谢谢!
Celeo,2015年

这是Python 2还是3?分区的工作方式因版本而异...
mbomb007

澄清@ mbomb007。
Celeo,2015年

1
您需要一个abs使答案肯定的答案。
xnor

2

PHP,77

根据@Yimin Rong的回答,我觉得我可以通过使用list()而不是直接$argv缩写一些变量来将其改进几个字节。此外echo,如果有回声和事物之间的分隔符正呼应并不需要的空间。

echo$variable;,,echo(4+2);echo'some string';同样有效,而echofunction($variable)混淆PHP。

另一方面,我也补充说abs()在数学上是准确的,因为某些顶点组合会产生“负面积”

list($t,$a,$b,$c,$d,$e,$f)=$argv;echo.5*abs(($a-$e)*($d-$b)-($a-$c)*($f-$b));

您可以通过CLI运行它

php -r "list($t,$a,$b,$c,$d,$e,$f)=$argv;echo.5*abs(($a-$e)*($d-$b)-($a-$c)*($f-$b));" 1 2 4 2 3 7
7.5

2

AWK – 51 42字节

AWK没有内置功能,abs因此可以sqrt(x^2)用来替代。

{print sqrt((($1-$5)*($4-$2)-($1-$3)*($6-$2))^2)/2}

另存为area.awk并用作echo x₁ y₁ x₂ y₂ x₃ y₃ | awk -f area.awk,例如

$ echo 1 2 4 2 3 7 | awk -f area.awk
7.5

1

PowerShell,70字节

[math]::Abs(($t[0]-$t[4])*($t[3]-$t[1])-($t[0]-$t[2])*($t[5]-$t[1]))/2

使用与其他解决方案相同的标准公式。对于每个问题,假定阵列已预先填充,例如$t=(1,2,4,2,3,7)。但是ooof$[]语法会杀死这一点吗?


您对使用$[]启发我尝试AWK解决方案所造成的损失的评论,从长远来看,它并不是没有竞争性的!

1

dc,52个字节

假设输入在寄存器中t 为:x1 y1 x2 y2 x3 y3x1位于t堆栈的顶部。

1kLtLtsaLtsbLtdscLtltrlalclbltla-*sd-*se-*leld++2/p

1 2 4 2 3 7stStStStStSt #puts coordinates into register t (closest thing dc has to variables) 1kLtLtsaLtsbLtdscLtltrlalclbltla-*sd-*se-*leld++2/p 7.5

这使用以下公式计算面积:

(x1(y2-y3) + x2(y3-y1) + x3(y1 - y2))/2

并快速分解该过程:

  • 1k Lt Lt sa Lt sb Lt d sc Lt lt r:将小数精度设置为1位,将t堆栈的一部分移入主堆栈,并将堆栈的各个部分移至其他寄存器进行存储(d复制主堆栈r的顶部,反转主堆栈的顶部两个元素,L/l移动/从给定寄存器复制到主寄存器,s将主堆栈的顶部移至给定寄存器)

    主要: y3 x3 y2 x1

    a:y1,b:x2,c:y2,t:y3

  • la lc lb lt la:将栈顶复制到寄存器中acbt,和a以在该顺序的主堆叠

    主要: y1 y3 x2 y2 y1 y3 x3 y2 x1

    a:y1,b:x2,c:y2,t:y3

  • - * sd:计算((y3-y1)*x2)结果并将其放入d(寄存器ab不再使用和ct因此现在将它们从堆栈列表中删除)

    主要: y2 y1 y3 x3 y2 x1

    d:((y3-y1)*x2)

  • - * se - *:计算((y1-y2)*y3)((y2-x3)*x1) ; 将前者存储在其中e,并将后者留在主堆栈中

    主要: ((y2-x3)*x1)

    d:((y3-y1)*x2),e:((y1-y2)*y3)

  • le ld + +:复制寄存器顶部ed到主堆叠,顶部2堆栈值(推结果返回给主堆叠)的计算总和的两倍

    主要: (((y3-y1)*x2)+((y1-y2)*y3)+((y2-x3)*x1))

    d:((y3-y1)*x2),e:((y1-y2)*y3)

  • 2 /:将2压入主堆栈,将堆栈上的第二个值除以1st(de不再使用,将其从堆栈列表中删除)

    主要: (((y3-y1)*x2)+((y1-y2)*y3)+((y2-x3)*x1))/2

重新排列堆栈上的值,我们可以看到它等同于此解释顶部的公式: (x1(y2-y3) + x2(y3-y1) + x3(y1 - y2))/2

  • p:打印主堆栈的顶部以输出。
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.