İki Tamsayı Polinomunu Çarpma


14

Senin görevin iki tek değişkenli tamsayı polinom ifadeleri almak ve bunları sadeleştirilmemiş birinci-dönem-büyük soldan sağa genişleme (çarpma durumunda AKA FOIL ) ile çarpmaktır . Benzer terimleri birleştirmeyin veya sonucu yeniden sıralamayın. Genişletme konusunda daha açık olmak için, ilk ifadedeki ilk terimi sırayla her terimle ikincisiyle çarpın ve tüm terimler diğer tüm terimlerle çarpılana kadar ilk ifadede devam edin. İfadeler basitleştirilmiş bir LaTeX varyantında verilecektir.

Her ifade, birbirinden ayrı bir terim dizisi olacaktır +(her bir tarafta tam olarak bir boşluk olacak) Her terim aşağıdaki normal ifadeye uyacaktır: (PCRE notasyonu)

-?\d+x\^\d+

Basit İngilizce'de, terim isteğe bağlı bir satır başı ve -ardından bir veya daha fazla basamak xve ardından negatif olmayan bir tamsayı gücüdür (ile ^)

Tam ifadeye bir örnek:

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

LaTeX'e takıldığında 6 x 3 + 1337 x 2 + - 4 x 1 + 2 x 0 elde edersiniz6x3+1337x2+-4x1+2x0

Çıktı da bu formata uygun olmalıdır.

Köşeli parantezler bu biçimde üsleri çevrelemediğinden, LaTeX aslında çok basamaklı üsleri hatalı şekilde oluşturur. (örneğin 4x^3 + -2x^14 + 54x^28 + -4x^5, ) Bunu hesaba gerek yoktur ve köşeli parantezleri çıktınıza dahil etmemelisiniz .4x3+-2x14+54x28+-4x5

Örnek Test Durumları

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

Kurallar ve Varsayımlar

  • Tüm girişlerin tam olarak bu biçime uyduğunu varsayabilirsiniz. Başka herhangi bir format için davranış, bu meydan okuma amacıyla tanımlanmamıştır.
    • Her ikisinin yukarıdaki formata uyan dizeler olarak okunması koşuluyla, iki polinomu almak için herhangi bir yöntemin geçerli olduğuna dikkat edilmelidir.
  • Polinomların sırası, ürünün genişlemesinin beklenen sırası nedeniyle önemlidir.
  • ve arasındaki giriş katsayılarını ve kadar giriş üslerini desteklemelisiniz . -128127255
    • Arasındaki Çıktı katsayıları ve ve kadar üstellerle nedenle desteklenmelidir.-16,25616,384510
  • Her bir giriş polinomunun en fazla 16 terim içerdiğini varsayabilirsiniz.
    • Bu nedenle (en azından) çıktıda 256 terimi desteklemelisiniz
  • Sıfır katsayılı terimler olduğu gibi bırakılmalı ve üsler düzgün bir şekilde birleştirilmelidir
  • Girişte negatif sıfıra izin verilir, ancak anlamsal olarak pozitif sıfırdan ayırt edilemez. Her zaman pozitif sıfır verin. Sıfır terimi atlamayın.

Mutlu Golf! İyi şanslar!



2
@LuisfelipeDejesusMunoz Hayal etmiyorum. Ayrıştırma, zorluğun ayrılmaz bir parçasıdır ve OP, "Her ikisinin yukarıdaki formata uygun dizeler olarak okunması koşuluyla , iki polinomu almak için herhangi bir yöntemin geçerli olduğuna dikkat edilmelidir . " (Vurgu eklenmiştir)
Giuseppe

Yanıtlar:


4

R , 159 153 148 bayt

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)

Çevrimiçi deneyin!

Gerçekten kullanmak istedim outer, bu yüzden neredeyse daha verimli bir yaklaşım var.


4

Haskell , 131122 bayt

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

Çevrimiçi deneyin!

fbir dizeden bir polinomu ayrıştırır, !ikisini çarpar ve sonucu biçimlendirir.

H.PWiz 9 bayt kurtardı. Teşekkürler!

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

Yakut , 102100 98 bayt

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

Çevrimiçi deneyin!

Nasıl?

İlk adım: her iki polinomdan da tüm sayıları alın: scansayıları bir dizi dize çifti olarak döndürür. Ardından, 2 listenin kartezyen bir ürününü yapın. Şimdi ihtiyacımız olan tüm sayılara sahibiz, ama yine de yanlış sırada.

Örnek: Biz çarpma eğer 3x^4tarafından -5x^2, biz rakamları elde [["3","4"],["-5","2"]]ilk fikir zip oldu ve bu listeyi dümdüz ve sonra olarak değerlendirilecek bir ifadenin içine numaralarını koymak [3*-5, 4+2]. Aslında, sayıları yeniden sıralamamız gerekmiyor, geçici bir değişken kullanarak ifade içinde yapabiliriz: ifade olur [3*(z=4,-5),z+2].

Bu ifadeleri değerlendirdikten sonra, katsayıyı ve üssü elde ederiz, bunları kullanarak "x^"birleştirmemiz ve ardından kullanarak tüm temlere katılmamız gerekir "+".


2

Haskell, 124 121 bayt

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)

Not: TIO eksik Data.Lists, bu yüzden içe aktarıyorum Data.Lists.Splitve Data.List: Çevrimiçi deneyin!

Düzenleme: @Lynn sayesinde -3 bayt.


Bu aslında 123 bayt! f!x=map f.splitOn xve sonra z=read!"x^"!"+"bir bayt kaydeder; son satır için drop 3$do[u,v]<-z a;[p,q]<-z b;" + "++shows(u*p)"x^"++show(v+q)iki tane daha kaydeder. 120 bayt
Lynn

1
@Lynn: TIO sürümü Data.Listbunun yerine içe aktarılır Data.Lists, dolayısıyla +1 bayttır.
nimi



1

Python 2 , 193 bayt

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

Çevrimiçi deneyin!

Yan not: İlk kez bir kod golf meydan okuma yapıyor, teşebbüs haha ​​berbat olursa çok üzgünüm


3
PPCG'ye Hoşgeldiniz! Ben bir python programcısı değilim, ama muhtemelen iyileştirilmesi gereken bir yer var. Belki de Python için İpuçları Golf için veya <tüm diller> için İpuçları Golf için yardım bulabilirsiniz ! Umarım burada geçirdiğiniz zamanın tadını çıkarırsınız :-)
Giuseppe


1
161 bayt için hızlı golf . Diğer python cevaplarına bakmakla birlikte, re.finditeren kısa yaklaşım olmayabilir
Jo King

1

Retina , 110 bayt

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

Çevrimiçi deneyin! Açıklama:

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

İlk girişteki her terimin önüne a #, ikinci girdinin bir kopyası ve bir boşluk ekleyin . Bu, ikinci girdinin kopyalarındaki tüm terimlerin önünde boşluk olduğu ve ilk girdideki terimlerin hiçbirinin olmadığı anlamına gelir.

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

İkinci girişteki terimlerin tüm kopyalarını ve ilk girişteki karşılık gelen terimlerini eşleştirin. Herhangi Concatenate -işaretler, çarpma katsayıları ve indekslerin ekleyin. Son olarak, ortaya çıkan tüm ikameleri dizeyle birleştirin  + .

--|-(0)
$1

Herhangi çiftleri silin -s ve dönüştürmek -0için 0.


1

SNOBOL4 (CSNOBOL4) , 192 176 bayt

	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

Çevrimiçi deneyin!

	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 # (Görsel C # Etkileşimli Derleyici) , 192190 bayt

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;

Sorgu sözdizimi, yöntem sözdiziminden daha kısa bir bayt gibi görünüyor.

Çevrimiçi deneyin!


Her ifade, + ile ayrılmış bir terim dizisi olacaktır (her bir tarafta tam olarak bir boşluk olacak) 190 bayt
Süresi Dolmuş Veriler

1

Jöle , 28 bayt

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

Çevrimiçi deneyin!

Tam program. İki polinomu iki dizenin bir listesi olarak alır.

Açıklama (genişletilmiş form)

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

)ile aynıdır µ€.
Bir iz açıktır ve atlanabilir.

Algoritma

Diyelim ki bu girdimiz var:

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

İlk prosedür, iki polinomun her birine uygulanan Ayrıştırmadır. İlkini ele alalım "6x^2 + 7x^1 + -2x^0":

İlk adım, '+'terimleri ayırmak için dizeyi ayırmaktır. Bunun sonucu:

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

Bir sonraki adım, 'x'katsayıyı üssünden ayırmak için her dizeyi ayırmaktır. Sonuç şudur:

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

Şu anda, bu dizelerde çok fazla çöp var gibi görünüyor, ancak bu çöp aslında önemsiz. Bu dizelerin tümü niladik Jelly bağlantıları olarak değerlendirilecektir. Önemsiz olarak, sayılar arasındaki rakamlar arasında olmadığı için boşluklar önemsizdir. Böylece aşağıdakileri de değerlendirebilir ve yine aynı sonucu elde edebiliriz:

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

^^0^^0^^20 XOR 2=20 XOR n=n. Tüm üsler tamsayıdır, bu yüzden iyiyiz. Bu nedenle, yukarıdakiler yerine bunu değerlendirmek sonucu değiştirmez:

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

İşte başlıyoruz:

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

Bu adım aynı zamanda dönüştürür "-0"için 0.

Her iki girişi de ayrıştırdığımız için, Ayrıştırma işleminden sonraki sonuç şu olacaktır:

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

Ayrıştırma artık tamamlanmıştır. Bir sonraki prosedür Çarpma işlemidir.

Önce bu iki listenin Kartezyen ürününü alıyoruz:

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

Her biri sol listeden bir eleman ve sağdan bir eleman olmak üzere birçok çift yapılır. Bu aynı zamanda çıktının amaçlanan sırasıdır. Bu zorluk, bizden, sonucu bundan sonra daha fazla işlemememiz istendiğinden, çarpımsal dağılabilirliği uygulamamızı istiyor.

birxcbxd=birbxcxd=birb(xcxd)=(birb)xc+d[[6, 2], [-2, 3]]

Önce çifti devrediyoruz:

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

Daha sonra ilk çiftin ürününü ve ikinci çiftin toplamını alırız:

[-12, 5]

Kodun ilgili kısmı, PSƭ€her terim çifti için sayacını gerçekten sıfırlamaz, ancak çift oldukları için buna gerek yoktur.

Tüm terim çiftlerini ele aldığımızda:

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

Burada, Çarpma yapılır, çünkü benzer terimleri birleştirmek zorunda değiliz. Son prosedür Prettyfying'dir.

Önce her bir çifte katılıyoruz "x^":

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

Sonra listeye katılıyoruz " + ":

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

Listede hala sayıların nasıl bulunduğuna dikkat edin, bu gerçekten bir dize değil. Bununla birlikte, Jelly, sonucu yazdırmak için bir program yürütüldükten hemen sonra "stringization" adı verilen bir işleme sahiptir. Derinlik 1'in bir listesi için, gerçekten her bir öğeyi dize temsiline dönüştürür ve dizeleri birleştirir, böylece istenen çıktıyı elde ederiz:

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

1

JavaScript, 112110 bayt

Aynı uzunlukta iki alternatif buldum. Körili sözdizimi ile çağrı: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 bayt ( Luis ): splitSınırlayıcı çevresindeki boşlukları kaldırır.


JavaScript, 112 bayt

Kullanma 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 bayt kurtarmak için
Luis felipe De jesus Munoz

@Arnauld Onlarsız iyi görünüyor
Bilgisizlik

@EmbodimentofIgnorance Kötüüm Luis'in yorumunu yanlış okudum. Bunun hakkında olduğunu düşündüm join.
Arnauld
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.