Çapraz Ürünü Bulun


20

Çapraz ürün , iki, üç boyutlu vektörlerin bir ve vektörü benzersiz gibi ifade edilmektedir:bc

  • ca b hem de dik olan vebirb

  • büyüklüğü paralelkenarın ve tarafından oluşturulan alana eşittir.cbirb

  • Doğrultuları , ve , bu sırayla takip sağ el kuralı .birbc

Çapraz ürün için birkaç eşdeğer formül vardır, ancak bir tanesi aşağıdaki gibidir:

birxb=det[benjkbir1bir2bir3b1b2b3]

burada ben , j ve k , birinci, ikinci ve üçüncü boyutlardaki birim vektörlerdir.

Meydan okuma

İki 3B vektör verildiğinde, çapraz ürünlerini bulmak için tam bir program veya işlev yazın. Özellikle çapraz ürünü hesaplayan yapılara izin verilmez.

Giriş

Her biri üç gerçek sayıdan oluşan iki dizi. Dilinizde diziler yoksa, sayılar yine de üçe gruplandırılmalıdır. Her iki vektör de <216 büyüklüğüne sahip olacaktır . Çapraz ürünün değişmeli olmadığını unutmayın ( birxb=-(bxbir) ), bu nedenle siparişi belirtmek için bir yolunuz olmalıdır.

Çıktı

Her bir bileşen dört önemli rakama veya 10-4 doğruysa, bunların çapraz ürünleri makul bir formatta . Bilimsel gösterim isteğe bağlıdır.

Test senaryoları

[3, 1, 4], [1, 5, 9]
[-11, -23, 14]

[5, 0, -3], [-3, -2, -8]
[-6, 49, -10]

[0.95972, 0.25833, 0.22140],[0.93507, -0.80917, -0.99177]
[-0.077054, 1.158846, -1.018133]

[1024.28, -2316.39, 2567.14], [-2290.77, 1941.87, 712.09]
[-6.6345e+06, -6.6101e+06, -3.3173e+06]

Bu , bu nedenle bayttaki en kısa çözüm kazanır.

Maltysen de benzer bir meydan okuma yayınladı , ancak yanıt zayıftı ve soru düzenlenmedi.


Giriş 2B dizi olarak alınabilir mi?
Dennis

Evet, 2 dış boyut olduğu sürece.
lirtosiast

Yanıtlar:


14

Jöle, 14 13 12 bayt

;"s€2U×¥/ḅ-U

Çevrimiçi deneyin!

Nasıl çalışır

;"s€2U×¥/ḅ-U Main link. Input: [a1, a2, a3], [b1, b2, b3]

;"           Concatenate each [x1, x2, x3] with itself.
             Yields [a1, a2, a3, a1, a2, a3], [b1, b2, b3, b1, b2, b3].
  s€2        Split each array into pairs.
             Yields [[a1, a2], [a3, a1], [a2, a3]], [[b1, b2], [b3, b1], [b2, b3]].
       ¥     Define a dyadic chain:
     U         Reverse the order of all arrays in the left argument.
      ×        Multiply both arguments, element by element.
        /    Reduce the 2D array of pairs by this chain.
             Reversing yields [a2, a1], [a1, a3], [a3, a2].
             Reducing yields [a2b1, a1b2], [a1b3, a3b1], [a3b2, a2b3].
         ḅ-  Convert each pair from base -1 to integer.
             This yields [a1b2 - a2b1, a3b1 - a1b3, a2b3 - a3b2]
           U Reverse the array.
             This yields [a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1] (cross product).

Rakip olmayan sürüm (10 bayt)

Tamam, bu utanç verici, ancak Jelly'nin dizi manipülasyon dili şimdiye kadar dizi rotasyonu için yerleşik değildi. Bu yeni yerleşik ile iki ek bayt kaydedebiliriz.

ṙ-×
ç_ç@ṙ-

Bu, @ AlexA.'nın J cevabındaki yaklaşımı kullanır . Çevrimiçi deneyin!

Nasıl çalışır

ṙ-×     Helper link. Left input: x = [x1, x2, x3]. Right input: y = [y1, y2, y3].

ṙ-      Rotate x 1 unit to the right (actually, -1 units to the left).
        This yields [x3, x1, x2].
  ×     Multiply the result with y.
        This yields [x3y1, x1y2, x2y3].


ç_ç@ṙ-  Main link. Left input: a = [a1, a2, a3]. Right input: b = [b1, b2, b3].

ç       Call the helper link with arguments a and b.
        This yields [a3b1, a1b2, a2b3].
  ç@    Call the helper link with arguments b and a.
        This yields [b3a1, b1a2, b2a3].
_       Subtract the result to the right from the result to the left.
        This yields [a3b1 - a1b3, a1b2 - a2b1, a2b3 - a3b2].
    ṙ-  Rotate the result 1 unit to the right.
        This yields [a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1] (cross product).

Her çifti taban -1'den dönüştürmek? Bu sadece kötülük. +1
ETHproductions

10

LISP, 128 122 bayt

Merhaba! Bu benim kodum:

(defmacro D(x y)`(list(*(cadr,x)(caddr,y))(*(caddr,x)(car,y))(*(car,x)(cadr,y))))(defun c(a b)(mapcar #'- (D a b)(D b a)))

Bunun en kısa çözüm olmadığını biliyorum, ama şimdiye kadar hiç kimse Lisp'de bir çözüm sunmadı :)

Denemek için aşağıdaki kodu kopyalayıp buraya yapıştırın !

(defmacro D(x y)`(list(*(cadr,x)(caddr,y))(*(caddr,x)(car,y))(*(car,x)(cadr,y))))(defun c(a b)(mapcar #'- (D a b)(D b a)))

(format T "Inputs: (3 1 4), (1 5 9)~%")
(format T "Result ~S~%~%" (c '(3 1 4) '(1 5 9)))

(format T "Inputs: (5 0 -3), (-3 -2 -8)~%")
(format T "Result ~S~%~%" (c '(5 0 -3) '(-3 -2 -8)))

(format T "Inputs: (0.95972 0.25833 0.22140), (0.93507 -0.80917 -0.99177)~%")
(format T "Result ~S~%" (c '(0.95972 0.25833 0.22140) '(0.93507 -0.80917 -0.99177)))

(format T "Inputs: (1024.28 -2316.39 2567.14), (-2290.77 1941.87 712.09)~%")
(format T "Result ~S~%" (c '(1024.28 -2316.39 2567.14) '(-2290.77 1941.87 712.09)))

Programlama Bulmacalar ve Kod Golf Stack Exchange hoş geldiniz. Bu harika bir cevap, +1. Kazanamayacak bir dilde cevap vermek için iyi, ama yine de yükler golf. Genellikle kod-golf zorlukları, diller arasında aralarında olduğundan daha fazladır!
wizzwizz4

9

Dyalog APL, 12 bayt

2⌽p⍨-p←⊣×2⌽⊢

Göre Alexa. Kullanıcısının J yanıt @ cevap bu yorum bölümünde @ randomra en iyileşmeye ve (tesadüfen) karşılığıdır.

TryAPL'de çevrimiçi deneyin .

Nasıl çalışır

2⌽p⍨-p←⊣×2⌽⊢  Dyadic function.
              Left argument: a = [a1, a2, a3]. Right argument: b = [b1, b2, b3].

         2⌽⊢  Rotate b 2 units to the left. Yields [b3, b1, b2].
       ⊣×     Multiply the result by a. Yields [a1b3, a2b1, a3b2].
     p←       Save the tacit function to the right (NOT the result) in p.
  p⍨          Apply p to b and a (reversed). Yields [b1a3, b2a1, b3a2].
    -         Subtract the right result (p) from the left one (p⍨).
              This yields [a3b1 - a1b3, a1b2 - a2b1, a2b3 - a3b2].
2⌽            Rotate the result 2 units to the left.
              This yields [a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1].

9

J, 27 14 bayt

2|.v~-v=.*2&|.

Bu, sol ve sağdaki dizileri kabul eden ve çapraz ürünlerini veren ikili bir fiildir.

Açıklama:

         *2&|.     NB. Dyadic verb: Left input * twice-rotated right input
      v=.          NB. Locally assign to v
   v~-             NB. Commute arguments, negate left
2|.                NB. Left rotate twice

Örnek:

    f =: 2|.v~-v=.*2&|.
    3 1 4 f 1 5 9
_11 _23 14

Burada deneyin

Randomra sayesinde 13 bayt kaydedildi!


@randomra Harika, teşekkürler! J uzmanı değilim, bu yüzden hala tam olarak nasıl çalıştığını anlıyorum ama genel bir fikrim var.
Alex

Bazı açıklamalar: *2&|.iki fiilden oluşan bir çataldır: *ve 2&|.. Sol girişi döndürülmüş 2 sağ girişle çarpar. Bu çatal, vyazdığımızda v~, parantez içindeki sol ve sağ giriş parametrelerini değiştirdiği (*2&|.)~yere eşdeğerdir ~.
randomra

@randomra Tamam, bu mantıklı. Tekrar teşekkürler!
Alex

6

Cı, 156 154 , 150 148 144 bayt

#include <stdio.h>
main(){float v[6];int i=7,j,k;for(;--i;)scanf("%f",v+6-i);for(i=1;i<4;)j=i%3,k=++i%3,printf("%f ",v[j]*v[k+3]-v[k]*v[j+3]);}

Uzun süredir ödül kazanmayacak, ama yine de gideceğimi düşündüm.

  • Girdi yeni satır veya boşlukla ayrılmış bileşenlerin listesidir (yani a1 a2 a3 b1 b2 b3), çıkış boşlukla sınırlandırılmıştır (yani c1 c2 c3).
  • İki giriş vektörünün indekslerinin ürünü hesaplamasına döngüsel olarak izin verir - belirleyicileri yazmaktan daha az karakter alır!

gösteri

Ungolfed:

#include <cstdio>
int main()
{
    float v[6];
    int i = 7, j, k;
    for (; --i; ) scanf("%f", v + 6 - 1);
    for (i = 1; i < 4; )
        j = i % 3,
        k = ++i % 3,
        printf("%f ", v[j] * v[k + 3] - v[k] * v[j + 3]);
}

1
Programlama Bulmacalar ve Kod Golf Stack Exchange hoş geldiniz. Bu harika bir cevap; golf dillerini yenmeyecek bir dilde cevap vermek için iyi. +1.
wizzwizz4

2
İlk forihtiyacınız yok{}
kaldırıldı

alkış, güncellendi.
calvinsykes

1
& V [6-i] yerine v + 6-i kullanabilirsiniz. Ayrıca, j = i% 3 ve k = (i + 1)% 3'ten sonra noktalı virgül yerine virgül kullanabilirsiniz. Son olarak, döngü için ikinci için i'yi 1 olarak başlatırsanız, artışı birkaç köşeli parantez kaydederek k = ++ i% 3'e taşıyabilirsiniz. Uyarılar konusunda endişelenmiyorsanız ve C'nin doğru sürümünü kullanıyorsanız, dahil etmeyi de atlayabilirsiniz.
Simyacı

harika, şerefe! Derleyicim üstbilginin atlanmasını kabul etmeyecek, bu yüzden oluşturabildiğim bir sürümle takıldım.
calvinsykes

4

Haskell, 41 bayt

x(a,b,c)(d,e,f)=(b*f-c*e,c*d-a*f,a*e-b*d)

Basit bir çözüm.


4

Bash + coreutils, 51

eval set {$1}*{$2}
bc<<<"scale=4;$6-$8;$7-$3;$2-$4"
  • Çizgi 1, iki vektörün kartezyen ürününü veren ve bunları konumsal parametrelere ayarlayan bir küme ayracı genişletmesi oluşturur.
  • Satır 2 uygun terimleri çıkarır; bcAritmetik değerlendirmeyi istenilen hassasiyette yapar.

Giriş, komut satırında virgülle ayrılmış iki liste gibidir. Yeni satırla ayrılmış satırlar olarak çıktı:

$ ./crossprod.sh 0.95972,0.25833,0.22140 0.93507,-0.80917,-0.99177
-.07705
1.15884
-1.01812
$

4

MATL , 17 bayt

!*[6,7,2;8,3,4])d

İlk girdi a , ikincisi b .

Çevrimiçi deneyin!

açıklama

!              % input b as a row array and transpose into a column array
*              % input a as a row array. Compute 3x3 matrix of pairwise products
[6,7,2;8,3,4]  % 2x3 matrix that picks elements from the former in column-major order
)              % apply index
d              % difference within each column

4

Pyth, 16 bayt

-VF*VM.<VLQ_BMS2

Çevrimiçi deneyin: Gösteri

Açıklama:

-VF*VM.<VLQ_BMS2   Q = input, pair of vectors [u, v]
              S2   creates the list [1, 2]
           _BM     transforms it to [[1, -1], [2, -2]]
      .<VLQ        rotate of the input vectors accordingly to the left:
                   [[u by 1, v by -1], [u by 2, v by -2]]
   *VM             vectorized multiplication for each of the vector-pairs
-VF                vectorized subtraction of the resulting two vectors

3

K5, 44 40 37 32 bayt

Bunu bir süre önce yazdı ve son zamanlarda tekrar tozunu aldı .

{{x[y]-x[|y]}[*/x@']'3 3\'5 6 1}

Eylemde:

 cross: {{x[y]-x[|y]}[*/x@']'3 3\'5 6 1};

 cross (3 1 4;1 5 9)
-11 -23 14
 cross (0.95972 0.25833 0.22140;0.93507 -0.80917 -0.99177)
-7.705371e-2 1.158846 -1.018133

Düzenleme 1:

İki ayrı argüman yerine liste listesi olarak girdi alarak 4 bayt kaydedildi:

old: {m:{*/x@'y}(x;y);{m[x]-m[|x]}'(1 2;2 0;0 1)}
new: {m:{*/x@'y}x    ;{m[x]-m[|x]}'(1 2;2 0;0 1)}

Düzenleme 2:

Base-decode ile bir arama tablosu hesaplayarak 3 bayt kaydedildi:

old: {m:{*/x@'y}x;{m[x]-m[|x]}'(1 2;2 0;0 1)}
new: {m:{*/x@'y}x;{m[x]-m[|x]}'3 3\'5 6 1}

Düzenleme 3:

Yerel bir lambda yerine örtük bir tanım kullanmaya izin vermek için uygulamayı yeniden düzenleyerek 5 bayt kaydedin. Ne yazık ki, bu çözüm artık OK'de çalışmamaktadır ve resmi k5 tercümanı gerektirir. OK'deki hatayı düzeltene kadar bunun için sözümü almalıyım:

old: {m:{*/x@'y}x;{m[x]-m[|x]}'3 3\'5 6 1}
new: {{x[y]-x[|y]}[*/x@']     '3 3\'5 6 1}

3

Ruby , 49 bayt

->u,v{(0..2).map{|a|u[a-2]*v[a-1]-u[a-1]*v[a-2]}}

Çevrimiçi deneyin!

2 yıl sonra dönen, Ruby negatif dizi indeksleri tedavi nasıl kullanarak 12 bayt traş. -1dizinin son öğesi -2, ikinci son vb.

Yakut, 57

->u,v{(0..2).map{|a|u[b=(a+1)%3]*v[c=(a+2)%3]-u[c]*v[b]}}

Test programında

f=->u,v{(0..2).map{|a|u[b=(a+1)%3]*v[c=(a+2)%3]-u[c]*v[b]}}

p f[[3, 1, 4], [1, 5, 9]]

p f[[5, 0, -3], [-3, -2, -8]]

p f[[0.95972, 0.25833, 0.22140],[0.93507, -0.80917, -0.99177]]

p f[[1024.28, -2316.39, 2567.14], [-2290.77, 1941.87, 712.09]]

2

Python, 73 48 bayt

Teşekkürler @FryAmTheEggman

lambda (a,b,c),(d,e,f):[b*f-c*e,c*d-a*f,a*e-b*d]

Bu, vektör çapraz ürününün bileşen tanımına dayanmaktadır.

Burada deneyin


lambda (a,b,c),(d,e,f):...çok tasarruf etmeli.
FryAmTheEggman

@FryAmTheEggman Haklısın. Lambda'nın bu argümanın nasıl olması gerektiğini belirtebileceğini unuttum.
TanMath

2

Jöle , 5 bayt

[[x1,x2],[y1,y2],[z1,z2]]Z

ṁ4ÆḊƝ

Çevrimiçi deneyin!

İşte SE işaretlemesinin üstesinden gelememesi durumunda bir PDF açıklaması .


Analitik formda çapraz çarpım

(x1,y1,z1)v1(x2,y2,z2)v2

v1=x1ben+y1j+z1k
v2=x2ben+y2j+z2k

Oxyz

v1xv2=(x1ben+y1j+z1k)x(x2ben+y2j+z2k)

benxj=k,benxk=-j,jxben=-k,jxk=ben,kxben=j,kxj=-ben

Gerekli yeniden düzenleme ve hesaplamalardan sonra:

v1xv2=(y1z2-z1y2)ben+(z1x2-x1z2)j+(x1y2-y1x2)k

Matris determinantları ile yakın ilişki

Burada dikkat edilmesi gereken ilginç bir nokta var:

x1y2-y1x2=|x1y1 x2y2|
z1x2-x1z2=|z1x1 z2x2|
y1z2-z1y2=|y1z1 y2z2|

||

Jöle kodu açıklaması

Şey ... burada açıklanacak fazla bir şey yok. Sadece matrisi oluşturur:

(x1y1z1x1 x2y2z2x2)

Ve her bir komşu matris çifti için, ikisine katılarak oluşturulan matrisin determinantını hesaplar.

ṁ4ÆḊƝ – Monadic Link. Takes input as [[x1,x2],[y1,y2],[z1,z2]].
ṁ4    – Mold 4. Cycle the list up to length 4, reusing the elements if necessary.
        Generates [[x1,x2],[y1,y2],[z1,z2],[x1,x2]].
    Ɲ – For each pair of neighbours: [[x1,x2],[y1,y2]], [[y1,y2],[z1,z2]], [[z1,z2],[x1,x2]].
  ÆḊ  – Compute the determinant of those 2 paired together into a single matrix.



1

ES6, 40 bayt

(a,b,c,d,e,f)=>[b*f-c*e,c*d-a*f,a*e-b*d]

Girdinin iki dizi olması gerekiyorsa 44 bayt:

([a,b,c],[d,e,f])=>[b*f-c*e,c*d-a*f,a*e-b*d]

Daha ilginç bir sürüm için 52 bayt:

(a,b)=>a.map((_,i)=>a[x=++i%3]*b[y=++i%3]-a[y]*b[x])

1

Julia 0.7 , 45 39 bayt

f(a,b)=1:3 .|>i->det([eye(3)[i,:] a b])

Çevrimiçi deneyin!

Görev açıklamasında verilen determinant tabanlı formülü kullanır.

-6 baytlık H.PWiz'e teşekkürler.


İki f(a,b)=1:3 .|>i->det([eye(3)[i,:] a b])
hileli

0

APL (NARS), 23 karakter, 46 bayt

{((1⌽⍺)×5⌽⍵)-(5⌽⍺)×1⌽⍵}

Ölçek:

  f←{((1⌽⍺)×5⌽⍵)-(5⌽⍺)×1⌽⍵}
  (3 1 4) f (1 5 9)
¯11 ¯23 14 
  (5 0 ¯3) f (¯3 ¯2 ¯8)
¯6 49 ¯10 
  (0.95972 0.25833 0.22140) f (0.93507 ¯0.80917 ¯0.99177)
¯0.0770537061 1.158846002 ¯1.018133265 
  (1024.28 ¯2316.39 2567.14) f (¯2290.77 1941.87 712.09)
¯6634530.307 ¯6610106.843 ¯3317298.117 

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.