두 개의 정수 다항식 곱하기


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

규칙과 가정

  • 모든 입력이이 정확한 형식을 준수한다고 가정 할 수 있습니다. 다른 형식의 동작은이 문제의 목적으로 정의되지 않습니다.
    • 두 가지 다항식을 취하는 방법은 모두 위의 형식에 맞는 문자열로 읽혀진다면 유효합니다.
  • 다항식의 순서는 예상되는 제품 확장 순서로 인해 중요합니다.
  • 에서 사이의 입력 계수 와 최대 입력 지수 를 지원해야합니다 . 128127255
    • 따라서 에서 사이의 출력 계수 와 까지의 지수 가 지원되어야합니다.16,25616,384510
  • 각 입력 다항식이 16 개 이하의 용어를 포함한다고 가정 할 수 있습니다.
    • 따라서 출력에서 ​​최대 256 개의 항을 지원해야합니다.
  • 계수가 0 인 항은 그대로두고 지수가 올바르게 결합되어야합니다.
  • 음수 0은 입력에 허용되지만 의미 적으로 양수 0과 구분할 수는 없습니다. 항상 양의 0을 출력합니다. 제로 용어를 생략하지 마십시오.

행복한 골프! 행운을 빕니다!



2
@LuisfelipeDejesusMunoz 나는 상상하지 않는다. 구문 분석은 문제의 핵심 부분이며 OP는 다음과 같이 말합니다. "두 가지 다항식을 취하는 방법은 모두 위의 형식에 맞는 문자열로 읽 히면 유효 합니다. "(강조 추가)
Giuseppe

답변:


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

하스켈 , 131122 바이트

(%)=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 바이트를 절약했습니다. 감사!

언 골프

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숫자를 문자열 쌍의 배열로 반환합니다. 그런 다음 두 목록 중 데카르트 곱을 수행하십시오. 이제 필요한 곳에 모든 숫자가 있지만 여전히 잘못된 순서입니다.

예 : 우리가 곱 경우 3x^4-5x^2, 우리가 숫자를 얻을 [["3","4"],["-5","2"]]첫 번째 아이디어는 우편에, 그리고이 목록을 평평하게 한 다음로 평가되는 식으로 숫자를 넣어 [3*-5, 4+2]. 실제로, 우리는 숫자를 재정렬 할 필요가 없습니다. 임시 변수를 사용하여 표현식 안에서 숫자를 바꿀 수 있습니다 : 표현식은 [3*(z=4,-5),z+2].

이러한 표현식을 평가 한 후 계수와 지수를 구하고를 사용 "x^"하여 결합한 다음을 사용하여 모든 항목을 결합해야합니다 "+".


2

하스켈, 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.ListsI 가져올 수 있도록, Data.Lists.Split그리고 Data.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)은 두 개를 더 절약합니다. 120 바이트
Lynn

1
@Lynn : TIO 버전이 Data.List대신에 가져 오기 Data.Lists때문에 +1 바이트입니다.
nimi



1

파이썬 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에 오신 것을 환영합니다! 나는 파이썬 프로그래머가별로 없지만 개선의 여지가있을 것입니다. 어쩌면 파이썬의 골프 팁 또는 <모든 언어>의 골프 팁 에서 도움을 찾을 수 있습니다 ! 당신이 여기에서 보내는 시간을 즐기시기 바랍니다 :-)
Giuseppe


1
161 바이트에 대한 빠른 골프 . 다른 파이썬 답변을 살펴 보더라도 re.finditer가장 짧은 접근 방식은 아닐 수도 있습니다.
Jo King

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#$&

첫 번째 입력의 각 항 앞에 #, 두 번째 입력의 사본 및 공백을 접두어로 사용하십시오 . 이것은 두 번째 입력의 사본에있는 모든 용어 앞에 공백이 있고 첫 번째 입력의 용어는 없음을 의미합니다.

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

두 번째 입력의 모든 용어 사본과 첫 번째 입력의 해당 용어를 일치시킵니다. -부호를 연결 하고 계수를 곱한 다음 색인을 추가하십시오. 마지막으로 모든 결과 대체를 문자열로 결합하십시오  + .

--|-(0)
$1

의 쌍을 모두 삭제 -하고로 변환 -0하십시오 0.


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 # 대화식 컴파일러) , 192190 바이트

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.

앨리어싱

)와 동일합니다 µ€.
후행 은 내포되어 있으며 생략 할 수 있습니다.

연산

이 입력이 있다고 가정 해 봅시다.

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

현재이 문자열에는 많은 쓰레기가있는 것처럼 보이지만 실제로는 그 쓰레기는 중요하지 않습니다. 이 문자열은 모두 닐 라드 젤리 링크로 평가됩니다. 사소하게, 공백은 숫자의 숫자 사이에 있지 않기 때문에 중요하지 않습니다. 따라서 아래를 평가해도 여전히 같은 결과를 얻을 수 있습니다.

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

^s는 좀 더 방해 보이지만 실제로 중 아무것도하지 마! 글쎄, ^비트 XOR 원자이지만, 닐라 딕 사슬은 모나 딕 링크처럼 행동합니다. 단, 첫 번째 링크는 나일 경우 인수를 취하는 대신 실제로 인수가됩니다. 그렇지 않은 경우 링크의 인수는 0입니다. 지수는 ^s를 첫 번째 문자로 사용하며 ^나쁘지 않으므로 인수는로 간주됩니다 0. 문자열의 나머지 부분, 즉 숫자는의 올바른 인수입니다 ^. 따라서, 예를 들어, ^2이다0 XOR 2=2. 명백하게,0 XOR =. 모든 지수는 정수이므로 우리는 괜찮습니다. 따라서 위의 값 대신이를 평가해도 결과가 변경되지 않습니다.

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

왼쪽 목록에서 하나의 요소와 오른쪽에서 하나의 요소로 순서대로 여러 쌍이 만들어집니다. 이것은 또한 의도 된 출력 순서입니다. 이 도전은 우리가 그 이후 결과를 더 이상 처리하지 않기를 요청하면서 곱셈 분포를 적용하도록 요구합니다.

각 쌍의 쌍은 곱하고자하는 항을 나타내며, 첫 번째 요소는 계수이고 두 번째 요소는 지수입니다. 항을 곱하기 위해 계수를 곱하고 지수를 함께 더합니다 (엑스엑스=엑스엑스=(엑스엑스)=()엑스+). 우리는 어떻게합니까? 두 번째 쌍을 처리합시다 [[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]

리스트에 숫자가 어떻게 남아 있는지 확인하십시오. 그래서 실제로 문자열이 아닙니다. 그러나 Jelly에는 "stringification"이라는 프로세스가 있으며 프로그램 실행이 끝날 때 바로 실행되어 결과를 인쇄합니다. 깊이 1 목록의 경우 실제로 각 요소를 문자열 표현으로 변환하고 문자열을 연결하므로 원하는 출력을 얻습니다.

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

1

자바 스크립트, 112110 바이트

길이가 같은 두 가지 대안을 찾았습니다. 카레 구문으로 전화하십시오.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구분 기호 주위의 공백을 제거하십시오 .


자바 스크립트, 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


@ImbodimentofIgnorance 나의 나쁜, 나는 Luis의 의견을 잘못 읽었다. 나는 그것이join .
Arnauld
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.