Nhân đa thức hai số nguyên


14

Nhiệm vụ của bạn là lấy hai biểu thức đa thức số nguyên một biến và nhân chúng vào khai triển mở rộng từ trái sang phải đầu tiên của chúng (AKA FOIL trong trường hợp nhị thức). Không kết hợp như các điều khoản hoặc sắp xếp lại kết quả. Để rõ ràng hơn về việc mở rộng, hãy nhân thuật ngữ đầu tiên trong biểu thức đầu tiên với mỗi thuật ngữ thứ hai, theo thứ tự và tiếp tục trong biểu thức đầu tiên cho đến khi tất cả các thuật ngữ đã được nhân với tất cả các thuật ngữ khác. Biểu thức sẽ được đưa ra trong một biến thể LaTeX đơn giản hóa.

Mỗi biểu thức sẽ là một chuỗi các thuật ngữ được phân tách bằng +(với chính xác một khoảng trắng ở mỗi bên) Mỗi ​​thuật ngữ sẽ tuân theo biểu thức chính quy sau: (ký hiệu PCRE)

-?\d+x\^\d+

Trong tiếng Anh đơn giản, thuật ngữ này là một tùy chọn hàng đầu -theo sau bởi một hoặc nhiều chữ số theo sau xvà một số nguyên không âm (có ^)

Một ví dụ về biểu thức đầy đủ:

6x^3 + 1337x^2 + -4x^1 + 2x^0

Khi cắm vào LaTeX, bạn nhận được6x3+1337x2+-4x1+2x0

Đầu ra cũng phải phù hợp với định dạng này.

Vì dấu ngoặc không bao quanh số mũ theo định dạng này, LaTeX thực sự sẽ hiển thị số mũ nhiều chữ số không chính xác. (ví dụ: 4x^3 + -2x^14 + 54x^28 + -4x^5hiển thị là ) Bạn không cần tính đến điều này và bạn không nên bao gồm dấu ngoặc trong đầu ra của mình.4x3+-2x14+54x2số 8+-4x5

Ví dụ trường hợp kiểm tra

5x^4
3x^23

15x^27

6x^2 + 7x^1 + -2x^0
1x^2 + -2x^3

6x^4 + -12x^5 + 7x^3 + -14x^4 + -2x^2 + 4x^3

3x^1 + 5x^2 + 2x^4 + 3x^0
3x^0

9x^1 + 15x^2 + 6x^4 + 9x^0

4x^3 + -2x^14 + 54x^28 + -4x^5
-0x^7

0x^10 + 0x^21 + 0x^35 + 0x^12

4x^3 + -2x^4 + 0x^255 + -4x^5
-3x^4 + 2x^2

-12x^7 + 8x^5 + 6x^8 + -4x^6 + 0x^259 + 0x^257 + 12x^9 + -8x^7

Quy tắc và giả định

  • Bạn có thể cho rằng tất cả các đầu vào phù hợp với định dạng chính xác này. Hành vi cho bất kỳ định dạng nào khác là không xác định cho các mục đích của thách thức này.
    • Cần lưu ý rằng bất kỳ phương pháp nào trong hai đa thức đều hợp lệ, miễn là cả hai đều được đọc dưới dạng các chuỗi tuân theo định dạng trên.
  • Thứ tự của các đa thức có vấn đề do thứ tự dự kiến ​​mở rộng sản phẩm.
  • Bạn phải hỗ trợ các hệ số đầu vào trong khoảng từ đến và số mũ đầu vào lên tới . -128127255
    • Coefficents đầu ra giữa và và mũ lên đến do đó phải được hỗ trợ.-16,25616,384510
  • Bạn có thể giả sử mỗi đa thức đầu vào chứa không quá 16 số hạng
    • Do đó, bạn phải (tối thiểu) hỗ trợ tối đa 256 điều khoản trong đầu ra
  • Các thuật ngữ có hệ số bằng 0 nên được giữ nguyên, với số mũ được kết hợp đúng
  • Số 0 âm được cho phép trong đầu vào, nhưng không thể phân biệt với số 0 dương về mặt ngữ nghĩa. Luôn luôn đầu ra dương. Đừng bỏ qua các điều khoản không.

Chúc bạn chơi golf vui vẻ! Chúc may mắn!



2
@LuisfelipeDejesusMunoz Tôi tưởng tượng không phải. Phân tích cú pháp là một phần không thể thiếu của thách thức và OP nói - "Cần lưu ý rằng bất kỳ phương pháp nào trong hai đa thức đều hợp lệ, miễn là cả hai đều được đọc dưới dạng các chuỗi tuân theo định dạng trên. " (Nhấn mạnh thêm)
Giuseppe

Câu trả lời:


4

R , 159 153 148 byte

function(P,Q,a=h(P),b=h(Q))paste0(b[1,]%o%a[1,],"x^",outer(b,a,"+")[2,,2,],collapse=" + ")
h=function(s,`/`=strsplit)sapply(el(s/" . ")/"x.",strtoi)

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

Tôi thực sự muốn sử dụng outer, vì vậy gần như chắc chắn có một cách tiếp cận hiệu quả hơn.


4

Haskell , 131 122 byte

(%)=drop
f s=do(a,t)<-reads s;(i,u)<-reads$2%t;(a,i):f(3%u)
p!q=3%do(a,i)<-f p;(b,j)<-f q;" + "++shows(a*b)"x^"++show(i+j)

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

fphân tích một đa thức từ một chuỗi, !nhân hai trong số chúng và định dạng kết quả.

H.PWiz đã lưu 9 byte. Cảm ơn!

Ung dung

type Monomial = (Int, Int) -- a^i
type Polynomial = [Monomial]

parse :: String -> Polynomial
parse s = do (a, s')  <- reads s
             (i, s'') <- reads (drop 2 s')
             (a, i) : parse (drop 3 s'')

(!) :: String -> String -> String
p!q = drop 3 (concat terms)
  where terms    = [term (a*b) (i+j) | (a,i) <- p', (b,j) <- q']
        term a i = concat [" + ", show a, "x^", show i]
        p'       = parse p
        q'       = parse q



2

Ruby , 102 100 98 byte

->a,b{a.scan(w=/(.*?)x.(\d+)/).map{|x|b.scan(w).map{|y|(eval"[%s*(z=%s;%s),z+%s]"%y+=x)*"x^"}}*?+}

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

Làm sao?

Bước đầu tiên: lấy tất cả các số từ cả hai đa thức: scantrả về các số dưới dạng một mảng các cặp chuỗi. Sau đó, làm một sản phẩm cartesian của 2 danh sách. Bây giờ chúng ta có tất cả các số mà chúng ta cần chúng, nhưng vẫn theo thứ tự sai.

Ví dụ: nếu chúng tôi nhân 3x^4với -5x^2, chúng tôi nhận được các số như [["3","4"],["-5","2"]], ý tưởng đầu tiên là nén và làm phẳng danh sách này, sau đó đặt các số vào một biểu thức để được đánh giá là [3*-5, 4+2]. Trên thực tế, chúng ta không cần phải sắp xếp lại các số, chúng ta có thể thực hiện nó bên trong biểu thức bằng cách sử dụng một biến tạm thời: biểu thức trở thành [3*(z=4,-5),z+2].

Sau khi đánh giá các biểu thức này, chúng ta có được hệ số và số mũ, chúng ta cần tham gia chúng bằng cách sử dụng "x^", và sau đó tham gia tất cả các giai điệu sử dụng "+".


2

Haskell, 124 121 byte

import Data.Lists
f!x=map f.splitOn x
z=read!"x^"!"+"
a#b=drop 3$do[u,v]<-z a;[p,q]<-z b;" + "++shows(u*p)"x^"++show(v+q)

Lưu ý: TIO thiếu Data.Lists, vì vậy tôi nhập Data.Lists.SplitData.List: Dùng thử trực tuyến!

Chỉnh sửa: -3 byte nhờ @Lynn.


Đây thực sự là 123 byte! f!x=map f.splitOn xvà sau đó z=read!"x^"!"+"lưu một byte; cho dòng cuối cùng drop 3$do[u,v]<-z a;[p,q]<-z b;" + "++shows(u*p)"x^"++show(v+q)tiết kiệm thêm hai. 120 byte
Lynn

1
@Lynn: phiên bản TIO nhập Data.Listthay vì Data.Lists, do đó là 1 byte.
nimi



1

Python 2 , 193 byte

import re
f=re.finditer
lambda a,b:' + '.join(' + '.join(`int(m.group(1))*int(n.group(1))`+'x^'+`int(m.group(2))+int(n.group(2))`for n in f('(-?\d+)x\^(\d+)',b))for m in f('(-?\d+)x\^(\d+)',a))

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

Lưu ý bên lề: Lần đầu tiên thực hiện một thử thách golf mã, rất xin lỗi nếu nỗ lực này haha


3
Chào mừng đến với PPCG! Tôi không phải là một lập trình viên trăn, nhưng có lẽ có một số chỗ cần cải thiện. Có lẽ bạn có thể tìm thấy trợ giúp tại Mẹo chơi gôn bằng Python hoặc Mẹo chơi gôn bằng <tất cả các ngôn ngữ> ! Hy vọng bạn tận hưởng thời gian bạn dành ở đây :-)
Giuseppe


1
Một số golf nhanh chóng cho 161 byte . Mặc dù nhìn vào các câu trả lời của con trăn khác, re.finditercó thể không phải là cách tiếp cận ngắn nhất
Jo King

1

Võng mạc , 110 byte

\S\S+(?=.*\n(.+))
 $1#$&
|" + "L$v` (-?)(\d+)x.(\d+).*?#(-?)(\d+)x.(\d+)
$1$4$.($2*$5*)x^$.($3*_$6*
--|-(0)
$1

Hãy thử trực tuyến! Giải trình:

\S\S+(?=.*\n(.+))
 $1#$&

Tiền tố mỗi thuật ngữ trong đầu vào đầu tiên với một #, một bản sao của đầu vào thứ hai và một khoảng trắng. Điều này có nghĩa là tất cả các điều khoản trong các bản sao của đầu vào thứ hai được đặt trước một khoảng trắng và không có thuật ngữ nào từ đầu vào đầu tiên.

|" + "L$v` (-?)(\d+)x.(\d+).*?#(-?)(\d+)x.(\d+)
$1$4$.($2*$5*)x^$.($3*_$6*

Khớp tất cả các bản sao của các điều khoản trong đầu vào thứ hai và thuật ngữ tương ứng của chúng từ đầu vào đầu tiên. Ghép bất kỳ -dấu hiệu nào , nhân các hệ số và thêm các chỉ số. Cuối cùng tham gia tất cả các thay thế kết quả với chuỗi  + .

--|-(0)
$1

Xóa mọi cặp -s và chuyển đổi -0thành 0.


1

SNOBOL4 (CSNOBOL4) , 192 176 byte

	P =INPUT
	Q =INPUT
	D =SPAN(-1234567890)
P	P D . K ARB D . W REM . P	:F(O)
	B =Q
B	B D . C ARB D . E REM . B	:F(P)
	O =O ' + ' K * C 'x^' W + E	:(B)
O	O ' + ' REM . OUTPUT
END

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

	P =INPUT				;* read P
	Q =INPUT				;* read Q
	D =SPAN(-1234567890)			;* save PATTERN for Digits (or a - sign); equivalent to [0-9\\-]+
P	P D . K ARB D . W REM . P	:F(O)	;* save the Koefficient and the poWer, saving the REMainder as P, or if no match, goto O
	B =Q					;* set B = Q
B	B D . C ARB D . E REM . B	:F(P)	;* save the Coefficient and the powEr, saving the REMainder as B, or if no match, goto P
	O =O ' + ' K * C 'x^' W + E	:(B)	;* accumulate the output
O	O ' + ' REM . OUTPUT			;* match ' + ' and OUTPUT the REMainder
END



1

C # (Trình biên dịch tương tác Visual C #) , 192 190 byte

n=>m=>string.Join(g=" + ",from a in n.Split(g)from b in m.Split(g)select f(a.Split(p="x^")[0])*f(b.Split(p)[0])+p+(f(a.Split(p)[1])+f(b.Split(p)[1])));Func<string,int>f=int.Parse;string p,g;

Cú pháp truy vấn dường như là một byte ngắn hơn cú pháp phương thức.

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


Mỗi biểu thức sẽ là một chuỗi các thuật ngữ được phân tách bằng + (với chính xác một khoảng trắng ở mỗi bên) 190 byte
Dữ liệu hết hạn vào

1

Thạch , 28 byte

ṣ”+ṣ”xV$€)p/ZPSƭ€j⁾x^Ʋ€j“ + 

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

Chương trình đầy đủ. Lấy hai đa thức là một danh sách của hai chuỗi.

Giải thích (hình thức mở rộng)

ṣ”+ṣ”xV$€µ€p/ZPSƭ€j⁾x^Ʋ€j“ + ” Arguments: x
         µ                     Monadic chain.
          €                    Map the monadic link over the argument.
                               Note that this will "pop" the previous chain, so
                               it will really act as a link rather than a
                               sub-chain.
ṣ”+                             ṣ, right = '+'.
                                Split the left argument on each occurrence of
                                the right.
                                Note that strings in Jelly are lists of
                                single-character Python strings.
        €                       Map the monadic link over the argument.
       $                         Make a non-niladic monadic chain of at least
                                 two links.
   ṣ”x                            ṣ, right = 'x'.
                                  Split the left argument on each occurrence of
                                  the right.
      V                           Evaluate the argument as a niladic link.
            /                  Reduce the dyadic link over the argument.
           p                    Cartesian product of left and right arguments.
                       €       Map the monadic link over the argument.
                      Ʋ         Make a non-niladic monadic chain of at least
                                four links.
             Z                   Transpose the argument.
                 €               Map the monadic link over the argument.
                ƭ                 At the first call, call the first link. At the
                                  second call, call the second link. Rinse and
                                  repeat.
              P                    Product: ;1×/$
               S                   Sum: ;0+/$
                  j⁾x^           j, right = "x^".
                                 Put the right argument between the left one's
                                 elements and concatenate the result.
                        j“ + ” j, right = " + ".
                               Put the right argument between the left one's
                               elements and concatenate the result.

Răng cưa

)cũng giống như µ€.
Một dấu được ngụ ý và có thể được bỏ qua.

Thuật toán

Giả sử chúng ta có đầu vào này:

["6x^2 + 7x^1 + -2x^0", "1x^2 + -2x^3"]

Quy trình đầu tiên là Phân tích cú pháp, áp dụng cho từng đa thức. Hãy xử lý cái đầu tiên , "6x^2 + 7x^1 + -2x^0":

Bước đầu tiên là phân tách chuỗi theo '+', để tách các điều khoản. Kết quả này trong:

["6x^2 ", " 7x^1 ", " -2x^0"]

Bước tiếp theo là chia từng chuỗi theo 'x', để tách hệ số khỏi số mũ. Kết quả là thế này:

[["6", "^2 "], [" 7", "^1 "], [" -2", "^0"]]

Hiện tại, có vẻ như có rất nhiều rác trong các chuỗi này, nhưng rác đó thực sự không quan trọng. Các chuỗi này sẽ được đánh giá là các liên kết Jelly niladic. Một cách tầm thường, các không gian là không quan trọng, vì chúng không nằm giữa các chữ số của các số. Vì vậy, chúng tôi cũng có thể đánh giá dưới đây và vẫn nhận được kết quả tương tự:

[["6", "^2"], ["7", "^1"], ["-2", "^0"]]

^^0^^0^^20 XOR 2= =20 XOR n= =n. Tất cả các số mũ là số nguyên, vì vậy chúng tôi ổn. Do đó, đánh giá điều này thay vì ở trên sẽ không thay đổi kết quả:

[["6", "2"], ["7", "1"], ["-2", "0"]]

Ở đây chúng tôi đi:

[[6, 2], [7, 1], [-2, 0]]

Bước này cũng sẽ chuyển đổi "-0"sang 0.

Vì chúng tôi phân tích cú pháp cả hai đầu vào, kết quả sau khi phân tích cú pháp sẽ là:

[[[6, 2], [7, 1], [-2, 0]], [[1, 2], [-2, 3]]]

Phân tích cú pháp đã hoàn tất. Thủ tục tiếp theo là Phép nhân.

Trước tiên chúng tôi lấy sản phẩm của Cartesian trong hai danh sách này:

[[[6, 2], [1, 2]], [[6, 2], [-2, 3]], [[7, 1], [1, 2]], [[7, 1], [-2, 3]], [[-2, 0], [1, 2]], [[-2, 0], [-2, 3]]]

Nhiều cặp được tạo ra, mỗi cặp có một yếu tố từ danh sách bên trái và một từ bên phải, theo thứ tự. Điều này cũng xảy ra là thứ tự dự định của đầu ra. Thử thách này thực sự yêu cầu chúng tôi áp dụng phân phối nhân, vì chúng tôi được yêu cầu không xử lý thêm kết quả sau đó.

mộtxcbxd= =mộtbxcxd= =mộtb(xcxd)= =(mộtb)xc+d[[6, 2], [-2, 3]]

Đầu tiên chúng ta hoán đổi cặp:

[[6, -2], [2, 3]]

Sau đó, chúng tôi lấy sản phẩm của cặp đầu tiên và tổng của thứ hai:

[-12, 5]

Phần có liên quan của mã, PSƭ€không thực sự đặt lại bộ đếm của nó cho từng cặp thuật ngữ, nhưng, vì chúng là cặp, nên không cần.

Xử lý tất cả các cặp điều khoản, chúng tôi có:

[[6, 4], [-12, 5], [7, 3], [-14, 4], [-2, 2], [4, 3]]

Ở đây, Phép nhân được thực hiện, vì chúng ta không phải kết hợp như các thuật ngữ. Thủ tục cuối cùng là Prettyfying.

Trước tiên chúng tôi tham gia mỗi cặp với "x^":

[[6, 'x', '^', 4], [-12, 'x', '^', 5], [7, 'x', '^', 3], [-14, 'x', '^', 4], [-2, 'x', '^', 2], [4, 'x', '^', 3]]

Sau đó, chúng tôi tham gia danh sách với " + ":

[6, 'x', '^', 4, ' ', '+', ' ', -12, 'x', '^', 5, ' ', '+', ' ', 7, 'x', '^', 3, ' ', '+', ' ', -14, 'x', '^', 4, ' ', '+', ' ', -2, 'x', '^', 2, ' ', '+', ' ', 4, 'x', '^', 3]

Lưu ý cách chúng ta vẫn có số trong danh sách, vì vậy nó không thực sự là một chuỗi. Tuy nhiên, Jelly có một quy trình gọi là "chuỗi hóa", được chạy ngay khi kết thúc thực hiện chương trình để in kết quả ra. Đối với danh sách độ sâu 1, nó thực sự chỉ chuyển đổi từng phần tử thành biểu diễn chuỗi của nó và nối các chuỗi lại với nhau, vì vậy chúng ta có được đầu ra mong muốn:

6x^4 + -12x^5 + 7x^3 + -14x^4 + -2x^2 + 4x^3

1

JavaScript, 112 110 byte

Tôi tìm thấy hai lựa chọn thay thế với cùng chiều dài. Gọi với cú pháp currying:f(A)(B)

A=>B=>(P=x=>x.split`+`.map(x=>x.split`x^`))(A).flatMap(a=>P(B).map(b=>a[0]*b[0]+'x^'+(a[1]- -b[1]))).join` + `

A=>B=>(P=x=>x.split`+`.map(x=>x.split`x^`))(A).flatMap(([c,e])=>P(B).map(([C,E])=>c*C+'x^'+(e- -E))).join` + `

-2 byte ( Luis ): Xóa khoảng trắng xung quanh splitdấu phân cách.


JavaScript, 112 byte

Sử dụng String.prototype.matchAll.

A=>B=>(P=x=>[...x.matchAll(/(\S+)x.(\S+)/g)])(A).flatMap(a=>P(B).map(b=>a[1]*b[1]+'x^'+(a[2]- -b[2]))).join` + `


1
split' + ' => split'+'để tiết kiệm 2 byte
Luis felipe De jesus Munoz


@EmbodimentofIgnorance Thật tệ, tôi đã đọc sai nhận xét của Luis. Tôi nghĩ rằng đó là về join.
Arnauld
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.