Nhân tứ


13

Viết hàm hoặc chương trình được đặt tên để tính sản phẩm bậc bốn của hai bậc bốn. Sử dụng càng ít byte càng tốt.

Đệ tứ

Đệ tứ là một phần mở rộng của các số thực tiếp tục mở rộng các số phức. Thay vì một đơn vị tưởng tượng duy nhất i, tứ phương sử dụng ba đơn vị tưởng tượng i,j,kthỏa mãn các mối quan hệ.

i*i = j*j = k*k = -1
i*j =  k
j*i = -k
j*k =  i
k*j = -i
k*i =  j
i*k = -j

(Ngoài ra còn có các bảng này trên trang Wikipedia .)

Nói cách khác, mỗi đơn vị tưởng tượng bình phương -1và tích của hai đơn vị tưởng tượng khác nhau là đơn vị thứ ba còn lại với +/-tùy thuộc vào thứ tự tuần hoàn (i,j,k)có được tôn trọng hay không (nghĩa là quy tắc bàn tay phải ). Vì vậy, thứ tự của vấn đề nhân.

Một tứ phân vị chung là sự kết hợp tuyến tính của một phần thực và ba đơn vị tưởng tượng. Vì vậy, nó được mô tả bởi bốn số thực (a,b,c,d).

x = a + b*i + c*j + d*k

Vì vậy, chúng ta có thể nhân hai bậc bốn bằng cách sử dụng thuộc tính phân phối, cẩn thận để nhân các đơn vị theo đúng thứ tự và nhóm như các điều khoản trong kết quả.

(a + b*i + c*j + d*k) * (e + f*i + g*j + h*k)
= (a*e - b*f - c*g - d*h)    +
  (a*f + b*e + c*h - d*g)*i  +
  (a*g - b*h + c*e + d*f)*j  +
  (a*h + b*g - c*f + d*e)*k

Nhìn theo cách này, phép nhân bậc bốn có thể được xem như một bản đồ từ một cặp 4-tup đến một 4-tuple duy nhất, đó là những gì bạn được yêu cầu thực hiện.

định dạng

Bạn nên viết một chương trình hoặc chức năng được đặt tên . Một chương trình nên lấy đầu vào từ STDIN và in ra kết quả. Một chức năng sẽ nhận đầu vào chức năng và trả lại (không in) một đầu ra.

Định dạng đầu vào và đầu ra là linh hoạt. Đầu vào là tám số thực (hệ số của hai bậc bốn) và đầu ra bao gồm bốn số thực. Đầu vào có thể là tám số, hai danh sách bốn số, ma trận 2x4, v.v ... Định dạng đầu vào / đầu ra không nhất thiết phải giống nhau. Thứ tự các (1,i,j,k)hệ số là tùy thuộc vào bạn.

Các hệ số có thể âm hoặc không toàn bộ. Đừng lo lắng về độ chính xác thực sự hoặc tràn.

Cấm: Chức năng hoặc các loại đặc biệt cho bậc bốn hoặc tương đương.

Các trường hợp thử nghiệm

Đây là ở (1,i,j,k)định dạng hệ số.

[[12, 54, -2, 23], [1, 4, 6, -2]] 
 [-146, -32, 270, 331]

[[1, 4, 6, -2], [12, 54, -2, 23]] 
 [-146, 236, -130, -333]

[[3.5, 4.6, -0.24, 0], [2.1, -3, -4.3, -12]] 
 [20.118, 2.04, 39.646, -62.5]

Thực hiện tham khảo

Trong Python, dưới dạng hàm:

#Input quaternions: [a,b,c,d], [e,f,g,h]
#Coeff order: [1,i,j,k]

def mult(a,b,c,d,e,f,g,h):
    coeff_1 = a*e-b*f-c*g-d*h
    coeff_i = a*f+b*e+c*h-d*g
    coeff_j = a*g-b*h+c*e+d*f
    coeff_k = a*h+b*g-c*f+d*e

    result = [coeff_1, coeff_i, coeff_j, coeff_k]
    return result

Câu trả lời:


4

CJam, 49 45 39 byte

"cM-^\M-^G-^^KM-zP"256bGbq~m*f{=:*}4/{:-W*}/W*]`

Ở trên sử dụng ký hiệu caret và M, vì mã chứa các ký tự không thể in được.

Với chi phí của hai byte bổ sung, những ký tự đó có thể tránh được:

6Z9C8 7YDXE4BFA5U]q~m*f{=:*}4/{:-W*}/W*]`

Bạn có thể dùng thử phiên bản trực tuyến này: phiên dịch viên CJam

Các trường hợp thử nghiệm

Để tính toán (a + bi + cj + dk) * (e + fi + gj + hk), sử dụng đầu vào sau:

[ d c b a ] [ h g f e ]

Đầu ra sẽ là

[ z y x w ]

tương ứng với tứ phương w + xi + yj + zk.

$ base64 -d > product.cjam <<< ImOchy0eS/pQIjI1NmJHYnF+bSpmez06Kn00L3s6LVcqfS9XKl1g
$ wc -c product.cjam
39 product.cjam
$ LANG=en_US cjam product.cjam <<< "[23 -2 54 12] [-2 6 4 1]"; echo
[331 270 -32 -146]
$ LANG=en_US cjam product.cjam <<< "[-2 6 4 1] [23 -2 54 12]"; echo
[-333 -130 236 -146]
$ LANG=en_US cjam product.cjam <<< "[0 -0.24 4.6 3.5] [-12 -4.3 -3 2.1]"; echo
[-62.5 39.646 2.04 20.118]

Làm thế nào nó hoạt động

6Z9C8 7YDXE4BFA5U]  " Push the array [ 6 3 9 12 8 7 2 13 1 14 4 11 15 10 5 0].         ";
q~                  " Read from STDIN and interpret the input.                         ";
m*                  " Compute the cartesian product of the input arrays.               ";
f                   " Execute the following for each element of the first array:       ";
{                   " Push the cartesian product (implicit).                           ";
    =               " Retrieve the corresponding pair of coefficients.                 ";
    :*              " Calculate their product.                                         ";
}                   "                                                                  ";
4/                  " Split into chunks of 4 elements.                                 ";
{:-W*}/             " For each, subtract the first element from the sum of the others. ";
W*                  " Multiply the last integers (coefficient of 1) by -1.             ";
]`                  " Collect the results into an array and stringify it.              ";

6

Con trăn (83)

r=lambda A,B,R=range(4):[sum(A[m]*B[m^p]*(-1)**(14672>>p+4*m)for m in R)for p in R]

Đưa hai danh sách A,Btheo [1,i,j,k]thứ tự và trả về một kết quả ở cùng định dạng.

Ý tưởng chính là với [1,i,j,k]tương ứng với các chỉ số [0,1,2,3], bạn có được chỉ số của sản phẩm (tối đa ký) bằng cách XOR'ing các chỉ số. Vì vậy, các thuật ngữ được đặt trong chỉ mục plà những người chỉ định XOR pvà do đó là các sản phẩm A[m]*B[m^p].

Nó chỉ còn lại để làm cho các dấu hiệu làm việc ra. Cách ngắn nhất tôi tìm thấy là chỉ cần mã hóa chúng thành một chuỗi ma thuật. 16 khả năng (m,p)được biến thành con số 0để 15làm p+4*m. Số 14672trong nhị phân có 1tại những nơi -1cần có dấu hiệu. Bằng cách chuyển nó số lượng thích hợp các địa điểm, một 1hoặc 0gió lên ở các chữ số cuối cùng, làm cho số lẻ hoặc thậm chí, và vì vậy (-1)**là một trong hai 1hoặc -1khi cần thiết.


Phần XOR là thiên tài thuần túy.
Dennis

3

Con trăn - 90 75 72 69

Python thuần túy, không có thư viện - 90:

m=lambda a,b,c,d,e,f,g,h:[a*e-b*f-c*g-d*h,a*f+b*e+c*h-d*g,a*g-b*h+c*e+d*f,a*h+b*g-c*f+d*e]

Có lẽ khá khó để rút ngắn giải pháp "mặc định" này trong Python. Nhưng tôi rất tò mò về những gì người khác có thể nghĩ ra. :)


Sử dụng NumPy - 75 72 69:

Chà, vì đầu vào và đầu ra khá linh hoạt, chúng ta có thể sử dụng một số hàm NumPy và khai thác biểu diễn vectơ vô hướng :

import numpy
m=lambda s,p,t,q:[s*t-sum(p*q),s*q+t*p+numpy.cross(p,q)]

Đối số đầu vào stlà phần vô hướng của hai phần tử (phần thực) pqlà phần vectơ tương ứng (đơn vị tưởng tượng). Đầu ra là một danh sách chứa phần vô hướng và phần vectơ của bậc bốn kết quả, phần sau được biểu diễn dưới dạng mảng NumPy.

Kịch bản kiểm tra đơn giản:

for i in range(5):
    a,b,c,d,e,f,g,h=np.random.randn(8)
    s,p,t,q=a, np.array([b, c, d]), e, np.array([f, g, h])
    print mult(a, b, c, d, e, f, g, h), "\n", m(s,p,t,q)

( mult(...)là triển khai tham chiếu của OP.)

Đầu ra:

[1.1564241702553644, 0.51859264077125156, 2.5839001110572792, 1.2010364098925583] 
[1.1564241702553644, array([ 0.51859264,  2.58390011,  1.20103641])]
[-1.8892934508324888, 1.5690229769129256, 3.5520713781125863, 1.455726589916204] 
[-1.889293450832489, array([ 1.56902298,  3.55207138,  1.45572659])]
[-0.72875976923685226, -0.69631848934167684, 0.77897519489219036, 1.4024428845608419] 
[-0.72875976923685226, array([-0.69631849,  0.77897519,  1.40244288])]
[-0.83690812141836401, -6.5476014589535243, 0.29693969165495304, 1.7810682337361325] 
[-0.8369081214183639, array([-6.54760146,  0.29693969,  1.78106823])]
[-1.1284033842268242, 1.4038096725834259, -0.12599103441714574, -0.5233468317643214] 
[-1.1284033842268244, array([ 1.40380967, -0.12599103, -0.52334683])]

2

Haskell, 85

m a b c d e f g h=[a*e-b*f-c*g-d*h,a*f+b*e+c*h-d*g,a*g-b*h+c*e+d*f,a*h+b*g-c*f+d*e]

Chuyển nó đến Haskell giúp chúng ta tiết kiệm một vài ký tự;)


2

Toán học 83 50

Có lẽ có thể được chơi golf nhiều hơn ..

p = Permutations;
f = #1.(Join[{{1, 1, 1, 1}}, p[{-1, 1, -1, 1}][[1 ;; 3]]] p[#2][[{1, 8, 17, 24}]]) &

Không gian và dòng mới không được tính và không cần thiết.

Sử dụng:

f[{a,b,c,d},{e,f,g,h}]        (* => {x,w,y,z}   *)


EDIT Làm thế nào điều này hoạt động.

Hàm Mathicala Permutationslàm cho tất cả các hoán vị có thể có của #2(đối số thứ hai). Có 24 hoán vị, nhưng chúng ta chỉ cần {e,f,g,h}, {f,e,h,g}, {g,h,e,f}, và {h,g,f,e}. Đây là các hoán vị đầu tiên, 8, 17 và 24. Mã vậy

p[#2][[{1,8,17,24}]]

chính xác chọn chúng từ các hoán vị của đối số thứ hai và trả về chúng dưới dạng ma trận. Nhưng sau đó họ chưa có dấu hiệu chính xác. Mã p[{-1,1,-1,1}][[1;;3]]trả về một ma trận 3x4 với dấu chính xác. Chúng tôi chuẩn bị trước {1,1,1,1}bằng cách sử dụng Joinvà tạo một phép nhân bình thường ( Timeshoặc như trường hợp ở đây bằng cách chỉ viết chúng sau nhau) giữa hai ma trận tạo ra phép nhân từng yếu tố trong Mathicala.

Cuối cùng, kết quả của

(Join[{{1, 1, 1, 1}}, p[{-1, 1, -1, 1}][[1 ;; 3]]] p[#2][[{1, 8, 17, 24}]])

là ma trận

 e  f  g  h
-f  e -h  g
-g  h  e -f
-h -g  f  e

Tạo một ma trận nhân giữa {a,b,c,d}(đối số đầu tiên #1) và ma trận cũ cho kết quả mong muốn.



EDIT 2 Mã ngắn hơn

Lấy cảm hứng từ mã Python của Falko, tôi chia ra phần tư trong một phần vô hướng và một phần vectơ, và sử dụng lệnh được xây dựng trong Mathicala Crossđể tính toán sản phẩm chéo của các phần vectơ:

f[a_, A_, b_, B_] := Join[{a*b - A.B}, a*B + b*A + Cross[A, B]]

Sử dụng:

f[a,{b,c,d},e,{f,g,h}]        (* => {x,w,y,z}   *)

Bạn có thể giải thích làm thế nào điều này hoạt động? Là 1, 8, 17, 24
xnor

1

Con trăn, 94

Cách đơn giản nhất không quá dài.

def m(a,b,c,d,e,f,g,h):return[a*e-b*f-c*g-d*h,a*f+b*e+c*h-d*g,a*g-b*h+c*e+d*f,a*h+b*g-c*f+d*e]

1

JavaScript ES6 - 86

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

1

Lua - 99

Có thể là tốt.

_,a,b,c,d,e,f,g,h=unpack(arg)print(a*e-b*f-c*g-d*h,a*f+b*e+c*h-d*g,a*g-b*h+c*e+d*f,a*h+b*g-c*f+d*e)

"Unpack ()" của Lua giải phóng các phần tử của bảng. Vì vậy, bảng 'arg' là nơi lưu trữ tất cả các đầu vào dòng lệnh (bao gồm cả arg[0]tên tệp của chương trình, nó sẽ bị loại bỏ).


1

Python, 58 56 ký tự

m=lambda x,y,z,w:(x*z-y*(2*w.real-w),x*w+y*(2*z.real-z))

Tôi sử dụng rất tự do của phòng ngọ nguậy định dạng đầu vào / đầu ra. Các đầu vào là 4 số phức, được mã hóa như vậy:

x = a+b*i
y = c+d*i
z = e+f*i
w = g+h*i

Nó xuất ra một cặp số phức theo định dạng tương tự, đầu tiên của cặp mã hóa phần thực và iphần, phần thứ hai mã hóa phần jkphần.

Để xem điều này hoạt động, lưu ý rằng tứ đầu tiên là x+y*jvà thứ hai là z+w*j. Chỉ cần đánh giá (x+y*j)*(z+w*j)và nhận ra rằng j*t= conj(t)*jcho bất kỳ số ảo t.


Rất thông minh! Bạn có biết tại sao các bậc bốn dường như nhân lên như các số phức với các hệ số phức, vì nó nhìn từ biểu thức của bạn không?
xnor

Không sao, bây giờ tôi hiểu từ giải thích của bạn như thế nào ijhành động như các hệ số phức tạp bên trong và bên ngoài. Thật hấp dẫn làm sao!
xnor

Thật buồn cười khi các cuộc gọi liên kết chiếm hơn 2/5 số ký tự của bạn. Tôi nghĩ rằng bạn có thể cạo một char mỗi sử dụng (2*w.real-w). abs(w)**2/wsẽ làm việc nhưng với 0. Có lẽ ngay cả thực hiện với thay thế chuỗi sẽ có giá trị nó? `
xnor

1

Thì thầm v2 , 396 byte

> 1
> 2
> 0
> 4
> Input
> Input
>> 6ᶠ2
>> 6ᵗ2
>> 7ⁿ3
>> 7ⁿ1
>> 10‖9
>> 8ⁿ3
>> 8ⁿ1
>> 13‖12
>> 7‖8
>> 11‖14
>> 8‖7
>> 14‖11
>> 15‖16
>> 19‖17
>> 20‖18
>> 4⋅5
>> L⋅R
>> Each 23 22 21
> [1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1]
>> Each 23 24 25
>> 26ᶠ4
>> 26ᵗ4
>> 28ᶠ4
> 8
>> 26ᵗ30
>> 31ᶠ4
>> 31ᵗ4
>> ∑27
>> ∑29
>> ∑32
>> ∑33
>> Output 34 35 36 37

Hãy thử trực tuyến!

Đưa đầu vào theo mẫu

[a, b, c, d]
[e, f, g, h]

và đầu ra như

w
x
y
z

q= =w+xTôi+yj+zk

Cây cấu trúc của câu trả lời này là:

cây

Một đoạn hay của câu trả lời này đến từ hai lỗi chính trong Whispers:

  • Không có chức năng đảo ngược một mảng
  • Việc sử dụng các bộ trong tính toán của sản phẩm Cartesian

Do đó, chúng ta có thể chia mã thành 3 phần.

Làm thế nào nó hoạt động

Chúng tôi sẽ sử dụng các định nghĩa sau đây cho rõ ràng và cụ thể:

q= =một+bTôi+cj+dk
p= =e+fTôi+gj+hk
r= =w+xTôi+yj+zk,(qp= =r)
Một= =[một,b,c,d]
B= =[e,f,g,h]
C= =[w,x,y,z]

MộtB

Phần đầu tiên dài nhất, kéo dài từ dòng 1 đến dòng 22 :

> 1
> 2
> 0
> 4
> Input
> Input
>> 6ᶠ2
>> 6ᵗ2
>> 7ⁿ3
>> 7ⁿ1
>> 10‖9
>> 8ⁿ3
>> 8ⁿ1
>> 13‖12
>> 7‖8
>> 11‖14
>> 8‖7
>> 14‖11
>> 15‖16
>> 19‖17
>> 20‖18
>> 4⋅5

BMộtBBMột

B1= =[e,f,g,h]
B2= =[f,e,h,g]
B3= =[g,h,e,f]
B4= =[h,g,f,e]

BBBB2B4

>> 7ⁿ3
>> 7ⁿ1
>> 10‖9

[f,e]

>> 8ⁿ3
>> 8ⁿ1
>> 13‖12

[h,g]B1,B2,B3B4BTMộtTMột4

MộtT= =[một,b,c,d,một,b,c,d,một,b,c,d,một,b,c,d]
BT= =[e,f,g,h,f,e,h,g,g,h,e,f,h,g,f,e]

BTMộtTqp

Mục 2: Dấu hiệu và sản phẩm

MộtTBTqp

> [1,-1,-1,-1,1,1,1,-1,1,-1,1,1,1,1,-1,1]

Chúng tôi sẽ gọi mảng này là S (dấu hiệu). Tiếp theo, chúng tôi nén lại từng phần tử trong MộtT,BTS và lấy sản phẩm của từng mảng con, ví dụ: [[một,e,1],[b,f,-1],Giáo dục,[e,f,-1],[d,e,1]]D= =[mộte,-bf,Giáo dục,-ef,de]

Phần 3: Phân chia và số tiền cuối cùng.

qpqp

> 4

đến dòng 4 chứ không phải 2654DD

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.