예쁜 인쇄 다항식


38

소개

인간은 놀라운 종이지만, 특히 컴퓨터에 대해서는 때때로 이해하기가 매우 어려울 수 있습니다. 특히, 우리는 임의의 규칙으로 매우 복잡한 방식으로 다항식을 작성하는 것을 좋아합니다.

이 규칙을 사용하여 다항식을 올바르게 형식화하기 위해 작성할 수있는 가장 짧은 프로그램은 무엇입니까?

도전

입력

다항식의 계수를 나타내는 -1000에서 1000 사이의 정수 목록 (마지막 항목은 x ^ 0 (상수), 두 번째는 x ^ 1의 계수 등임)

산출

올바른 형식의 인간의 수학적 표기법으로이 다항식을 나타내는 문자열입니다.

규칙 :

  • 선행 계수의 부호는 음수 인 경우에만 표시됩니다.

Right: -x^2+3

Wrong: +x^2+3

  • 계수가 0 인 부품은 인쇄되지 않습니다 (모든 계수가 0 * ​​인 코너 케이스 제외).

Right: x^5-x^2+3

Wrong: x^5+0x^4+0x^3-x^2+0x+3

  • 계수 -1와는 +1그들이 일정하지 않는 한, 1없이 표시 할 수 있습니다.

Right: x^5-x^2+1

Wrong: 1x^5-1x^2+1

  • 지수는 1보다 큰 경우에만 표시되고 지수가 0보다 큰 경우에만 변수가 표시됩니다.

Right: 3x^3-7x^2+2x+1

Wrong: 3x^3-7x^2+2x^1+1x^0

  • * Corner case : 값이 0이면 일반적으로 해당 구성 요소를 인쇄하지 않지만 모든 계수가 0이면 상수 0을 인쇄해야합니다.

Right: 0

Wrong: 0x+0

Wrong: (nothing)

  • 이것은 코드 골프이므로 우승자는 가장 적은 바이트를 가진 프로그램이됩니다.

입력 및 출력 예

Input:                  Output:
      [0]                      0
      [0,0]                    0
      [0,-1,35,0]             -x^2+35x
      [5,1,7,-9]               5x^3+x^2+7x-9
      [100,0,0,-1]             100x^3-1
      [931,21,-11,1]           931x^3+21x^2-11x+1

귀하의 솔루션을 기대합니다. 즐기세요!

편집하다:

  • 원하는 경우 공백으로 작업을 둘러 쌀 수 있습니다. 그래서 3x+5하고 3x + 5모두 정상입니다. 3x+ 5그리고 3x +5아닙니다.
  • 인간이 쓰는 방식에 더 가깝기 때문에 실제 지수 문자 (예 : Tex)를 생성하려면 허용됩니다.
  • 계수는 소수점 이하 자릿수없이 표시되어야합니다. 예를 들어 9x^2, 정확 9.0x^2하지 않습니다.

7
샌드 박스에서 질문했지만하지 않은 질문은 연산자 사이에 공백으로 인쇄 할 수 있습니까? 그래서 3x^2 + 43x^2+4?
Giuseppe

1
캐럿을 사용하여 지수를 출력해야합니까? 아니면 실제 위 첨자 문자 생성이 허용됩니까 (예 : TeX의 답변)?
Tutleman

3
@KevinCruijssen 나는 OP가 아니지만 대부분의 인간은 그렇게 쓰지 않기 때문에 그렇지 않다고 말할 것입니다.
ShreevatsaR

2
@ManishKundu 네, 입력을 문자열로 취할 수 있습니다.
Oisín Moran

1
OisínMoran 아무것도 펑키 @ 다만 확실히 간단하게 1x-> x교체는 변경되지 않습니다 21x^22x^2.
DLosc

답변:


10

레티 나 0.8.2 , 56 바이트

(?=( \S+)+)
x^$#1
\b0x.\d+ 

\b1x
x
x.1 
x 
 0

 -
-
 
+

온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다. 설명:

(?=( \S+)+)
x^$#1

x포함 x^1하되 포함 하지 않는 모든 기능을 삽입하십시오 x^0.

\b0x.\d+ 

x계수가 0이지만 후미 0(아직) 가 아닌 모든 거듭 제곱을 삭제합니다 .

\b1x
x

의 승수를 삭제합니다 1(상수는 1아님).

x.1 
x 

삭제 ^1의를 x^1.

 0

남은 것이 아닌 한 상수 0을 삭제하십시오.

 -
-

앞에 공백을 삭제하십시오 -.

 
+

나머지 공백을 +s로 변경하십시오 .


6

자바 스크립트 (ES6) 107 106 바이트

a=>a.map(c=>c?s+=(c>0&&s?'+':_)+(!--e|c*c-1?c:c<0?'-':_)+(e?e-1?'x^'+e:'x':_):e--,e=a.length,_=s='')&&s||0

온라인으로 사용해보십시오!

어떻게?

현재 지수 e를 추적하면서 입력 배열 a [] 의 각 계수 c 에 다음 공식을 적용하여 출력을 작성합니다 .

첫 번째 공식 : 더하기 부호

계수가 엄격하게 양수이고 이것이 출력 표현식의 첫 번째 항이 아닌 경우,를 추가합니다 +. 그렇지 않으면 아무것도 추가하지 않습니다.

c > 0 && s ? '+' : _

두 번째 공식 : 빼기 부호와 계수

지수가 0이거나 계수의 절대 값이 1이 아닌 경우 계수를 추가합니다 (이는 선행을 포함 할 수 있음 -). 그렇지 않으면, -계수가 음수 인 경우 또는 아무것도 추가하지 않습니다.

!--e | c * c - 1 ? c : c < 0 ? '-' : _

세 번째 공식 : 변수와 ​​지수

지수가 0이면 아무것도 추가하지 않습니다. 지수가 1이면 추가 x합니다. 그렇지 않으면 x^지수 가 추가 됩니다.

e ? e - 1 ? 'x^' + e : 'x' : _

이 경우에는 실패합니다 : [0,1,35,0], + x ^ 2로 이어질 것입니다
Makotosan

2
@Makotosan 신고 해 주셔서 감사합니다! 지금은 괜찮을 것입니다.
Arnauld

5

Stax , 37 바이트

┴₧↕ê♦•Vªâÿσ9s╘dσ■à@@ⁿ■o─╦ñºº┌x╡ER▓ δ¿

온라인으로 실행 및 디버깅

압축이 풀린 언 골프 버전입니다.

r{          reverse the input and map using block ...
  |c        skip this coefficient if it's falsy (zero)
  0<.+-@    sign char; e.g. '+'
  _|aYv i!+ abs(coeff)!=1 || i>0
    y$      str(abs(coeff)); e.g. '7'
    z       ""
  ?+        if-then-else, concatenate; e.g. '+7'
  "x^`i"    string template e.g. 'x^3' or 'x^0'
  iJ(T+     truncate string at i*i and trim. e.g. 'x^3' or ''
mr$         re-reverse mapped array, and flatten to string
c43=t       if it starts with '+', drop the first character
c0?         if the result is blank, use 0 instead

이것을 실행


5

파이썬 3, 279 277 258 251 바이트

k=str.replace
def f(x):
 z=len(x)
 y='--'*(['-1']==[c for c in x if'0'!=c][:1])
 for i,v in enumerate(x):
  p=str(z+~i)
  if v in'-1'and~i+z:y+='+x^'+p
  elif'0'!=v:y+='+'+v+'x^'+p
 return y and k(k(k(k(y[1:],'+-','-'),'^1',''),'x^0',''),'-+','-')or 0

문자열 목록으로 입력을받습니다. 이 솔루션은 아직 고도로 골프화되지 않았습니다. 이것은 기본적으로 출력 형식에 맞게 항목을 교체하여 바이트 수를 크게 증가시킵니다.

온라인으로 사용해보십시오!

ovs와 NK1406에 특별한 감사 .


모든 오류를 수정했습니다.
Manish Kundu

당신은 그들을 만들 수 평등 검사 순서를 변경할 수 있습니다 if'0'!=iif'-1'==i.
Zacharý


@ovs 감사합니다
Manish Kundu



4

APL (Dyalog 기본) , 114 (113) 109 107 106 바이트

{{⍵≡'':⍕0⋄⍵↓⍨'+'=⊃⍵}∊⍵{{'1x'≡2↑1↓⍵:¯1⌽1↓1⌽⍵⋄⍵}('-0+'[1+×⍺]~⍕0),∊(U/⍕|⍺),(U←⍺≠0)/(⍵>⍳2)/¨'x'('^',⍕⍵)}¨⌽⍳⍴⍵}

온라인으로 사용해보십시오!

@dzaima 덕분에 -4 바이트!

이것은 확실히 더 아래로 골프 수 있습니다. 이것은 필요합니다⎕IO←0


나는 마지막으로 ... 그 두 바이트를 면도
재커리

3

, 78 바이트

(RV(B."x^"._MERVg)J'+)R[`\b0[^+]+``x.0|\^1|^\++|\++$``\b1x``\++-?`][xx'x_@v]|0

계수를 명령 줄 인수로 사용합니다. 온라인으로 사용해보십시오!

용도 ME(지도-열거) 및 J(조인) 형태의 무언가를 생성 0x^3+-1x^2+35x^1+0x^0한 다음 정규식 교체 한 무리의 적절한 형식으로이 변환 할 수 있습니다.



3

파이썬 3, 161162 바이트

ovs 덕분에 버그가 수정되었습니다.

l=len
lambda p:''.join(['+'*(i>0)*(c>0)+(str(c)[:-1],str(c))[abs(c)!=1or i==l(p)-1]+'x'*(i!=l(p)-1)+('^%d'%(l(p)+~i))*(i<l(p)-2)for i,c in enumerate(p)if c])or'0'

넓히는:

l=len # Alias the len function since we use it a lot
lambda p: ''.join([ # Join a list of strings
    '+'*(i>0)*(c>0) # Prepend a + if this isn't the first term and the coefficient is positive
    + (str(c)[:-1], str(c))[abs(c) != 1 or i == l(p) - 1] # If the coefficient is 1 and this isn't the last term, delete the '1' from the string representation, otherwise just use the string representation
    + 'x' * (i != l(p) - 1) # If this isn't the last term, append an x
    + ('^%d' % (l(p) + ~i)) * (i < l(p) - 2) # If this isn't one of the last two terms, append the exponent
for i, c in enumerate(p) if c]) # Iterating over each coefficient with its index, discarding the term if the coefficient is zero
or '0' # If all of the above resulted in an empty string, replace it with '0'

3

C # , 237 바이트

c=>{var b=1>0;var r="";int l=c.Length;var p=!b;for(int i=0;i<l;i++){int n=c[i];int e=l-1-i;var o=p&&i>0&&n>0?"+":n==-1&&e!=0?"-":"";p=n!=0?b:p;r+=n==0?"":o+(e==0?$"{n}":e==1?$"{n}x":n==1||n==-1?$"x^{e}":$"{n}x^{e}");}return r==""?"0":r;}

1
PPCG에 오신 것을 환영합니다!
Martin Ender

3

클린 , 172 바이트

import StdEnv,Text
r=reverse
@""="0"
@a|a.[size a-1]<'0'=a+"1"=a
? -1="-"
?1=""
?a=a<+""
$l=join"-"(split"+-"(join"+"(r[?v+e\\v<-r l&e<-["","x":map((<+)"x^")[1..]]|v<>0])))

온라인으로 사용해보십시오!


@BMO가 일시적으로 더 많은 골프를 기다리는 중 수정되었습니다.
OUurous

3

Wolfram 언어 / 수학, 39 바이트

TraditionalForm@Expand@FromDigits[#,x]&

온라인으로 사용해보십시오!

올바른 순서로 들어갈 수있는 내장 장치가 있습니다.

이전 솔루션 :

Wolfram 언어 / 수학, 93 바이트

StringReplace[StringRiffle[ToString/@InputForm/@MonomialList@FromDigits[#,x],"+"],"+-"->"-"]&

적어도 나에게 이것은 수학 조작을 위해 설계된 언어의 경우 엄청나게 길다. Expand@FromDigits[#,x]&작동하는 것처럼 보이지만 다항식의 기본 순서는 질문에 필요한 것과 반대이므로 약간의 추가 정보가 필요합니다.

설명

FromDigits[#,x]               converts input list to polynomial (technically converts to a number in base x)
MonomialList@                 gets list of terms of polynomial
InputForm/@                   converts each term to the form a*x^n
ToString/@                    then to a string version of that
StringRiffle[...,"+"]         joins using +'s
StringReplace[...,"+-"->"-"]& replaces +-'s with -'s

SringReplaceStringReplace?
Scott Milner

@ScottMilner 복사 할 때 실수 였을 것입니다. 주목 해 주셔서 감사합니다!
DanTheMan

3

Python3 : 150 146 바이트

f=lambda l:''.join('+-'[a<0]+str(a)[a<0:5*((abs(a)!=1)|(1>i))]+'x^'[:i]+str(i)[:i-1]for i,a in zip(range(len(l)-1,-1,-1),l)if a).lstrip('+')or '0'

(이전 구현) :

f=lambda l: ''.join('+-'[a<0]+str(a)[a<0:5*((abs(a)!=1)|(1>i))]+'x^'[:i]+str(i)[:i-1] for i,a in zip(range(len(l)-1,-1,-1),l) if a).lstrip('+') or '0'

당신은 할 수 있습니다 온라인으로 시도

쿠도스 : @Benjamin


1
Arhg, 알았어요! 공백을 제거하면 4만큼 줄어 듭니다.f=lambda l:''.join('+-'[a<0]+str(a)[a<0:5*((abs(a)!=1)|(1>i))]+'x^'[:i]+str(i)[:i-1]for i,a in zip(range(len(l)-1,-1,-1),l)if a).lstrip('+')or '0'
Benjamin

3

펄 5 -a , 94 바이트

($_=shift@F)&&push@a,@a*!/-/>0&&'+',@F?s/\b1\b//r:$_,@F>0&&'x',@F>1&&'^'.@F while@F;say@a?@a:0

온라인으로 사용해보십시오!


최종 (일정한) 계수가 1 또는 -1 인 경우 올바르게 작동하지 않는 것 같습니다.
nwellnhof

댕 내가 골프를 치는 동안 그것을 깨 뜨렸을 것입니다. 몇 바이트 더 고정했습니다.
Xcali


2

하스켈 , 166163 바이트

g s|l<-length s,v:w:r<-id=<<["- +"!!(1+signum m):(id=<<[show$abs m|abs m>1||e==0]++["x"|e>0]++['^':show e|e>1])|(e,m)<-zip[l-1,l-2..]s,m/=0]=[v|v>'+']++w:r|1<3="0"

온라인으로 사용해보십시오! 사용법 예 : g [0,-1,35,0]yields "-x^2+35x".


약간 더 읽기 쉬운 이전 166 바이트 솔루션 :

0#n=show n
m#n=id=<<[show n|n>1]++"x":['^':show m|m>1]
m%0=""
m%n|n<0='-':m#(-n)|1<3='+':m#n
g s|l<-length s,v:m:r<-id=<<zipWith(%)[l-1,l-2..]s=[v|v>'+']++m:r|1<3="0"

온라인으로 사용해보십시오!


2

루비 , 111 바이트

->a{i=a.size;s=a.map{|x|i-=1;"%+d"%x+[?x,"x^#{i}",""][i<=>1]if x!=0}*'';s[0]?s.gsub(/(?<!\d)1(?=x)|^\+/,""):?0}

온라인으로 사용해보십시오!

루비 에서이 문제를 해결하는 것은 대부분 실망 스럽습니다. 주로 대부분의 언어와는 달리 루비 (거의)는 0과 빈 문자열을 포함하여 모든 것이 진실이므로 0에 대한 간단한 검사조차도 거의 불가능합니다. 만큼 짧습니다 x?.

나는 문자열을 구성하는 다양한 방법으로 연주했으며 궁극적으로 여러 가지 접근법을 혼합하여 정착했습니다.

  • 계수가 0 인 항은 간단한 조건을 사용하여 삭제됩니다.
  • +-징후는 강제 기호 구문을 서식에 의해 생성된다 :%+d
  • x^i로켓 연산자 인덱싱을 사용하여 올바른 형식 또는 선택[...][i<=>1]
  • 선행 + 및 불필요한 1은 정규식 교체로 제거됩니다.

2

껍질 , 44 43 41 40 바이트

|s0Ψf¤|□ṁ`:'+f¹zμ+↓s²_&ε²¹↑□¹+"x^"s)¹m←ṡ

온라인으로 사용해보십시오!

이것은 약간 어렴풋한 느낌입니다. Husk는 문자열 조작에 최적화되어 있지 않습니다. 나는 Stax 답변 에서 몇 가지 아이디어를 빌렸다 .

설명

         Implicit input, say L = [2,-3,0,-1].
         First we compute the exponents.
ṡ        Reversed indices: [4,3,2,1]
m←       Decrement each: [3,2,1,0]
         Then we format the individual terms of the polynomial.
zμ...)¹  Zip with L using two-argument lambda:
          Arguments are coefficient and index, say C = -3 and I = 2.
+"x^"s    Convert I to string and concatenate to "x^": "x^2"
↑□¹       Take first I*I characters (relevant when I = 0 or I = 1): "x^2"
_&ε²¹     Check if abs(C) <= 1 and I != 0, negate; returns -1 if true, 0 if false.
↓s²       Convert C to string and drop that many elements (from the end, since negative).
          Result: "-3"
          The drop is relevant if C = 1 or C = -1.
+         Concatenate: "-3x^2"
         Result of zipping is ["2x^3","-3x^2","x","-1"]
f¹       Keep those where the corresponding element of L is nonzero: ["2x^3","-3x^2","-1"]
         Next we join the terms with + and remove extraneous +s.
ṁ        Map and concatenate
`:'+      appending '+': "2x^3+-3x^2+-1+"
Ψf       Adjacent filter: keep those chars A with right neighbor B
¤|□       where at least one of A or B is alphanumeric: "2x^3-3x^2-1"
|s0      Finally, if the result is empty, return "0" instead.

2

펄 6 , 97 바이트

{$!=+$_;.map({('+'x?($_&&$++&$_>0)~.substr(--$!&&2>.abs)~(<<''x>>[$!]//'x^'~$!))x?$_}).join||'0'}

온라인으로 사용해보십시오!

설명:

$!=+$_;

$! 현재 지수를 추적합니다.

'+'x?($_&&$++&$_>0)

+0이 아닌 첫 번째 계수를 제외하고 양의 계수 앞에 추가하십시오 . $_&&단락 익명 상태 변수를 확인하게 $만 비 - 제로 계수들에 대해 증가된다. &와 BOOL 강제로 접합 할 때 접힐 ?.

.substr(--$!&&2>.abs)

감소 $!. 상수가 아닌 한 1 또는 -1 계수를 잘라냅니다.

<<''x>>[$!]//'x^'~$!

특수한 경우 선형 및 상수 항. 따옴표로 보호하는 << >> 구문을 사용하는 것은 동등한 ('','x')또는 1 바이트보다 짧습니다 2>$!??'x'x$!!!'x^'~$!.

x?$_

제로 항을 숨기지 만 항상 --$!부작용에 대한 앞의 표현을 평가하십시오 .

||'0'

0모든 계수가 0이면 반환


2

자바 (8) 202 176 174 173 바이트

a->{String r="";int j=a.length;for(int i:a)r+=i==0*j--?"":"+"+i+(j<1?"":j<2?"x":"x^"+j);return r.isEmpty()?"0":r.substring(1).replace("+-","-").replaceAll("(\\D)1x","$1x");}
  • @Nevay 덕분에 26 바이트 .

설명:

온라인으로 사용해보십시오.

a->{                     // Method with String-array parameter and String return-type
  String r="";           //  Result-String, starting empty
  int j=a.length;        //  Power-integer, starting at the size of the input-array
  for(int i:a)           //  Loop over the array
    r+=i==0              //   If the current item is 0
           *j--?         //   (And decrease `j` by 1 at the same time)
        ""               //    Append the result with nothing
       :                 //   Else:
        "+"              //    Append the result with a "+",
        +i               //    and the current item,
        +(j<1?           //    +If `j` is 0:
           ""            //      Append nothing more
          :j<2?          //     Else-if `j` is 1:
           "x"           //      Append "x"
          :              //     Else:
           "x^"+j);      //      Append "x^" and `j`
  return r.isEmpty()?    //  If `r` is still empty
    "0"                  //   Return "0"
   :                     //  Else:
    r.substring(1)       //   Return the result minus the leading "+",
     .replace("+-","-")  //   and change all occurrences of "+-" to "-",
     .replaceAll("(\\D)1x","$1x");}
                         //   and all occurrences of "1x" to "x"

1
176 바이트 :a->{String r="";int j=a.length;for(int u:a)r+=u==(j^j--)?"":"+"+u+(j<1?"":j<2?"x":"x^"+j);return r.isEmpty()?"0":r.substring(1).replace("+-","-").replaceAll("([+-])1x","$1x");}
Nevay

1
@Nevay 나는 이제 모든 입력이 정수임을 깨달았다. 십진수 입력도 허용된다고 생각했기 때문에 String-input을 사용했다. 그리고로 변경 (j^j--)하여 2 개 더 골프를 탈 수있었습니다 0*j--.
Kevin Cruijssen

2

파이썬, 165 바이트

lambda a:"".join([("+"if c>0 and i+1<len(a)else"")+(str(c)if i==0 or abs(c)!=1 else "")+{0:"",1:"x"}.get(i,"x^"+str(i))for i,c in enumerate(a[::-1])if c][::-1])or"0"

1

PHP, 213 바이트

$p=0;for($i=count($a=array_reverse(explode(',',trim($argv[1],'[]'))))-1;$i>=0;$i--)if(($b=(float)$a[$i])||(!$i&&!$p)){$k=abs($b);echo ($b<0?'-':($p?'+':'')).((($k!=1)||!$i)?$k:'').($i>1?'x^'.$i:($i?'x':''));$p=1;}

OP에서 요청한 명령 줄 인수 (괄호와 쉼표가있는 단일 인수)

예쁜 글씨와 설명 :

$p = false; /* No part of the polynomial has yet been printed. */
for ($i = count($a = array_reverse(explode(',',trim($argv[1],'[]')))) - 1; $i >= 0; $i--)
{
    $b = (float)$a[$i]; /* Cast to float to avoid -0 and numbers like 1.0 */
    if (($b != 0) or (($i == 0) and !$p)) /* Print, if $b != 0 or the constant if there is no part until here. */
    {
        $k = abs($b);
        echo ($b < 0 ? '-' : ( $p ? '+' : '')); /* Sign. The first sign is suppressed (if $p is false) if $b positive. */
        echo ((($k != 1) || ($i == 0)) ? $k : '');  /* Coefficient */
        echo ($i > 1 ? 'x^' . $i : (($i != 0) ? 'x' : ''));  /* x^3, x^2, x, constant with empty string. */
        $p = true; /* Part of the polynomial has been printed. */
    }
}

1

PowerShell, 295 바이트

$c=$args[0]
$p=$c.length-1
$i=0
$q=""
while($p -ge 0){$t="";$e="";$d=$c[$i];switch($p){0{$t=""}1{$t="x"}Default{$t="x^";$e=$p}}if($d-eq 0){$t=""}elseif($d-eq 1){$t="+$t$e"}elseif($d-eq-1){$t="-$t$e"}elseif($d-lt 0 -or$i -eq 0){$t="$d$t$e"}else{$t="+$d$t$e"}$q+=$t;$i++;$p--}if($q -eq""){$q=0}
$q
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.