พหุนามทวีคูณทวีคูณสองเท่า


14

งานของคุณคือการใช้นิพจน์พหุนามจำนวนเต็มสองตัวแปรและคูณลงในการขยายตัวจากซ้ายไปขวาของคำหลักในระยะแรกที่ไม่ระบุ (AKA FOILในกรณีของทวินาม) อย่ารวมเหมือนคำต่างๆหรือเรียงลำดับผลลัพธ์ใหม่ หากต้องการให้ชัดเจนยิ่งขึ้นเกี่ยวกับการขยายให้คูณเทอมแรกในนิพจน์แรกของแต่ละเทอมในลำดับที่สองตามลำดับและดำเนินการต่อในนิพจน์แรกจนกว่าจะมีการคูณข้อกำหนดทั้งหมดด้วยข้อกำหนดอื่นทั้งหมด การแสดงออกจะได้รับในตัวแปร LaTeX ที่ง่ายขึ้น

แต่ละนิพจน์จะเป็นลำดับของคำที่คั่นด้วย+( โดยมีหนึ่งช่องว่างในแต่ละด้าน) แต่ละคำจะสอดคล้องกับนิพจน์ทั่วไปต่อไปนี้: (สัญกรณ์ PCRE)

-?\d+x\^\d+

ในภาษาอังกฤษธรรมดาคำนี้เป็นตัวเลือกนำที่-ตามด้วยตัวเลขหนึ่งตัวหรือมากกว่าตามด้วยxและพลังงานจำนวนเต็มไม่ใช่ค่าลบ (พร้อม^)

ตัวอย่างของการแสดงออกเต็มรูปแบบ:

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

เมื่อเสียบเข้ากับ LaTeX คุณจะได้รับ6x3+1337x2+4x1+2x0

ผลลัพธ์ควรสอดคล้องกับรูปแบบนี้

เนื่องจากวงเล็บไม่ล้อมรอบเลขชี้กำลังในรูปแบบนี้ LaTeX จะแสดงเลขชี้กำลังหลายหลักอย่างไม่ถูกต้อง (เช่น4x^3 + -2x^14 + 54x^28 + -4x^5แสดงเป็น4x3+2x14+54x28+4x5 ) คุณไม่จำเป็นต้องพิจารณาเรื่องนี้และคุณไม่ควรใส่วงเล็บในผลลัพธ์ของคุณ

ตัวอย่างกรณีทดสอบ

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

กฎและข้อสมมติฐาน

  • คุณอาจสมมติว่าอินพุตทั้งหมดเป็นไปตามรูปแบบที่แน่นอนนี้ พฤติกรรมสำหรับรูปแบบอื่น ๆ นั้นไม่ได้กำหนดไว้สำหรับวัตถุประสงค์ของการท้าทายนี้
    • ควรสังเกตว่าวิธีการใด ๆ ในสองชื่อประกอบด้วยชื่อที่ประกอบด้วยหลายคำโดยมีเงื่อนไขว่าทั้งสองจะอ่านเป็นสตริงที่สอดคล้องกับรูปแบบข้างต้น
  • คำสั่งของชื่อพหุนามมีความสำคัญเนื่องจากคำสั่งซื้อที่คาดหวังของการขยายผลิตภัณฑ์
  • คุณจะต้องสนับสนุนค่าสัมประสิทธิ์การป้อนข้อมูลระหว่าง-128และ127และเลขยกกำลังป้อนข้อมูลได้ถึง255 255
    • ดังนั้นจึงต้องรองรับค่าสัมประสิทธิ์การส่งออกระหว่าง-16,256และ16,384และ exponents สูงสุด510
  • คุณอาจสมมติว่าพหุนามแต่ละรายการมีคำไม่เกิน 16 คำ
    • ดังนั้นคุณต้องสนับสนุนอย่างน้อย 256 คำในเอาต์พุต
  • ควรทิ้งข้อกำหนดที่มีค่าสัมประสิทธิ์เป็นศูนย์เช่นเดียวกับการยกกำลังรวมกันอย่างถูกต้อง
  • อนุญาตให้มีศูนย์ลบได้ในอินพุต แต่แยกไม่ออกจากศูนย์บวกเชิงความหมาย เอาต์พุตเป็นศูนย์บวกเสมอ อย่าละเว้นศูนย์เป็นศูนย์

มีความสุขในการเล่นกอล์ฟ! โชคดี!



2
@ LuisfelipeDejesusMunoz ฉันคิดว่าไม่ การแยกเป็นส่วนสำคัญของความท้าทายและ OP กล่าวว่า - "ควรสังเกตว่าวิธีการใด ๆ ในสองชื่อที่ประกอบด้วยหลายชื่อนั้นถูกต้องหากว่าทั้งสองถูกอ่านเป็นสตริงที่สอดคล้องกับรูปแบบข้างต้น " (เน้นเพิ่มเติม)
จูเซปเป้

คำตอบ:


4

R , 159 153 148 ไบต์

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)

ลองออนไลน์!

ฉันต้องการใช้จริงๆouterดังนั้นจึงมีวิธีการที่มีประสิทธิภาพมากกว่า


4

Haskell , 131 122 ไบต์

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

ลองออนไลน์!

f แยกวิเคราะห์พหุนามจากสตริง !ทวีคูณสองรายการและจัดรูปแบบผลลัพธ์

H.PWiz บันทึก 9 ไบต์ ขอบคุณ!

Ungolfed

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 ไบต์

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

ลองออนไลน์!

อย่างไร?

ขั้นตอนแรก: รับตัวเลขทั้งหมดจากพหุนามทั้งสอง: scanคืนค่าตัวเลขเป็นอาร์เรย์ของสตริงคู่ จากนั้นทำผลิตภัณฑ์คาร์ทีเซียนของ 2 รายการ ตอนนี้เรามีตัวเลขทั้งหมดที่เราต้องการ แต่ยังอยู่ในลำดับที่ไม่ถูกต้อง

ตัวอย่าง: ถ้าเราคูณ3x^4โดย-5x^2เราได้รับตัวเลขที่เป็นความคิดแรกคือการไปรษณีย์และแผ่รายการนี้แล้วใส่ตัวเลขลงในการแสดงออกที่จะได้รับการประเมินว่า[["3","4"],["-5","2"]] [3*-5, 4+2]ที่จริงแล้วเราไม่จำเป็นต้องเรียงลำดับหมายเลขใหม่เราสามารถทำได้ภายในนิพจน์โดยใช้ตัวแปรชั่วคราว[3*(z=4,-5),z+2]นั่นคือนิพจน์กลายเป็น

หลังจากการประเมินการแสดงออกเหล่านี้เราได้รับค่าสัมประสิทธิ์และตัวแทนเราต้องร่วมกับพวกเขาใช้"x^"แล้วเข้าร่วม TEMS "+"ทั้งหมดที่ใช้


2

Haskell, 124 121 ไบต์

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)

หมายเหตุ: TIO ขาดData.Listsฉันจึงนำเข้าData.Lists.SplitและData.List: ลองออนไลน์!

แก้ไข: -3 ไบต์ขอบคุณ @Lynn


อันที่จริงแล้วเป็น 123 ไบต์! f!x=map f.splitOn xแล้วz=read!"x^"!"+"บันทึกไบต์; สำหรับบรรทัดสุดท้ายdrop 3$do[u,v]<-z a;[p,q]<-z b;" + "++shows(u*p)"x^"++show(v+q)จะบันทึกอีกสองรายการ 120 bytes
Lynn

1
@Lynn: รุ่น TIO นำเข้าData.ListแทนData.Listsดังนั้นจึงเป็น +1 ไบต์
nimi



1

Python 2 , 193 ไบต์

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

ลองออนไลน์!

หมายเหตุด้านข้าง: ครั้งแรกที่ทำรหัสกอล์ฟท้าทายดังนั้นถ้าพยายามดูดฮ่าฮ่า


3
ยินดีต้อนรับสู่ PPCG! ฉันไม่ได้เป็นนักเขียนโปรแกรมหลามมากนัก แต่อาจมีห้องพักสำหรับการปรับปรุงบางอย่าง บางทีคุณสามารถขอความช่วยเหลือได้ที่Tips for Golfing ใน PythonหรือTips for Golfing ใน <ทุกภาษา> ! หวังว่าคุณจะสนุกกับเวลาที่คุณใช้ที่นี่ :-)
จูเซปเป้


1
บางคนเล่นกอล์ฟอย่างรวดเร็วสำหรับ161 ไบต์ แม้ว่าการดูคำตอบของงูหลามอื่น ๆre.finditerอาจไม่ใช่วิธีที่สั้นที่สุด
โจคิง

1

จอประสาทตา 110 ไบต์

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

ลองออนไลน์! คำอธิบาย:

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

นำหน้าแต่ละคำในอินพุตแรกด้วย a #, สำเนาของอินพุตที่สองและช่องว่าง ซึ่งหมายความว่าข้อกำหนดทั้งหมดในสำเนาของอินพุตที่สองนำหน้าด้วยช่องว่างและไม่มีข้อกำหนดใด ๆ จากอินพุตแรก

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

จับคู่สำเนาทั้งหมดของคำศัพท์ในอินพุทที่สองและคำที่เกี่ยวข้องจากอินพุทแรก เชื่อม-สัญญาณใด ๆเพิ่มจำนวนสัมประสิทธิ์และเพิ่มดัชนี  + สุดท้ายเข้าร่วมทั้งหมดของการแทนส่งผลกับสตริง

--|-(0)
$1

ลบคู่ใด ๆ-และแปลงไป-00


1

SNOBOL4 (CSNOBOL4) , 192 176 ไบต์

	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

ลองออนไลน์!

	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 # (Visual C # Interactive Compiler) , 192 190 ไบต์

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;

ดูเหมือนว่าไวยากรณ์แบบสอบถามจะมีขนาดสั้นกว่าไบต์ของไวยากรณ์ของวิธีการ

ลองออนไลน์!


แต่ละนิพจน์จะเป็นลำดับของคำที่คั่นด้วย + (มีหนึ่งช่องว่างในแต่ละด้าน) 190 ไบต์
ข้อมูลที่หมดอายุแล้ว

1

เยลลี่ขนาด 28 ไบต์

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

ลองออนไลน์!

โปรแกรมเต็มรูปแบบ ใช้ชื่อพหุนามทั้งสองเป็นรายการของสองสาย

คำอธิบาย (แบบฟอร์มขยาย)

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

aliasing

)µ€เป็นเช่นเดียวกับ
ต่อท้ายเป็นนัยและสามารถละเว้นได้

ขั้นตอนวิธี

สมมติว่าเรามีข้อมูลนี้:

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

ขั้นตอนแรกคือการแยกวิเคราะห์ใช้กับชื่อพหุนามสองแบบ มาจัดการกับอันแรกกัน"6x^2 + 7x^1 + -2x^0" :

ขั้นตอนแรกคือการแยกสตริงโดย'+'เพื่อแยกคำ ผลลัพธ์นี้ใน:

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

ขั้นตอนต่อไปคือการแยกแต่ละสตริงด้วย'x'เพื่อแยกสัมประสิทธิ์จากเลขชี้กำลัง ผลลัพธ์คือ:

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

ขณะนี้ดูเหมือนว่ามีถังขยะจำนวนมากในสตริงเหล่านี้ แต่ถังขยะนั้นไม่สำคัญจริง ๆ สตริงเหล่านี้ทั้งหมดจะได้รับการประเมินเป็นลิงก์วุ้น niladic สิ่งสำคัญที่สุดคือช่องว่างไม่สำคัญเนื่องจากไม่ได้อยู่ระหว่างตัวเลขของตัวเลข ดังนั้นเราสามารถประเมินด้านล่างและยังได้รับผลลัพธ์เดียวกัน:

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

^มาดูอีกเล็กน้อยรบกวน แต่พวกเขาเป็นจริงไม่ได้ทำอะไรอย่างใดอย่างหนึ่ง! ดี^เป็นอะตอมบิต XOR แต่โซ่ niladic กระทำเช่นการเชื่อมโยงเอกยกเว้นว่าลิงค์แรกจริงจะกลายเป็นข้อโต้แย้งแทนการโต้แย้งถ้ามัน niladic 0ถ้ามันไม่ได้แล้วการเชื่อมโยงจะมีการโต้แย้งของ เลขยกกำลังที่มี^ฐานะถ่านครั้งแรกของพวกเขาและ^ไม่ได้เป็น niladic 0ดังนั้นอาร์กิวเมนต์จะถือว่า ^ส่วนที่เหลือของสตริงเช่นจำนวนที่เป็นข้อโต้แย้งทางขวาของ ตัวอย่างเช่น^2คือ0 แฮคเกอร์ 2=2. เห็นได้ชัดว่า0 แฮคเกอร์ n=n. เลขชี้กำลังทั้งหมดเป็นจำนวนเต็มดังนั้นเราก็โอเค ดังนั้นการประเมินสิ่งนี้แทนสิ่งด้านบนจะไม่เปลี่ยนผลลัพธ์:

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

ไปเลย:

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

ขั้นตอนนี้จะเปลี่ยนไป"-0"0

เนื่องจากเราแยกวิเคราะห์ทั้งสองอินพุตผลลัพธ์หลังจากการแยกวิเคราะห์จะเป็นดังนี้:

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

การแยกวิเคราะห์เสร็จสมบูรณ์แล้ว ขั้นตอนต่อไปคือการคูณ

ก่อนอื่นเราจะนำผลิตภัณฑ์คาร์ทีเซียนของทั้งสองรายการ:

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

มีการสร้างหลายคู่โดยแต่ละองค์ประกอบมีหนึ่งรายการจากรายการด้านซ้ายและอีกหนึ่งรายการจากด้านขวาตามลำดับ สิ่งนี้จะเกิดขึ้นตามลำดับของผลลัพธ์ด้วย ความท้าทายนี้ขอให้เราใช้การกระจายแบบทวีคูณตามที่เราขอไม่ให้ประมวลผลต่อไปหลังจากนั้น

คู่ในแต่ละคู่หมายถึงคำที่เราต้องการคูณด้วยองค์ประกอบแรกคือสัมประสิทธิ์และอันดับที่สองเป็นเลขชี้กำลัง ในการคูณเงื่อนไขเราคูณสัมประสิทธิ์และเพิ่มเลขชี้กำลังด้วยกัน (axxd=axxd=a(xxd)=(a)x+d) เราจะทำอย่างนั้นได้อย่างไร? Let 's [[6, 2], [-2, 3]]จับคู่ที่สอง

เราทำการแปลงทั้งคู่เป็นครั้งแรก:

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

จากนั้นเราก็นำผลคูณของคู่แรกและผลรวมของคู่ที่สอง:

[-12, 5]

ส่วนที่เกี่ยวข้องของรหัสPSƭ€ไม่ได้รีเซ็ตตัวนับจริงสำหรับคำศัพท์แต่ละคู่ แต่เนื่องจากเป็นคู่จึงไม่จำเป็นต้อง

การจัดการคำศัพท์ทุกคู่เรามี:

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

ที่นี่การคูณเสร็จแล้วเราไม่ต้องรวมคำเหมือนกัน ขั้นตอนสุดท้ายคือ Prettyfying

เราเข้าร่วมแต่ละคู่ด้วย"x^":

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

จากนั้นเราจะเข้าร่วมรายการด้วย" + ":

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

สังเกตว่าเรายังมีตัวเลขอยู่ในรายการดังนั้นมันไม่ใช่สตริง อย่างไรก็ตามเจลลี่มีกระบวนการที่เรียกว่า "การทำให้เป็นสตริง" ซึ่งวิ่งไปเมื่อสิ้นสุดการทำงานของโปรแกรมเพื่อพิมพ์ผลลัพธ์ สำหรับรายการความลึก 1 มันแค่แปลงแต่ละองค์ประกอบเป็นการแทนค่าสตริงและเชื่อมสตริงเข้าด้วยกันดังนั้นเราจะได้ผลลัพธ์ที่ต้องการ:

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

1

JavaScript, 112 110 ไบต์

ฉันพบทางเลือกสองทางที่มีความยาวเท่ากัน โทรด้วยรูปแบบการแกง: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 bytes ( Luis ): ลบช่องว่างรอบsplitตัวคั่น


JavaScript, 112 ไบต์

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'+'บันทึก 2 ไบต์
Luis felipe De jesus Munoz


@EmbodimentofIgnorance ฉันไม่ดีฉันอ่านความคิดเห็นของหลุยส์ผิด joinฉันคิดว่ามันเป็นเรื่องเกี่ยวกับ
Arnauld
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.