Gandakan Dua Polinomial Integer

14

Tugas Anda adalah mengambil dua ekspresi polinomial integer variabel tunggal dan melipatgandakannya menjadi ekspansi kiri-ke-kanan utama-jangka-pertama yang tidak disederhanakan (AKA FOIL dalam kasus binomial). Jangan menggabungkan istilah suka atau menyusun ulang hasilnya. Untuk lebih eksplisit tentang ekspansi, gandakan istilah pertama dalam ekspresi pertama dengan setiap istilah dalam urutan kedua, secara berurutan, dan lanjutkan dalam ekspresi pertama hingga semua istilah dikalikan dengan semua istilah lainnya. Ekspresi akan diberikan dalam varian LaTeX yang disederhanakan.

Setiap ekspresi akan menjadi urutan istilah yang dipisahkan oleh +(dengan tepat satu ruang di setiap sisi) Setiap istilah akan sesuai dengan ekspresi reguler berikut: (notasi PCRE)

-?\d+x\^\d+

Dalam bahasa Inggris yang sederhana, istilah ini adalah opsional memimpin -diikuti oleh satu atau lebih digit diikuti oleh xdan kekuatan bilangan bulat negatif (dengan ^)

Contoh ekspresi penuh:

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

Ketika dicolokkan ke LaTeX, Anda mendapatkan 6x3+1337x2+-4x1+2x0

Outputnya juga harus sesuai dengan format ini.

Karena tanda kurung tidak mengelilingi eksponen dalam format ini, LaTeX sebenarnya akan membuat eksponen multi-digit secara tidak benar. (mis. 4x^3 + -2x^14 + 54x^28 + -4x^5merender sebagai 4x3+-2x14+54x28+-4x5 ) Anda tidak perlu memperhitungkan hal ini dan Anda tidak boleh memasukkan tanda kurung ke dalam output Anda.

Contoh Kasus Uji

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

Aturan dan Asumsi

  • Anda dapat berasumsi bahwa semua input sesuai dengan format yang tepat ini. Perilaku untuk format lain tidak ditentukan untuk tujuan tantangan ini.
    • Perlu dicatat bahwa setiap metode pengambilan dalam dua polinomial adalah valid, asalkan keduanya dibaca sebagai string yang sesuai dengan format di atas.
  • Urutan polinomial penting karena urutan yang diharapkan dari ekspansi produk.
  • Anda harus mendukung koefisien input antara -128 dan 127 dan memasukkan eksponen hingga 255 .
    • Koefisien keluaran antara -16,256 dan 16,384 dan eksponen hingga 510 harus didukung.
  • Anda dapat menganggap setiap input polinomial mengandung tidak lebih dari 16 istilah
    • Karena itu, Anda harus (minimal) mendukung hingga 256 syarat dalam output
  • Persyaratan dengan nol koefisien harus dibiarkan apa adanya, dengan eksponen digabungkan dengan benar
  • Nol negatif diizinkan dalam input, tetapi tidak dapat dibedakan dari nol positif secara semantik. Selalu menghasilkan nol positif. Jangan hilangkan istilah nol.

Selamat Golf! Semoga berhasil!

Beefster
sumber
1
terkait
H.PWiz
2
@LuisfelipeDejesusMunoz Saya kira tidak. Parsing adalah bagian integral dari tantangan dan OP mengatakan - "Perlu dicatat bahwa setiap metode pengambilan dalam dua polinom adalah valid, asalkan keduanya dibaca sebagai string yang sesuai dengan format di atas. " (Penekanan ditambahkan)
Giuseppe

Jawaban:

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)

Cobalah online!

Saya benar-benar ingin menggunakannya outer, jadi hampir pasti ada pendekatan yang lebih efisien.

Giuseppe
sumber
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)

Cobalah online!

fmem-parsing polinomial dari string, !mengalikan dua dari mereka dan memformat hasilnya.

H.PWiz menyimpan 9 byte. Terima kasih!

Tidak disatukan

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
Lynn
sumber
129 byte
H.PWiz
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^"}}*?+}

Cobalah online!

Bagaimana?

Langkah pertama: dapatkan semua angka dari kedua polinomial: scanmengembalikan angka sebagai array pasangan string. Kemudian, lakukan produk cartesian dari 2 daftar. Sekarang kita memiliki semua angka di mana kita membutuhkannya, tetapi masih dalam urutan yang salah.

Contoh: jika kita kalikan 3x^4dengan -5x^2, kita mendapatkan angka sebagai [["3","4"],["-5","2"]], ide pertama adalah untuk zip dan meratakan daftar ini, dan kemudian memasukkan angka ke dalam ekspresi yang akan dievaluasi sebagai [3*-5, 4+2]. Sebenarnya, kita tidak perlu menyusun ulang angka, kita bisa melakukannya di dalam ekspresi dengan menggunakan variabel sementara: ekspresi menjadi [3*(z=4,-5),z+2].

Setelah mengevaluasi ungkapan-ungkapan ini, kita mendapatkan koefisien dan eksponen, kita harus bergabung dengan mereka menggunakan "x^", dan kemudian bergabung dengan mereka semua menggunakan "+".

GB
sumber
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)

Catatan: TIO kurang Data.Lists, jadi saya mengimpor Data.Lists.Splitdan Data.List: Coba online!

Edit: -3 byte terima kasih kepada @Lynn.

nimi
sumber
Ini sebenarnya 123 byte! f!x=map f.splitOn xdan kemudian z=read!"x^"!"+"menyimpan byte; untuk baris terakhir drop 3$do[u,v]<-z a;[p,q]<-z b;" + "++shows(u*p)"x^"++show(v+q)menghemat dua lagi. 120 byte
Lynn
1
@ Lynn: versi TIO yang diimpor Data.Listbukan Data.Lists, jadi +1 byte.
nimi
1

JavaScript (Babel Node) , 118 byte

Mengambil input sebagai (a)(b).

a=>b=>(g=s=>[...s.matchAll(/(-?\d+)x.(\d+)/g)])(a).flatMap(([_,x,p])=>g(b).map(([_,X,P])=>x*X+'x^'+-(-p-P))).join` + `

Cobalah online!

Arnauld
sumber
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))

Cobalah online!

Catatan: Pertama kali melakukan tantangan kode golf, maaf jika upaya ini menyebalkan haha

GotCubes
sumber
3
Selamat datang di PPCG! Saya tidak banyak programmer python, tapi mungkin ada ruang untuk perbaikan. Mungkin Anda dapat menemukan bantuan di Tips untuk Golf dengan Python atau Tips untuk Golf dalam <semua bahasa> ! Semoga Anda menikmati waktu yang Anda habiskan di sini :-)
Giuseppe
hemat 12 byte
Noodle9
1
Beberapa golf cepat untuk 161 byte . Meskipun melihat jawaban python lainnya, re.finditermungkin bukan pendekatan terpendek
Jo King
1

Retina , 110 byte

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

Cobalah online! Penjelasan:

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

Awali setiap istilah dalam input pertama dengan #, salinan input kedua, dan spasi. Ini berarti bahwa semua istilah dalam salinan input kedua didahului oleh spasi dan tidak ada istilah dari input pertama.

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

Cocokkan semua salinan persyaratan dalam input kedua dan istilah terkait dari input pertama. Gabungkan -tanda - tanda, gandakan koefisien, dan tambahkan indeks. Akhirnya, gabungkan semua hasil pergantian dengan string  + .

--|-(0)
$1

Hapus sembarang pasang -dan konversikan -0ke 0.

Neil
sumber
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

Cobalah online!

	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
Giuseppe
sumber
1

Perl 6 , 114 byte

{my&g=*.match(/(\-?\d+)x\^(\d+)/,:g)».caps».Map;join " + ",map {"{[*] $_»{0}}x^{[+] $_»{1}}"},(g($^a)X g $^b)}

Cobalah online!

bb94
sumber
1
86 byte
Jo King
1

Python 2 , 130 byte

lambda a,b:' + '.join([`v*V`+'x^'+`k+K`for V,K in g(a)for v,k in g(b)])
g=lambda s:[map(int,t.split('x^'))for t in s.split(' + ')]

Cobalah online!

Chas Brown
sumber
1

C # (Visual C # Interactive Compiler) , 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;

Sintaks kueri tampaknya satu byte lebih pendek dari sintaks metode.

Cobalah online!

Perwujudan Ketidaktahuan
sumber
Setiap ekspresi akan menjadi urutan istilah yang dipisahkan oleh + (dengan tepat satu spasi di setiap sisi) 190 byte
Data Kedaluwarsa
1

Jelly , 28 byte

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

Cobalah online!

Program lengkap. Mengambil dua polinomial sebagai daftar dua string.

Penjelasan (formulir diperluas)

ṣ”+ṣ”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.

Mengasingkan

)sama dengan µ€.
A tertinggal tersirat dan dapat dihilangkan.

Algoritma

Katakanlah kita memiliki input ini:

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

Prosedur pertama adalah Parsing, diterapkan pada masing-masing dari dua polinomial. Mari kita menangani yang pertama,"6x^2 + 7x^1 + -2x^0" :

Langkah pertama adalah dengan memisahkan string '+', sehingga memisahkan istilah. Ini menghasilkan:

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

Langkah selanjutnya adalah membagi setiap string dengan 'x', untuk memisahkan koefisien dari eksponen. Hasilnya adalah ini:

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

Saat ini, sepertinya ada banyak sampah di string ini, tetapi sampah itu sebenarnya tidak penting. Semua string ini akan dievaluasi sebagai tautan Jelly niladic. Secara sepele, spasi tidak penting, karena mereka tidak berada di antara angka-angka. Jadi kami dapat mengevaluasi di bawah dan masih mendapatkan hasil yang sama:

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

The ^s terlihat sedikit lebih mengganggu, tetapi mereka benar-benar tidak melakukan apa-apa baik! Ya, ^adalah atom XOR bitwise, namun rantai niladik bertindak seperti tautan monadik, kecuali bahwa tautan pertama benar-benar menjadi argumen, alih-alih mengambil argumen, jika itu niladik. Jika tidak, maka tautannya akan memiliki argumen 0. Eksponen memiliki ^s sebagai char pertama mereka, dan ^bukan niladic, jadi argumennya dianggap 0. Sisa string, yaitu angka, adalah argumen yang benar dari ^. Jadi, misalnya, ^2adalah0 XOR 2=2. Jelas,0 XOR n=n. Semua eksponen bilangan bulat, jadi kami baik-baik saja. Karenanya, mengevaluasi ini sebagai ganti dari yang di atas tidak akan mengubah hasilnya:

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

Kita mulai:

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

Langkah ini juga akan dikonversi "-0"menjadi 0.

Karena kita mengurai kedua input, hasil setelah Parsing akan menjadi ini:

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

Parsing sudah selesai. Prosedur selanjutnya adalah Perkalian.

Kami pertama-tama mengambil produk Cartesian dari dua daftar ini:

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

Banyak pasangan dibuat, masing-masing dengan satu elemen dari daftar kiri dan satu dari kanan, secara berurutan. Ini juga merupakan urutan output yang diinginkan. Tantangan ini benar-benar meminta kami untuk menerapkan distribusi multiplikatif, karena kami diminta untuk tidak melanjutkan hasilnya setelah itu.

Pasangan dalam setiap pasangan mewakili istilah yang ingin kita gandakan, dengan elemen pertama adalah koefisien dan yang kedua adalah eksponen. Untuk melipatgandakan persyaratan, kami mengalikan koefisien dan menambahkan eksponen bersama-sama (Sebuahxcbxd=Sebuahbxcxd=Sebuahb(xcxd)=(Sebuahb)xc+d). Bagaimana kita melakukannya? Mari kita tangani pasangan kedua [[6, 2], [-2, 3]],.

Kami pertama-tama mengubah posisi pasangan:

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

Kami kemudian mengambil produk dari pasangan pertama, dan jumlah dari yang kedua:

[-12, 5]

Bagian kode yang relevan PSƭ€,, tidak benar-benar mengatur ulang penghitungnya untuk setiap pasangan istilah, tetapi, karena berpasangan, itu tidak perlu.

Menangani semua pasangan istilah, kami memiliki:

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

Di sini, Penggandaan selesai, karena kita tidak harus menggabungkan istilah yang serupa. Prosedur terakhir adalah Prettyfying.

Kami pertama kali bergabung dengan setiap pasangan dengan "x^":

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

Kemudian kami bergabung dengan daftar dengan " + ":

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

Perhatikan bagaimana kita masih memiliki angka dalam daftar, jadi itu bukan string. Namun, Jelly memiliki proses yang disebut "pengetatan", berjalan tepat di akhir pelaksanaan program untuk mencetak hasilnya. Untuk daftar kedalaman 1, itu benar-benar hanya mengkonversi setiap elemen ke representasi string dan menyatukan string, jadi kami mendapatkan hasil yang diinginkan:

6x^4 + -12x^5 + 7x^3 + -14x^4 + -2x^2 + 4x^3
Erik the Outgolfer
sumber
1

JavaScript, 112 110 byte

Saya menemukan dua alternatif dengan panjang yang sama. Panggil dengan sintaks 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 ): Hapus spasi di sekitar splitpembatas.


JavaScript, 112 byte

Menggunakan 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` + `

Darrylyeo
sumber
1
split' + ' => split'+' untuk menyimpan 2 byte
Luis felipe De jesus Munoz
@Arnauld Tampaknya baik-baik saja tanpa mereka
Perwujudan Ketidaktahuan
@EmbodimentofIgnorance Buruk saya, saya salah membaca komentar Luis. Saya pikir itu tentang join.
Arnauld