교차 제품 찾기


20

두 개의 3 차원 벡터 와 의 교차 곱은 과 같은 고유 벡터 입니다.abc

  • ca \ vec b 모두에 직교합니다.b

  • c 의 크기는 \ a\ vec b에 의해 형성된 평행 사변형의 면적과 같습니다.b

  • 의 방향 a , bc , 그 순서는 다음과 오른손 법칙을 .

교차 곱에 대한 몇 가지 동등한 수식이 있지만 그 중 하나는 다음과 같습니다.

a×b=det[ijka1a2a3b1b2b3]

여기서 i , jk 는 1 차원, 2 차원 및 3 차원의 단위 벡터입니다.

도전

두 개의 3D 벡터가 주어지면 교차 곱을 찾기위한 전체 프로그램이나 함수를 작성하십시오. 교차 곱을 구체적으로 계산하는 빌트인은 허용되지 않습니다.

입력

각각 3 개의 실수로 구성된 2 개의 배열. 언어에 배열이없는 경우 숫자를 여전히 3으로 그룹화해야합니다. 두 벡터의 크기는 <216 입니다. 교차 곱은 비 a×b=(b×a) )이므로 순서를 지정하는 방법이 있어야합니다.

산출

각각의 구성 요소가 4 개의 유효 숫자 또는 104 중 더 느슨한쪽에 정확한 형식의 교차 제품 입니다. 과학적 표기법은 선택 사항입니다.

테스트 사례

[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]

이것은 이므로 바이트 단위의 최단 솔루션이 이깁니다.

Maltysen도 비슷한 도전을 게시 했지만 답변이 좋지 않았으며 질문이 수정되지 않았습니다.


입력을 2D 배열로 가져올 수 있습니까?
Dennis

예, 2가 외부 치수 인 한
lirtosiast

답변:


14

젤리, 14 13 12 바이트

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

온라인으로 사용해보십시오!

작동 원리

;"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).

비경쟁 버전 (10 바이트)

자, 이것은 당황 스럽지만 배열 조작 언어 인 Jelly는 지금까지 배열 회전을위한 내장 기능을 가지고 있지 않았습니다. 이 새로운 내장 기능으로 2 바이트를 더 절약 할 수 있습니다.

ṙ-×
ç_ç@ṙ-

이것은 @ AlexA. 's J answer의 접근 방식을 사용합니다 . 온라인으로 사용해보십시오!

작동 원리

ṙ-×     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).

기본 -1에서 각 쌍을 변환 하시겠습니까? 그것은 단지 악입니다. +1
ETHproductions

10

LISP, 128 122 바이트

안녕! 이것은 내 코드입니다.

(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)))

나는 그것이 가장 짧은 해결책은 아니지만 지금까지 아무도 Lisp에 하나를 제공하지 않았다는 것을 알고있다 :)

다음 코드를 복사하여 붙여 여기에 그것을 시도!

(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)))

프로그래밍 퍼즐 및 코드 골프 스택 교환에 오신 것을 환영합니다. 이것은 좋은 대답입니다, +1. 이길 수없는 언어로 대답하기는했지만 여전히 골프를 치고 있습니다. 종종 코드 골프 문제는 언어 간 문제보다 언어 내에서 더 중요합니다!
wizzwizz4

9

Dyalog APL, 12 바이트

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

를 기반으로 알렉사.의 J 응답 @ 그 대답의 코멘트 섹션에서 @ randomra의 개선과 (우연히)와 같습니다.

TryAPL에서 온라인으로 사용해보십시오 .

작동 원리

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 바이트

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

이것은 왼쪽과 오른쪽의 배열을 받아들이고 교차 곱을 반환하는 이완 동사입니다.

설명:

         *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

예:

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

여기 사용해보십시오

randomra 덕분에 13 바이트를 절약했습니다!


@randomra 감사합니다! 나는 J 전문가가 아니기 때문에 여전히 그것이 정확히 어떻게 작동하는지 파악하고 있지만 일반적인 아이디어가 있습니다.
Alex A.

몇 가지 설명 *2&|.은 다음 *과 같은 두 동사의 포크입니다 2&|.. 왼쪽 입력에 2 개의 오른쪽 입력을 곱한 값을 곱합니다. 이 포크에 저장 v우리는 물품 그래서 v~그것과 동등하다 (*2&|.)~, 여기서 ~괄호 부분에 대한 스왑 좌측 및 우측 입력 파라미터.
randomra

@randomra 알았어. 다시 감사합니다!
Alex A.

6

C, 156 154 150 148 144 바이트

#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]);}

오랫동안 상을 수상하지는 않았지만 어쨌든 갈 것이라고 생각했습니다.

  • 입력은 개행 문자 또는 공백으로 구분 된 구성 요소 목록 (예 : a1 a2 a3 b1 b2 b3)이며 출력은 공백으로 구분됩니다 (예 : c1 c2 c3).
  • 주기적으로 두 입력 벡터의 인덱스를 치환하여 곱을 계산합니다. 결정자를 쓰는 것보다 적은 문자를 사용합니다!

데모

언 골프 드 :

#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
프로그래밍 퍼즐 및 코드 골프 스택 교환에 오신 것을 환영합니다. 이것은 훌륭한 답변입니다. 골프 언어를 능가하지 않는 언어로 대답하기에 적합합니다. +1.
wizzwizz4

2
당신의 첫 번째 for는 필요하지 않습니다{}
제거

건배, 업데이트.
calvinsykes

1
& v [6-i]를 v + 6-i로 바꿀 수 있습니다. 또한 j = i % 3 및 k = (i + 1) % 3 뒤의 세미콜론을 쉼표로 바꿀 수 있습니다. 이렇게하면 단일 명령문 다음에 모든 것이 만들어 지므로 {}을 생략 할 수 있습니다. 마지막으로 두 번째 for 루프에 대해 i를 1로 초기화하면 증분을 k = ++ i % 3으로 이동하여 몇 개의 괄호를 절약 할 수 있습니다. 경고가 걱정되지 않고 올바른 버전의 C를 사용하는 경우 포함도 건너 뛸 수 있습니다.
Alchymist

굉장해, 건배! 내 컴파일러는 헤더 생략을 허용하지 않으므로 빌드 할 수있는 버전을 고수했습니다.
calvinsykes

4

하스켈, 41 바이트

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

간단한 솔루션.


4

배쉬 + 코어 유틸리티, 51

eval set {$1}*{$2}
bc<<<"scale=4;$6-$8;$7-$3;$2-$4"
  • 라인 1은 두 벡터의 데카르트 곱을 제공하고이를 위치 매개 변수로 설정하는 가새 확장을 구성합니다.
  • 2 행은 적절한 항을 뺍니다. bc필요한 정밀도로 산술 평가를 수행합니다.

입력은 명령 행에서 두 개의 쉼표로 구분 된 목록입니다. 줄 바꿈으로 구분 된 줄로 출력 :

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

4

MATL , 17 바이트

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

첫 번째 입력은 a 이고 두 번째 입력은 b 입니다.

온라인으로 사용해보십시오!

설명

!              % 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 바이트

-VF*VM.<VLQ_BMS2

온라인으로 사용해보십시오 : 데모

설명:

-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 바이트

꽤 오래 전에 이것을 작성하고 최근에 다시 먼지를 제거했습니다 .

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

실제로 :

 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

편집 1 :

두 개의 별도 인수 대신 입력 목록으로 입력하여 4 바이트를 절약했습니다.

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

편집 2 :

기본 디코딩으로 룩업 테이블을 계산하여 3 바이트를 절약했습니다.

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}

편집 3 :

로컬 람다 대신 암묵적 정의를 사용하도록 응용 프로그램을 재배치하여 5 바이트를 절약하십시오. 불행히도이 솔루션은 더 이상 oK에서 작동하지 않으며 공식 k5 인터프리터가 필요합니다. ok에서 버그를 고칠 때까지 내 말을 들어야합니다.

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

루비 , 49 바이트

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

온라인으로 사용해보십시오!

2 년 후, 루비가 음수 배열 인덱스를 처리하는 방식을 사용하여 12 바이트를 줄였습니다. -1배열의 마지막 요소이고 -2두 번째 마지막 요소입니다 .

루비, 57

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

테스트 프로그램에서

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

파이썬, 73 48 바이트

감사합니다 @FryAmTheEggman

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

이는 벡터 교차 곱의 구성 요소 정의를 기반으로합니다.

여기 사용해보십시오


lambda (a,b,c),(d,e,f):...많이 저장해야합니다.
FryAmTheEggman

@FryAmTheEggman 당신이 맞아요. 나는 람다가 인수가 어떻게되어야하는지 지정할 수 있다는 것을 잊었다.
TanMath

2

젤리 , 5 바이트

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

ṁ4ÆḊƝ

온라인으로 사용해보십시오!

다음은 SE 마크 다운에서 처리 할 수없는 경우 의 PDF 설명 입니다.


분석 형태의 교차 생성물

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

v1=x1i+y1j+z1k
v2=x2i+y2j+z2k

Oxyz

v1×v2=(x1i+y1j+z1k)×(x2i+y2j+z2k)

i×j=k,i×k=j,j×i=k,j×k=i,k×i=j,k×j=i

필요한 재배치 및 계산 후 :

v1×v2=(y1z2z1y2)i+(z1x2x1z2)j+(x1y2y1x2)k

행렬 결정자와 밀접한 관계

여기서 주목할만한 것이 있습니다.

x1y2y1x2=|x1y1 x2y2|
z1x2x1z2=|z1x1 z2x2|
y1z2z1y2=|y1z1 y2z2|

||

젤리 코드 설명

글쎄 ... 여기서 설명 할 것이 많지 않습니다. 그냥 행렬을 생성합니다.

(x1y1z1x1 x2y2z2x2)

그리고 각 인접 행렬 쌍에 대해 두 행렬을 결합하여 형성된 행렬의 행렬식을 계산합니다.

ṁ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 바이트

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

입력이 두 개의 배열이어야하는 경우 44 바이트 :

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

더 흥미로운 버전의 경우 52 바이트 :

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


0

APL (NARS), 23 자, 46 바이트

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

테스트:

  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 

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.