漂亮的印刷多项式


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

  • *正确的情况:虽然零值通常会导致不打印该组件,但如果所有系数均为零,则应打印常数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+53x + 5都很好。3x+ 5而且3x +5不是。
  • 如果要生成实际的指数字符(例如在Tex中),则可以使用,因为它与人类的书写方式更加接近。
  • 系数必须没有小数点出现,例如9x^2正确,错误9.0x^2

7
我应该在沙箱中问过一个问题,但没有,我们可以在操作员之间使用空格打印吗?那么3x^2 + 43x^2+4
朱塞佩

1
我们是否需要使用插入符号输出指数?还是会允许产生一个实际的上标字符(例如在TeX中回答)?
Tutleman

3
@KevinCruijssen我不是OP,但我不会说,因为大多数人不会那样写。
ShreevatsaR

2
@ManishKundu是的,您可以将输入作为字符串。
[287]莪莫兰

1
@OisínMoran没什么特别的,只是确保简单的1x-> x替换不会21x^2变成2x^2
DLosc

Answers:


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(尚未)。

\b1x
x

删除的乘数1(但不是常数1)。

x.1 
x 

删除^1x^1

 0

除非它是唯一剩下的,否则删除一个常数0。

 -
-

删除-。之前的空格。

 
+

将所有剩余空间更改为+s。


6

的JavaScript(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 ? '+' : _

第二个公式:负号和系数

如果指数为零或系数的绝对值不等于1,我们会附加系数(可能包括前导-)。否则,我们将添加一个-(如果系数为负)或不添加任何内容。

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

第三个公式:变量和指数

如果指数为0,则不附加任何内容。如果指数为1,则追加x。否则,我们追加x^指数。

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

在这种情况下,此操作将失败:[0,1,35,0],它将以+ x ^ 2
开头

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

Python 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
扎卡里


@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'('^',⍕⍵)}¨⌽⍳⍴⍵}

在线尝试!

-4个字节感谢@dzaima!

无疑,这可以进一步进行下去。这需要⎕IO←0


我终于剃光这两个字节关闭...
扎卡里

3

,78字节

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

将系数作为命令行参数。在线尝试!

使用ME(map-enumerate)和J(join)生成某种形式的0x^3+-1x^2+35x^1+0x^0,然后使用大量正则表达式替换将其转换为正确的格式。



3

Python 3中,161个 162字节

修复了由于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暂时修复,等待更多打高尔夫球。
Οurous

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

SringReplace应该StringReplace吗?
Scott Milner '18

@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
啊,明白了!您可以通过删除一些空格将其降低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

Perl -a 5,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

ang 我打高尔夫球时肯定已经打破了。修复了几个字节。
Xcali


2

哈斯克尔166个 163字节

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}

在线尝试!

事实证明,在Ruby中解决此问题有点令人沮丧,这主要是因为与大多数语言不同,在Ruby中(几乎)一切都是真实的,包括0-s和空字符串,因此即使是简单的零检查也变得遥不可及短于x?

我玩过各种构造字符串的方法,最终选择了几种方法:

  • 使用简单的条件来删除系数为0的项
  • +-符号是通过使用强制符号格式化语法来产生的:%+d
  • 正确的格式或x^i使用火箭操作员索引选择[...][i<=>1]
  • 正则表达式替换会删除前导+和不必要的1-s

2

外壳44 43 41 40字节

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

在线尝试!

感觉有点笨拙。外壳没有针对字符串操作进行优化。我从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

Perl 6、97字节

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

在线尝试!

说明:

$!=+$_;

$! 跟踪当前指数。

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

+在正系数之前加上,除非它是第一个非零的。的$_&&短路可确保匿名状态变量$仅递增非零系数。&当用强制将其连接到Bool时,结点已折叠?

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

减量$!。除非恒定,否则将系数1或-1砍掉。

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

特殊情况下的线性和常数项。使用引用保护<< >> 结构比等效的('','x')或短一个字节2>$!??'x'x$!!!'x^'~$!

x?$_

隐藏零项,但始终会评估前面的表达式的--$!副作用。

||'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我现在才意识到所有输入都是整数。我使用了字符串输入,因为我认为也允许十进制输入。>>>不管怎么说,感谢-26字节。通过更改(j^j--)为,我已经可以再打2球0*j--
凯文·克鲁伊森

2

Python,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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.