Üçgenin alanı


16

Sizin için bir başka kolay meydan okuma.

Senin görevin

Girdiyi alan, 3 çift x ve y koordinatı içeren ve bunların içinde oluşan üçgenin alanını hesaplayan bir program veya işlev yazın. Nasıl hesaplayacağını hatırlayamayanlar için burada bulabilirsiniz .

Misal:

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

Wolfram Alpha'da görün

Bazı düşünceler:

  • Giriş altı temel 10 pozitif tamsayı olacaktır.
  • Girdinin makul bir biçimde olduğunu varsayabilirsiniz .
  • Noktalar her zaman geçerli bir üçgen oluşturur.
  • Girişin zaten gibi bir değişkende saklandığını varsayabilirsiniz t.
  • Bayttaki en kısa kod kazanır!

Düzenleme: Herhangi bir karışıklığı önlemek için ben mevcut kodlardan herhangi birini tehlikeye atmadan giriş ele nasıl basitleştirildi.

Programınızın / fonksiyonunuzun geçerli bir alan çıkarması gerektiğini unutmayın, böylece çıktı olarak negatif bir sayı veremez


1
Re: senin düzenleme. Bu gerçek bir çift dizi (örneğin, [[1, 2], [4, 2], [3, 7]]) olabilir anlamına mı geliyor T?
Dennis

4
Hala kafam karıştı. Mesaj hala hem "3 çift" hem de "altı ... tamsayı" diyor. İkisinden birini kaldırmanın bazı yanıtları geçersiz kılacağını unutmayın.
xnor

1
Gönderdikten ve yanıtladıktan sonra soru değişikliği görmekten hoşlanmıyorum. Ama bu sefer 2 bayt daha kaydedebilirim, bu yüzden sorun yok
edc65

1
Onları üç çift olarak alabilirsek, onları çok boyutlu bir dizi olarak alabilir miyiz? Yani, [1 2;4 2;3 7](Julia sözdizimini kullanarak)?
Glen O

2
@YiminRong Bir üçgenin alanı tanım gereği negatif olamaz. Puanların hangi sırada olduğu önemli değil.
Rainbolt

Yanıtlar:


16

CJam, 18 16 bayt

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

CJam yorumlayıcısında çevrimiçi deneyin .

Fikir

Wikipedia'da belirtildiği gibi , üçgenin alanı [[0 0] [x y] [z w]]olarak hesaplanabilir |det([[x y] [z w]])| / 2 = |xw-yz| / 2.

Genel bir üçgen için [[a b] [c d] [e f]], ilk tepe noktasını başlangıç ​​noktasına çevirebilir, böylece [[0 0] [c-a d-b] [e-a f-b]]alanı yukarıdaki formülle hesaplanabilen üçgeni elde edebiliriz.

kod

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 bayt

Area@Polygon@Partition[t,2]

17
Bunun Yerleşik'i nasıl kullandığını ve hala cjam cevabından daha uzun olduğunu seviyorum.
Carcigenicate

2
@ Gerçek sorunu CJam Partition[t,2]içinde karşılık gelen 2/sorunudur. ;)
Martin Ender

10

JavaScript (ES6) 42.44 .

Giriş Girdisini Düzenle değişti, 2 bayt kaydedebilirim

Diziyi parametre olarak alan ve hesaplanan değeri döndüren anonim bir işlev.

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

Aşağıdaki snippet'i EcmaScript 6 uyumlu bir tarayıcıda çalıştırmayı test edin.

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
Değerleri standart parametreler olarak alıp diziyi oluştururken kendinize 2 karakter kaydedemez misiniz?
Mwr247

@ Mwr247 meydan okuma diyorThe input will be a vector with six base 10 positive integers.
edc65

Aha. Başlangıçta her çiftin, girişin kendisinin bir dizi ile sınırlı olmasının aksine ve diğer formatları kullanabileceği gibi, bir koordinat vektörü (Wolfram örneği gibi) oluşturduğunu yorumlamıştım. Şimdi daha mantıklı.
Mwr247

@ Mwr247 şimdi haklısın
edc65

8

Julia, 32 bayt

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

Bir çapraz ürünün uygun terimlerinin bir matrisini oluşturur, detelde edilen değeri elde etmek için kullanır , negatiflerle başa çıkmak için mutlak değer alır ve daha sonra 2'ye bölünür, çünkü bir paralelkenar değil bir üçgendir.


7

Matlab / Oktav, 26 bayt

Bu şimdiye kadar inşa edilmiş hakkında bilmiyordum =)

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

6

Java, 79 88 bayt

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

Sadece temel formülü kullanır, özel bir şey değildir.

Düzenleme: Mutlak değeri almayı unuttum :(


çalıştırılabilir yapmanıza gerek yok mu?
Ağustos

3
Örnekte sadece bir işlev çağrısı gösterilmektedir ve bu burada nispeten normal bir varsayılan değerdir.
Geobits

2
Soru başına, • Girişin zaten 't' gibi bir değişkende saklandığını varsayabilirsiniz. Yani, return(t[0]*(t[3]...yeterli olmalı, değil mi?
AdmBorkBork

@TimmyD yapıyor gölgeli hisseder, fakat ediyorum 62 bayt için aşağı getirmek. Hmmm .... En azından şimdilik olduğu gibi bırakacağım.
Geobits

5

Minkolang 0.8 , 34 bayt

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

Biraz yumurta isteyen var n0gmı?

açıklama

Çok basit. Formülü kullanır |(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 bayt

Anonim bir işlev bildirir:

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

Misal:

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 ne yapar?
Level River St

@steveverrill Hiçbir şey, ben sadece aptalım. Sabitleme ...
mınxomaτ


3

PHP - 68 88 89 bayt

Martjin'e bazı harika işaretçiler için teşekkürler!

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

Bunu kullanmak için, area.phpbu içeriğe sahip bir dosya oluşturun , ekstra satır , verilerint özelliklerin değişken bir bölümüne kaydedildiği varsayımını karşılar ve sonunda ␍ bir satırbaşı ekler, böylece çıktı güzel ve ayrılır:

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

Sonra komut satırında koordinatları sağlayın x₁ y₁ x₂ y₂ x₃ y₃, örn.

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

Msgstr "Girişin zaten gibi bir değişkende saklandığını varsayabilirsiniz t." $a-> $t, $a=$argv;9 bayt tasarruf kaldır
Martijn

Bundan sonra, 7 bayt tasarruf <?php echoederek değiştirebilirsiniz<?=
Martijn

Bu işle, PHP4.1 olduğunu söyleyebiliriz register_globals=Onsenin içinde php.inidosya (varsayılan). Daha fazlası için php.net/manual/tr/security.globals.php
Ismael Miguel


2

R, 37 bayt

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

Koordinatların vektörünü bir matrise dönüştürür ve 1'lik bir sıraya yapışır.
Determinant hesaplar ve 2'ye böler
. Mutlak sonucu döndürür. Sipariş her zaman saat yönünde absolsaydı gerekli olmazdı.

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

2

Python 2, 48 47 50 bayt

Çok basit; standart denklemi takip eder:

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

Diğer benzer şekilde basit yaklaşımlar daha uzundur:

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'un belirli bir işleve erişimi numpy ile olur .

Bir hata yakalamak için 1 bayt ve xnor için çamur balığı sayesinde .


0-den kaldırabilirsin2.0 izne2.
Mavi

Oldukça doğru, muddyfish, teşekkürler!
Celeo

Bu Python 2 veya 3 mü? Bölüm, sürüme bağlı olarak farklı çalışır ...
mbomb007

Netleştirildi, @ mbomb007.
Celeo

1
Bir ihtiyaç abscevabı olumlu yapmak için.
xnor

2

PHP, 77

@Yimin Rong'un cevabına dayanarak, bazı değişkenleri kısaltmak list()yerine doğrudan kullanarak birkaç bayt geliştirebileceğimi hissettim $argv. Ayrıca echoyankı ve yankılanan şey arasında bir sınırlayıcı varsa bir boşluk gerekmez.

echo$variable;,, echo(4+2);ve echo'some string';eşit derecede geçerliyken echofunction($variable)PHP'yi karıştırır.

Öte yandan, abs()bazı köşe nokta kombinasyonları "negatif alan" verdiğinden, matematiksel olarak doğru olduğunu da ekledim .

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

CLI üzerinden çalıştırabilirsiniz

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 bayt

AWK'da yerleşik yok abs bu yüzden yerine sqrt(x^2)koymak için kullanılır .

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

Farklı kaydet area.awkve şu şekilde kullan echo x₁ y₁ x₂ y₂ x₃ y₃ | awk -f area.awk, ör.

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

1

PowerShell, 70 Bayt

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

Diğer çözümlerle aynı standart formülü kullanır. Soru başına, dizinin önceden doldurulduğunu varsayar, örn $t=(1,2,4,2,3,7). Ama ayrılmak istemiyordu , yapar $ve []bu bir öldürmek SÖZDİZİMİ ...


Kullanmanın cezası hakkındaki yorumunuz $ve []bana göre, uzun süredir rakip olmayan bir AWK çözümü denemem için ilham verdi!

1

dc , 52 bayt

Giriş halinde olduğu varsayılmıştır t olarak: x1 y1 x2 y2 x3 y3birlikte x1en az tbireyin yığın.

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

Bu, alan için aşağıdaki formülü kullanır:

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

Ve sürecin hızlı bir dökümü için:

  • 1k Lt Lt sa Lt sb Lt d sc Lt lt r: ondalık duyarlığı 1 yere ayarlayın, yığının parçalarını tana yığına taşıyın ve ana yığının çeşitli parçalarını depolama için diğer kayıtlara taşıyın d(ana yığının üstünü çoğaltır,r üst iki öğesini tersine çevirir, L/ltaşır / verilen kayıttan ana sayfaya kopyala,s sayfaya , ana yığının üst kısmını taşır)

    Ana: y3 x3 y2 x1

    a:, y1b:, x2c:, y2t:y3

  • la lc lb lt la: Kayıtlardaki yığınlar üst kopyalamak a, c, b, t, vea bu sırada ana yığını

    Ana: y1 y3 x2 y2 y1 y3 x3 y2 x1

    a:, y1b:, x2c:, y2t:y3

  • - * sd: Hesapla ((y3-y1)*x2)ve satım sonucu d(kayıtlar a, b,c vet şimdi yığınlarının listeden bırakın edeceğiz böylece artık kullanılır)

    Ana: y2 y1 y3 x3 y2 x1

    D:((y3-y1)*x2)

  • - * se - *: hesaplama ((y1-y2)*y3)ve ((y2-x3)*x1); ilkini saklae ana yığını üzerinde bırakın

    Ana: ((y2-x3)*x1)

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

  • le ld + +: kaydın üstünü eve dana yığını kopyalayın , ilk 2 yığın değerinin toplamını hesaplayın (sonucu ana yığını geri itin)

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

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

  • 2 /: 2'yi ana yığının üzerine itin, yığındaki 2. değerleri 1'e bölün ( dve eartık kullanılmıyor, bunları yığın listesinden bırakarak)

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

Yığındaki değeri yeniden düzenleyerek, bu açıklamanın üstündeki formüle eşdeğer olduğunu görebiliriz: (x1(y2-y3) + x2(y3-y1) + x3(y1 - y2))/2

  • p: Çıktı almak için ana yığının üstünü yazdırın.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.