Diện tích tam giác


16

Một thử thách dễ dàng khác cho bạn.

Nhiệm vụ của bạn

Viết chương trình hoặc hàm lấy đầu vào, chứa 3 cặp tọa độ x và y và tính diện tích tam giác hình thành bên trong chúng. Đối với những người không thể nhớ cách tính toán, bạn có thể tìm thấy nó ở đây .

Thí dụ:

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

Xem nó tại Wolfram Alpha

Một số cân nhắc:

  • Đầu vào sẽ là sáu số nguyên cơ bản 10.
  • Bạn có thể giả sử đầu vào ở bất kỳ định dạng hợp lý .
  • Các điểm sẽ luôn tạo thành một tam giác hợp lệ.
  • Bạn có thể giả sử đầu vào đã được lưu trữ trong một biến như t.
  • Mã ngắn nhất tính bằng byte thắng!

Chỉnh sửa: Để tránh bất kỳ sự nhầm lẫn nào, tôi đã đơn giản hóa cách xử lý đầu vào mà không gây nguy hiểm cho bất kỳ mã hiện tại nào.

Hãy nhớ rằng chương trình / chức năng của bạn phải xuất ra một khu vực hợp lệ, vì vậy nó không thể đưa ra số âm làm đầu ra


1
Re: chỉnh sửa của bạn. Điều đó có nghĩa là tôi có thể có một mảng thực sự của các cặp (ví dụ [[1, 2], [4, 2], [3, 7]]:) trong T?
Dennis

4
Tôi vẫn còn bối rối. Bài đăng vẫn nói cả "3 cặp" và "sáu ... số nguyên". Lưu ý rằng loại bỏ một trong hai sẽ làm mất hiệu lực một số câu trả lời.
xnor

1
Tôi không muốn thấy một sự thay đổi câu hỏi sau khi đăng và trả lời. Nhưng lần này tôi có thể tiết kiệm thêm 2 byte, vì vậy mọi thứ đều ổn
edc65

1
Nếu chúng ta có thể lấy chúng thành ba cặp, chúng ta có thể lấy chúng thành một mảng nhiều chiều không? Đó là, [1 2;4 2;3 7](sử dụng cú pháp Julia)?
Glen O

2
@YiminRong Diện tích của một hình tam giác không thể âm theo định nghĩa. Việc các điểm được xếp theo thứ tự nào không quan trọng.
Rainbolt

Câu trả lời:


16

CJam, 18 16 byte

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

Hãy thử trực tuyến trong trình thông dịch CJam .

Ý tưởng

Như đã đề cập trên Wikipedia , diện tích của tam giác [[0 0] [x y] [z w]]có thể được tính là |det([[x y] [z w]])| / 2 = |xw-yz| / 2.

Đối với một tam giác chung [[a b] [c d] [e f]], chúng ta có thể dịch đỉnh đầu tiên của nó sang gốc, do đó thu được tam giác [[0 0] [c-a d-b] [e-a f-b]], diện tích có thể được tính theo công thức trên.

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

Toán học, 27 byte

Area@Polygon@Partition[t,2]

17
Tôi thích cách này sử dụng Tích hợp và vẫn dài hơn câu trả lời của cjam.
Carcigenicate

2
@Carcigenicate vấn đề thực sự là Partition[t,2], tương ứng với 2/trong CJam. ;)
Martin Ender

10

JavaScript (ES6) 42 .44.

Chỉnh sửa định dạng đầu vào thay đổi, tôi có thể lưu 2 byte

Một hàm ẩn danh lấy mảng làm tham số và trả về giá trị được tính.

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

Kiểm tra chạy đoạn mã dưới đây trong trình duyệt tuân thủ 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
Bạn không thể lấy các giá trị làm tham số tiêu chuẩn và tự lưu 2 ký tự khi tạo mảng?
Mwr247

@ Mwr247 thách thức nóiThe input will be a vector with six base 10 positive integers.
edc65

Aha. Ban đầu tôi đã giải thích rằng có nghĩa là mỗi cặp tạo nên một vectơ tọa độ (ví dụ như ví dụ Wolfram), trái ngược với chính đầu vào bị giới hạn trong một mảng và do đó có thể sử dụng các định dạng khác. Làm cho ý nghĩa hơn bây giờ.
Mwr247

@ Mwr247 bây giờ bạn đã đúng
edc65

8

Julia, 32 byte

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

Xây dựng một ma trận các điều khoản thích hợp của sản phẩm chéo, sử dụng detđể lấy giá trị kết quả, lấy giá trị tuyệt đối để xử lý các phủ định và sau đó chia cho 2 vì đó là hình tam giác chứ không phải hình bình hành.


7

Matlab / Octave, 26 byte

Tôi không biết về điều này được xây dựng cho đến nay =)

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

6

Java, 79 88 byte

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;}

Chỉ cần sử dụng công thức cơ bản, không có gì đặc biệt.

Chỉnh sửa: Quên lấy giá trị tuyệt đối :(


bạn không cần phải làm cho nó chạy được?
downrep_nation

3
Ví dụ này chỉ hiển thị một lệnh gọi hàm và đó là một mặc định tương đối bình thường ở đây.
Geobits

2
Theo câu hỏi, • Bạn có thể giả sử đầu vào đã được lưu trữ trong một biến như 't'. Vì vậy, return(t[0]*(t[3]...nên đủ, không?
admBorkBork

@TimmyD Cảm thấy mờ ám khi làm điều đó, nhưng nó sẽ giảm xuống còn 62 byte. Hmmm .... tôi sẽ để nó như vậy, ít nhất là bây giờ.
Geobits

5

Chồn 0,8 , 34 byte

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

Bất cứ ai cũng muốn một số trứng- n0g?

Giải trình

Rất đơn giản. Sử dụng công thức |(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 byte

Khai báo một hàm ẩn danh:

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

Thí dụ:

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 làm gì
Cấp sông St

@steveverrill Không có gì, tôi chỉ là một thằng ngốc. Đang sửa chữa ...
mınxomaτ


3

PHP - 68 88 89 byte

Cảm ơn Martjin cho một số gợi ý tuyệt vời!

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

Để sử dụng nó, hãy tạo một tệp area.phpcó nội dung này, dòng bổ sung đáp ứng giả định rằng dữ liệu được lưu trong mộtt phần biến của thông số kỹ thuật và ở cuối thêm một trả về vận chuyển để đầu ra tốt và tách biệt:

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

Sau đó cung cấp tọa độ trên dòng lệnh như x₁ y₁ x₂ y₂ x₃ y₃, vd

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

"Bạn có thể giả sử đầu vào đã được lưu trữ trong một biến như t." $a-> $t, xóa $a=$argv;lưu 9 byte
Martijn

Sau đó, bạn có thể thay thế <?php echobằng <?=, lưu thêm 7 byte
Martijn

Bạn có thể nói rằng đây là PHP4.1, với tệp register_globals=Oncủa bạn php.ini(mặc định). Đọc thêm tại php.net/manual/en/security.globals.php
Ismael Miguel


2

R, 37 byte

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

Chuyển đổi vectơ tọa độ thành ma trận và xử lý trên một hàng 1 '.
Tính hệ số xác định và chia cho 2.
Trả về kết quả tuyệt đối. Nếu thứ tự luôn luôn theo chiều kim đồng hồ thì abssẽ không được yêu cầu.

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

2

Python 2, 48 47 50 byte

Rất đơn giản; theo phương trình chuẩn:

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

Các cách tiếp cận đơn giản tương tự khác dài hơn:

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

Truy cập của Python vào một hàm xác định là thông qua numpy .

Cảm ơn bùn cho 1 byte và xnor để bắt lỗi.


bạn có thể xóa 0từ 2.0rời khỏi2.
Blue

Hoàn toàn đúng, @muddyfish, cảm ơn!
Celeo

Đây là Python 2 hay 3? Bộ phận hoạt động khác nhau tùy thuộc vào phiên bản ...
mbomb007

Làm rõ, @ mbomb007.
Celeo

1
Bạn cần một abscâu trả lời tích cực.
xnor

2

PHP, 77

Dựa trên câu trả lời của @Yimin Rong, tôi cảm thấy mình có thể cải thiện nó bằng một vài byte bằng cách sử dụng list()thay vì $argvviết thẳng một số biến. Cũng echokhông cần một khoảng trắng nếu có dấu phân cách giữa tiếng vang và sự việc được lặp lại.

echo$variable;, echo(4+2);echo'some string';có giá trị như nhau trong khi echofunction($variable)nhầm lẫn PHP.

Mặt khác, tôi cũng thêm abs()vào là chính xác về mặt toán học, vì một số tổ hợp đỉnh mang lại "vùng âm"

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

Bạn có thể chạy nó thông qua 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 byte

AWK không có tích hợp absđể sử dụng sqrt(x^2)để thay thế.

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

Lưu dưới dạng area.awkvà sử dụng như echo x₁ y₁ x₂ y₂ x₃ y₃ | awk -f area.awk, vd

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

1

PowerShell, 70 byte

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

Sử dụng công thức tiêu chuẩn giống như các giải pháp khác. Theo câu hỏi, giả sử mảng được điền trước, ví dụ $t=(1,2,4,2,3,7). Nhưng ooof , liệu $[]cú pháp giết chết cái này ...


Nhận xét của bạn về hình phạt từ việc sử dụng $[]truyền cảm hứng cho tôi để thử một giải pháp AWK, theo chiều dài, không phải là không cạnh tranh!

1

dc , 52 byte

Giả sử đầu vào được đăng ký t là: x1 y1 x2 y2 x3 y3với x1ở đầu tngăn xếp.

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

Điều này sử dụng công thức sau đây cho khu vực:

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

Và để phân tích nhanh quá trình:

  • 1k Lt Lt sa Lt sb Lt d sc Lt lt r: đặt độ chính xác thập phân đến 1 vị trí, di chuyển các phần của ngăn xếp vào ngăn xếp tchính và di chuyển các phần khác nhau của ngăn xếp chính sang các thanh ghi khác để lưu trữ ( dsao chép đỉnh của ngăn xếp chính, rđảo ngược hai phần tử trên cùng của ngăn xếp chính, L/ldi chuyển / sao chép từ thanh ghi đã cho sang chính, sdi chuyển đỉnh ngăn xếp chính sang thanh ghi đã cho)

    Chủ yếu: y3 x3 y2 x1

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

  • la lc lb lt la: Copy phía trên cùng của ngăn xếp trong thanh ghi a, c, b, t, và ađể ngăn xếp chính theo thứ tự

    Chủ yếu: y1 y3 x2 y2 y1 y3 x3 y2 x1

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

  • - * sd: Tính toán ((y3-y1)*x2)và kết quả đặt trong d(thanh ghi a, b, c, và tkhông còn được sử dụng vì vậy tôi sẽ thả chúng ra khỏi danh sách các ngăn xếp bây giờ)

    Chủ yếu: y2 y1 y3 x3 y2 x1

    d:((y3-y1)*x2)

  • - * se - *: tính toán ((y1-y2)*y3)((y2-x3)*x1); lưu trữ cái trước evà để cái sau trên ngăn xếp chính

    Chủ yếu: ((y2-x3)*x1)

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

  • le ld + +: sao chép đỉnh của thanh ghi edvào ngăn xếp chính, tính tổng của 2 giá trị ngăn xếp trên cùng (đẩy kết quả trở lại ngăn xếp chính) hai lần

    Chủ yếu: (((y3-y1)*x2)+((y1-y2)*y3)+((y2-x3)*x1))

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

  • 2 /: đẩy 2 lên ngăn xếp chính, chia giá trị thứ 2 trên ngăn xếp cho ngăn thứ 1 ( dekhông còn được sử dụng, thả chúng khỏi danh sách các ngăn xếp)

    Chủ yếu: (((y3-y1)*x2)+((y1-y2)*y3)+((y2-x3)*x1))/2

Sắp xếp lại giá trị trên ngăn xếp, chúng ta có thể thấy nó tương đương với công thức ở đầu giải thích này: (x1(y2-y3) + x2(y3-y1) + x3(y1 - y2))/2

  • p: In đầu ngăn xếp chính ra đầu ra.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.