พื้นที่ของรูปสามเหลี่ยม


16

อีกหนึ่งความท้าทายที่ง่ายสำหรับคุณ

งานของคุณ

เขียนโปรแกรมหรือฟังก์ชั่นที่รับอินพุตซึ่งมี x- และ y-พิกัด 3 คู่และคำนวณพื้นที่ของสามเหลี่ยมที่เกิดขึ้นภายใน สำหรับผู้ที่ไม่สามารถจำวิธีการคำนวณนั้นคุณสามารถค้นหาได้ที่นี่

ตัวอย่าง:

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 คู่" และ "หก ... จำนวนเต็ม" โปรดทราบว่าการลบคำตอบอาจทำให้คำตอบบางอย่างไม่ถูกต้อง
xnor

1
ฉันไม่ชอบที่จะเห็นการเปลี่ยนแปลงคำถามหลังจากโพสต์และตอบ แต่ครั้งนี้ฉันสามารถบันทึกได้อีก 2 ไบต์ดังนั้นจึงไม่
เป็นไร

1
หากเราสามารถจับพวกมันเป็นคู่ที่สามเราจะนำพวกมันไปเป็นอาร์เรย์หลายมิติได้หรือไม่? นั่นคือ[1 2;4 2;3 7](ใช้ไวยากรณ์ Julia) หรือไม่
เกลน O

2
@YiminRong พื้นที่ของรูปสามเหลี่ยมไม่สามารถลบได้โดยการกำหนด ไม่สำคัญว่าจะเรียงตามลำดับคะแนนใด
Rainbolt

คำตอบ:


16

CJam, 18 16 ไบต์

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

ลองใช้ออนไลน์ในล่าม CJam

ความคิด

ตามที่กล่าวถึงในWikipediaพื้นที่ของรูปสามเหลี่ยม[[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
ฉันชอบที่สิ่งนี้ใช้ Built-in และยังคงนานกว่าคำตอบ cjam
Carcigenicate

2
@Carcigenicate ปัญหาที่แท้จริงคือPartition[t,2]ซึ่งสอดคล้องกับ2/ใน CJam ;)
Martin Ender

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

@ Mwr247 ความท้าทายบอกว่าThe 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 / Octave ขนาด 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

3
ตัวอย่างแสดงการเรียกใช้ฟังก์ชันและนั่นเป็นค่าเริ่มต้นที่ค่อนข้างปกติที่นี่
Geobits

2
ตามคำถาม•คุณสามารถสมมติว่าอินพุตถูกเก็บไว้ในตัวแปรเช่น 't' แล้ว ดังนั้นreturn(t[0]*(t[3]...ควรจะพอเพียงหรือไม่
AdmBorkBork

@ TimmyD รู้สึกร่มรื่น แต่มันจะทำให้มันเหลือ 62 ไบต์ อืม ....ฉันจะปล่อยให้เป็นอย่างนี้อย่างน้อยตอนนี้
Geobits

5

Minkolang 0.8 , 34 ไบต์

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

ทุกคนต้องการ egg- บาง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));


@ สตีฟเวอร์ริลล์ไม่มีอะไรฉันเป็นแค่คนงี่เง่า กำลังแก้ไข ...
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ส่วนตัวแปรของข้อมูลจำเพาะและ␍ที่ส่วนท้ายจะเพิ่มการขึ้นบรรทัดใหม่เพื่อให้เอาต์พุตดีและแยกออก:

<?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

คุณสามารถพูดได้ว่านี่คือ 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))

แปลงเวกเตอร์ของพิกัดเป็นเมทริกซ์และ tacks ในแถวที่ 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

ขอบคุณmuddyfishสำหรับ 1 ไบต์และxnorสำหรับการจับข้อผิดพลาด


คุณสามารถลบ0จาก2.0เพื่อออก2.
Blue

ค่อนข้างจริง @ muddyfish ขอบคุณ!
Celeo

Python 2 หรือ 3 นี้หรือไม่ แผนกทำงานแตกต่างกันไปตามรุ่น ...
mbomb007

ชี้แจงแล้ว, @ mbomb007
Celeo

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)pre-ประชากรเช่น แต่ooof , $และ[]ไวยากรณ์จะฆ่าอันนี้หรือไม่ ...


ความคิดเห็นของคุณเกี่ยวกับบทลงโทษจากการใช้$และเป็น[]แรงบันดาลใจให้ฉันลองใช้โซลูชัน AWK ซึ่งตามยาวแล้วก็ไม่ได้เป็นการแข่งขัน

1

กระแสตรง , 52 ไบต์

ถือว่าอินพุตอยู่ในการลงทะเบียนt เป็น: x1 y1 x2 y2 x3 y3โดยx1ที่ด้านบนสุดของ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: คัดลอกด้านบนของสแต็คในทะเบียนที่a, c, b, tและaการกองหลักในลำดับที่

    หลัก: y1 y3 x2 y2 y1 y3 x3 y2 x1

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

  • - * sd: การคำนวณ((y3-y1)*x2)และนำผลd(ลงทะเบียนa, b, cและtไม่ใช้ดังนั้นฉันจะวางพวกเขาจากรายการของสแต็คในขณะนี้)

    หลัก: 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 + +: คัดลอกด้านบนของรีจิสเตอร์eและdไปยังสแต็กหลักคำนวณผลรวมของค่าสแต็ค 2 อันดับแรก (ผลักผลลัพธ์กลับไปที่สแต็กหลัก) สองครั้ง

    หลัก: (((y3-y1)*x2)+((y1-y2)*y3)+((y2-x3)*x1))

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

  • 2 /: กด 2 ไปยังสแต็กหลักแบ่งค่าที่ 2 ในสแต็กด้วยอันดับที่ 1 ( dและeไม่ได้ใช้งานอีกต่อไปโดยปล่อยจากรายการสแต็ค)

    หลัก: (((y3-y1)*x2)+((y1-y2)*y3)+((y2-x3)*x1))/2

การจัดเรียงค่าใหม่บนสแต็กเราจะเห็นว่ามันเทียบเท่ากับสูตรที่ด้านบนของคำอธิบายนี้: (x1(y2-y3) + x2(y3-y1) + x3(y1 - y2))/2

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