Kết hợp rời rạc hoặc nhân đa thức


19

Đưa ra hai danh sách số nguyên không trống , bài nộp của bạn sẽ tính toán và trả về tích chập riêng của hai số nguyên. Thật thú vị, nếu bạn coi các yếu tố danh sách là hệ số của đa thức, thì tích chập của hai danh sách đại diện cho hệ số của sản phẩm của hai đa thức.

Định nghĩa

Đưa ra các danh sách A=[a(0),a(1),a(2),...,a(n)]B=[b(0),b(1),b(2),...,b(m)](cài đặt a(k)=0 for k<0 and k>nb(k)=0 for k<0 and k>m) sau đó tích chập của hai được xác định là A*B=[c(0),c(1),...,c(m+n)]nơic(k) = sum [ a(x)*b(y) for all integers x y such that x+y=k]

Quy tắc

  • Bất kỳ định dạng đầu vào và đầu ra thuận tiện cho ngôn ngữ của bạn đều được cho phép.
  • Không được phép xây dựng để tích chập, tạo ma trận tích chập, tương quan và nhân đa thức.

Ví dụ

[1,1]*[1] = [1,1]
[1,1]*[1,1] = [1,2,1]
[1,1]*[1,2,1] = [1,3,3,1]
[1,1]*[1,3,3,1] = [1,4,6,4,1]
[1,1]*[1,4,6,4,1] = [1,5,10,10,5,1]

[1,-1]*[1,1,1,1,1] = [1,0,0,0,0,-1]
[80085,1337]*[-24319,406] = [-1947587115,7,542822]

3
Thông số kỹ thuật ngụ ý rằng các đầu vào có độ dài n, m sẽ tạo ra đầu ra có độ dài n + m - 1, nhưng điều này không giữ cho trường hợp thử nghiệm của bạn [1,1]*[] = []và không thể giữ được []*[] = ?. Convolution không được xác định rõ trong danh sách trống. Tôi nghĩ bạn nên đảm bảo rằng danh sách đầu vào là không trống.
Anders Kaseorg

1
@AndersKaseorg Bạn nói đúng, tôi sẽ thay đổi điều đó.
flawr

Câu trả lời:


14

J, 10 8 byte

[:+//.*/

Sử dụng:

ppc =: [:+//.*/    NB. polynomial product coefficients 
80085 1337 ppc _24319 406
_1947587115 7 542822

Mô tả: Chương trình lấy hai danh sách, tạo bảng nhân, sau đó thêm các số trên các đường chéo dương.


Cách tiếp cận rất thông minh!
Luis Mendo

Bạn không cần phải đếm dấu ngoặc đơn. Biểu thức bên trong chúng ước tính cho một động từ ngầm, có thể được gán cho một biến.
Dennis

Ví dụ tuyệt vời của trạng từ!
dặm

6

MATL , 19 byte

PiYdt"TF2&YStpsw]xx

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

Giải trình

Điều này xây dựng một ma trận khối chéo với hai đầu vào, đảo ngược đầu tiên. Ví dụ, với đầu vào [1 4 3 5], [1 3 2]ma trận là

[ 5 3 4 1 0 0 0
  0 0 0 0 1 3 2 ]

Mỗi mục của tích chập thu được bằng cách dịch chuyển vị trí của hàng đầu tiên sang phải, tính toán sản phẩm của mỗi cột và tổng hợp tất cả các kết quả.

Về nguyên tắc, việc chuyển đổi nên được thực hiện đệm với các số không từ bên trái. Tương tự, dịch chuyển tròn có thể được sử dụng, bởi vì ma trận chứa các số không tại các mục thích hợp.

Ví dụ: kết quả đầu tiên thu được từ ma trận đã dịch chuyển

[ 0 5 3 4 1 0 0
  0 0 0 0 1 3 2 ]

và là như vậy 1*1 == 1. Thứ hai được lấy từ

[ 0 0 5 3 4 1 0
  0 0 0 0 1 3 2 ]

và do đó 4*1+1*3 == 7, vv Điều này phải được thực hiện m+n-1lần, trong đó mnlà độ dài đầu vào. Mã này sử dụng một vòng lặp với các m+nlần lặp (giúp lưu một số byte) và loại bỏ kết quả cuối cùng.

P          % Take first input (numeric vactor) implicitly and reverse it
i          % Take second input (numeric vactor) 
Yd         % Build diagonal matrix with the two vectors
t          % Duplicate
"          % For each column of the matrix
  TF2&YS   %   Circularly shift first row 1 step to the right
  t        %   Duplicate
  p        %   Product of each column
  s        %   Sum all those products
  w        %   Swap top two elements in stack. The shifted matrix is left on top
]          % End for
xx         % Delete matrix and last result. Implicitly display

4

Haskell, 55 49 byte

(a:b)#c=zipWith(+)(0:b#c)$map(a*)c++[]#b
_#c=0<$c

Xác định một toán tử #.


1
Tôi nghĩ phần đệm [0,0..]có thể (0<$b)cho chính xác độ dài cần thiết, cho phép trường hợp cơ sở trống _#b=0<$b.
xnor

@xnor Thật vậy, tiết kiệm được 6 byte.
Anders Kaseorg 17/05/2016

Bây giờ tôi cuối cùng đã hiểu câu trả lời của bạn, tôi phải nói rằng điều này thật quá thông minh! Tôi rất ấn tượng!
flawr

3

Matlab / Octave, 41 byte

@(p,q)poly([roots(p);roots(q)])*p(1)*q(1)

Điều này xác định một chức năng ẩn danh. Để gọi nó, gán nó cho một biến hoặc sử dụng ans.

Hãy thử nó ở đây .

Giải trình

Điều này khai thác sự thật rằng

  • Rễ (có thể lặp đi lặp lại) đặc trưng cho một đa thức lên đến hệ số dẫn đầu của nó.
  • Tích của hai đa thức có gốc của cả hai.

Mã này tính toán các gốc của hai đa thức (hàm roots) và ghép chúng thành một mảng cột. Từ đó nó thu được các hệ số của đa thức sản phẩm với một 1hàm (hàm poly) hàng đầu . Cuối cùng, kết quả được nhân với các hệ số hàng đầu của hai đa thức.


3

Octave , 48 byte

@(p,q)ifft(fft([p q*0]).*fft([q p*0]))(1:end-1)

Hãy thử nó ở đây .

Giải trình

Tích chập rời rạc tương ứng với phép nhân biến đổi Fourier (thời gian rời rạc). Vì vậy, một cách để nhân các đa thức sẽ biến đổi chúng, nhân các chuỗi biến đổi và biến đổi trở lại.

Nếu biến đổi Fourier rời rạc (DFT) được sử dụng thay cho biến đổi Fourier, kết quả là tích chập tuần hoàn của các chuỗi gốc của các hệ số đa thức. Mã theo lộ trình này. Để thực hiện tích chập tròn bằng tích chập tiêu chuẩn, các chuỗi được đệm bằng 0 và kết quả được cắt bớt.


Chết tiệt, tôi vẫn có thể cấm fft, nhưng làm tốt lắm!
flawr

@flawr Vâng, tôi nghĩ chúng ta đã nói về điều đó ...? :-P
Luis Mendo

2

05AB1E , 18 17 byte

0Ev²¹g<Å0«y*NFÁ}+

Giải trình

Lý thuyết đằng sau:

Để tìm tích chập, hãy lấy ví dụ [1, 2, 3], [3, 4, 5]. Chúng tôi định vị các giá trị của mảng đầu tiên lộn ngược và theo chiều dọc, như thế này:

3
2
1

Bây giờ, chúng ta đặt mảng thứ hai giống như một cái thang và nhân nó với:

3 ×       [3  4  5]
2 ×    [3  4  5]
1 × [3  4  5]

Kết quả là:

        9   12   15
    6   8   10
3   4   5

Sau đó, chúng tôi thêm chúng lên, kết quả là:

        9   12   15
    6   8   10
3   4   5       

3   10  22  22   15

Vì vậy, tích chập là [3, 10, 22, 22, 15].

Bản thân mã:

Chúng tôi sẽ làm điều này từng bước bằng cách sử dụng [1, 2, 3], [3, 4, 5]như trường hợp thử nghiệm.

0Ev²¹g<Å0«y*NFÁ}+

Chúng tôi đẩy đầu tiên 0và sau đó chúng tôi Eđịnh giá mảng đầu vào đầu tiên. Chúng tôi ánh xạ qua từng yếu tố bằng cách sử dụng v.

Vì vậy, đối với mỗi phần tử, chúng ta đẩy mảng thứ hai bằng ²và sau đó độ dài của mảng thứ nhất bằng cách sử dụng ¹gvà giảm giá trị này đi 1 (với <). Chúng tôi chuyển đổi danh sách này thành một danh sách các số không với (các mảng 1 - chiều dài 1) , sử dụng Å0và nối nó vào danh sách của chúng tôi. Ngăn xếp của chúng tôi bây giờ trông như thế này cho mục đầu tiên trong danh sách đầu vào:

[3, 4, 5, 0, 0]

Chúng tôi nhân mảng này với mục hiện tại, được thực hiện với y*. Sau đó, chúng tôi đẩy N, chỉ ra chỉ mục của mục hiện tại (không có chỉ mục) và xoay mảng nhiều lần sang bên phải bằng cách sử dụng FÁ}. Cuối cùng, chúng tôi thêm giá trị này vào giá trị ban đầu của chúng tôi ( 0). Vì vậy, những gì cơ bản được thực hiện là như sau:

[0, 0, 9, 12, 15] +
[0, 6, 8, 10, 0] +
[3, 4, 5, 0, 0] =

[3, 10, 22, 22, 15]

Mà sau đó được in ngầm. Sử dụng mã hóa CP-1252 . Hãy thử trực tuyến! .


2

Thạch , 9 byte

0;+
×'Ṛç/

Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

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

×'Ṛç/  Main link. Arguments: p, q (lists)

×'     Spawned multiplication; multiply each item of p with each item of q.
  Ṛ    Reverse the rows of the result.
   ç/  Reduce the rows by the helper link.


0;+    Helper link. Arguments: p, q (lists)

0;     Prepend a 0 to p.
  +    Perform vectorized addition of the result and q.

Định nghĩa gì lâu hơn J‽ Điều đó là không thể!
Adám

2

Husk , 5 byte

mΣ∂Ṫ*

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

Lưu ý: Khi cung cấp danh sách không đa thức / trống, bạn cần chỉ định loại của nó (tức là. []:LN)!

Giải trình

mΣ∂Ṫ*  -- implicit inputs xs ys, for example: [1,-1] [1,1]
   Ṫ*  -- compute the outer product xsᵀ·ys: [[1,1],[-1,-1]]
  ∂    -- diagonals: [[1],[1,-1],[-1]]
mΣ     -- map sum: [1,0,1]

2

Matlab, 33 byte

@(x,y)sum(spdiags(flip(x').*y),1)

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

Tạo một ma trận của tất cả các sản phẩm có yếu tố thông minh của các yếu tố đầu vào, sau đó tính tổng theo các đường chéo. Các ,1tại các lực lượng cuối MATLAB để tổng hợp theo hướng đúng khi một trong số các vectơ đầu vào có chiều dài 1.

Trong Octave spdiagskhông hoạt động đối với vectơ, dẫn đến lỗi khi một trong các đầu vào có độ dài 1. Matlab 2016b hoặc mới hơn được yêu cầu để mở rộng rõ ràng sản phẩm thông minh phần tử.


Cách tiếp cận tốt đẹp !!
Luis Mendo


1

Python, 90 byte

lambda p,q:[sum((p+k*[0])[i]*(q+k*[0])[k-i]for i in range(k+1))for k in range(len(p+q)-1)]

1

JavaScript (ES6), 64 byte

(a,b)=>a.map((n,i)=>b.map((m,j)=>r[j+=i]=m*n+(r[j]||0)),r=[])&&r

Trả về mảng trống nếu đầu vào trống. Dựa trên câu trả lời của tôi cho đa thức .



1

Clojure, 104 byte

#(vals(apply merge-with +(sorted-map)(for[i(range(count %))j(range(count %2))]{(+ i j)(*(% i)(%2 j))})))

Hợp nhất để sorted-mapđảm bảo rằng các giá trị được trả về theo đúng thứ tự. Tôi muốn có thêm một vài trường hợp thử nghiệm.

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.