2つの整数多項式の乗算


14

あなたの仕事は、多項式の整数と乗算それら彼らのunsimplified最初期-主要な左から右への展開(AKAへの2つの変数を取ることですFOIL二項の場合)。同様の用語を組み合わせたり、結果を並べ替えたりしないでください。展開をより明確にするには、最初の式の最初の用語に2番目の式の各用語を順番に乗算し、すべての用語に他のすべての用語が乗算されるまで最初の式を続けます。式は、単純化されたLaTeXバリアントで提供されます。

各式は、+(各側にちょうど1つのスペースがある)で区切られた一連の用語になります。各用語は、次の正規表現に準拠します。(PCRE表記)

-?\d+x\^\d+

平易な英語では、この用語は、オプションの先頭-に1つ以上の数字が続き、その後にx非負の整数の累乗が続く(で^

完全な式の例:

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

LaTeXに接続すると、6x3+1337x2+4バツ1+2バツ0

出力もこの形式に準拠する必要があります。

この形式ではブラケットが指数を囲んでいないため、LaTeXは実際に複数桁の指数を正しくレンダリングしません。(例えば4x^3 + -2x^14 + 54x^28 + -4x^54バツ3+2バツ14+54バツ28+4バツ5としてレンダリング)これを考慮する必要はなく、出力に括弧含めるべきではありません

テストケースの例

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

ルールと仮定

  • すべての入力がこの正確な形式に準拠していると想定できます。他の形式の動作は、このチャレンジの目的では定義されていません。
    • 2つの多項式を取り込む方法はすべて有効であることに注意してください。両方の多項式が上記の形式に準拠する文字列として読み込まれる場合に限ります。
  • 多項式の順序は、製品展開の予想される順序のために重要です。
  • あなたは間の入力係数をサポートしている必要があります128127までと入力指数255
    • 間の出力係数16,25616,384までと指数510したがって、サポートされなければなりません。
  • 各入力多項式には16個以下の項が含まれると仮定できます。
    • したがって、出力で(最低でも)最大256語をサポートする必要があります
  • 係数がゼロの項はそのまま残し、指数を適切に組み合わせてください
  • 入力では負のゼロを使用できますが、意味的には正のゼロと区別できません。常に正のゼロを出力します。ゼロ項を省略しないでください。

ハッピーゴルフ!幸運を!



2
@LuisfelipeDejesusMunoz私は想像していません。解析は課題の不可欠な部分であり、OPは「2つの多項式を取り込む方法はすべて有効であることに注意する必要があります。ただし、両方とも上記の形式に準拠する文字列として読み込まれます。」(強調を追加)
ジュゼッペ

回答:


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

Haskell131 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文字列から多項式を解析し、!そのうちの2つを乗算して結果をフォーマットします。

H.PWizは9バイトを節約しました。ありがとう!

非ゴルフ

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

ルビー102100 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^"、次にを使用してすべての項目を結合する必要があり"+"ます。


2

Haskell、124121バイト

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.SplitData.List:はオンラインそれをお試しください!

編集:@Lynnのおかげで-3バイト。


これは実際には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)はさらに2つ節約できます。120バイト
リン

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へようこそ!私はPythonプログラマーではありませんが、おそらく改善の余地があります。おそらく、Pythonのゴルフのヒントまたは<すべての言語>のゴルフのヒントでヘルプを見つけることができます!ここで過ごす時間をお楽しみください:
ジュゼッペ


1
161バイトのクイックゴルフ。他のpythonの答えを見て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#$&

最初の入力の各用語の前に、、#2番目の入力のコピー、およびスペースを付けます。これは、2番目の入力のコピーに含まれるすべての用語の前にスペースが付き、最初の入力の用語はどれも先頭にないことを意味します。

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

2番目の入力の用語のコピーと、最初の入力の対応する用語のすべてのコピーに一致します。-符号を連結し、係数を乗算し、インデックスを追加します。最後に、結果のすべての置換を文字列で結合します + 

--|-(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;

クエリ構文は、メソッド構文より1バイト短いようです。

オンラインでお試しください!


各式は、+(各側にちょうど1つのスペースがある)で区切られた一連の用語になります 190バイト
有効期限切れデータ

1

ゼリー、28バイト

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

オンラインでお試しください!

完全なプログラム。2つの多項式を2つの文字列のリストとして受け取ります。

説明(拡張フォーム)

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

エイリアス

)はと同じµ€です。
末尾は暗示され、省略できます。

アルゴリズム

この入力があるとしましょう:

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

最初の手順は、2つの多項式のそれぞれに適用される解析です。最初のものを処理しましょう"6x^2 + 7x^1 + -2x^0"

最初のステップは、文字列をで分割'+'して、用語を分離することです。この結果:

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

次のステップでは、各文字列をで分割'x'して、係数を指数から分離します。結果は次のとおりです。

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

現在、これらの文字列には多くのゴミがあるように見えますが、そのゴミは実際には重要ではありません。これらの文字列はすべて、niladic Jellyリンクとして評価されます。数字の桁の間ではないため、スペースは重要ではありません。したがって、以下を評価しても同じ結果が得られます。

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

^Sはもう少し邪魔に見えるが、彼らは実際にどちらか何もしません!さて、^ビット単位のXORアトムですが、ニラディックチェーンはモナドリンクのように動作します。ただし、ニラディックの場合、最初のリンクは引数を取る代わりに実際に引数になります。そうでない場合、リンクの引数はになり0ます。指数は^最初の文字としてsを持ち、^niladicではないため、引数はであると想定されます0。文字列の残りの部分、つまり数値は、の正しい引数です^。したがって、たとえば、^2あります0 XOR 2=2。明らかに、0 XOR 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]]]

これで解析が完了しました。次の手順は乗算です。

最初に、これら2つのリストのデカルト積を取得します。

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

多くのペアが作成され、それぞれ左のリストから1つの要素と右から1つの要素が順に配置されます。これは、出力の意図した順序でもあります。この課題では、結果をさらに処理しないように求められているため、乗法的分布を適用するように本当に求められます。

各ペアのペアは、乗算する項を表します。最初の要素は係数で、2番目の要素は指数です。項を乗算するには、係数を乗算し、指数を加算します(aバツcbバツd=abバツcバツd=abバツcバツd=abバツc+d)。どうすればいいですか?2番目のペアを処理しましょう[[6, 2], [-2, 3]]

最初にペアを転置します。

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

次に、最初のペアの積と2番目のペアの合計を取得します。

[-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]

リストにまだ数字が残っていることに注意してください。したがって、実際には文字列ではありません。ただし、Jellyには「文字列化」と呼ばれるプロセスがあり、プログラムの実行の最後に実行されて結果を出力します。深さ1のリストの場合、実際には各要素を文字列表現に変換し、文字列を連結するだけなので、目的の出力が得られます。

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

1

JavaScript、112 110バイト

同じ長さの2つの選択肢が見つかりました。カリー化構文で呼び出します: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バイト(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バイトを保存するには
ルイスフェリペデジェススムニョス


@EmbodimentofIgnorance私の悪い、私はルイスのコメントを読み間違えた。私はそれについてだと思ったjoin
アーナルド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.