Güzel Baskı Polinomları


38

Giriş

İnsanlar dikkate değer bir türdür, ancak bazen bilgisayarları anlamak bazen çok garip olabilir. Özellikle, polinomları görünüşte keyfi kurallarla çok karmaşık bir şekilde yazmaktan hoşlanıyoruz.

Bir polinomu bu kuralları kullanarak doğru bir şekilde formatlamak için yazabileceğiniz en kısa program nedir?

Meydan okuma

Giriş

Bir polinomun katsayılarını temsil eden -1000 ila 1000 (dahil) arasında bir tamsayı listesi, son giriş x ^ 0 (sabit) katsayısı, ikinci son x ^ 1 katsayısı, vb.

Çıktı

Bu polinomu, insanların doğru şekilde biçimlendirilmiş matematiksel gösterimlerinde temsil eden bir dize.

Kurallar:

  • Önde gelen katsayı üzerindeki işaret yalnızca negatifse gösterilir.

Right: -x^2+3

Wrong: +x^2+3

  • 0 katsayılı bileşenler yazdırılmaz (tüm katsayıların 0 * olduğu köşe durumu hariç).

Right: x^5-x^2+3

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

  • Katsayılar -1ve +1sabit olmadıkça 1 olmadan gösterilmelidir.

Right: x^5-x^2+1

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

  • Üssü yalnızca 1'den büyükse gösterilir ve değişken yalnızca üs, 0'dan büyükse gösterilir.

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

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

  • * Köşe kutusu: sıfır değerler genellikle bu bileşenin yazdırılmamasına neden olurken, tüm katsayılar sıfırsa, 0 sabiti yazdırılmalıdır.

Right: 0

Wrong: 0x+0

Wrong: (nothing)

  • Bu kod-golf olduğundan kazanan en az baytlık program olacak.

Örnek Giriş ve Çıkış

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

Çözümlerinizi görmeyi dört gözle bekliyorum. İyi eğlenceler!

DÜZENLE:

  • İsterseniz işlemleri boşluk ile çevreleyebilirsiniz. Yani 3x+5ve 3x + 5her ikisi de iyi. 3x+ 5ve 3x +5değil.
  • İnsanların nasıl yazdıklarına daha yakın olduğu için izin verilen gerçek üstel karakterleri (Tex'de söyleyin) üretmek istiyorsanız.
  • Katsayılar herhangi bir ondalık sayı olmadan görünmelidir, örneğin 9x^2doğru, 9.0x^2öyle değil.

7
Sanal alanda sormam gereken bir soru vardı ama yapmadım, operatörler arasındaki boşlukla yazdırabilir miyiz? Yani 3x^2 + 4karşı 3x^2+4?
Giuseppe

1
Balet kullanarak üs üretmemize gerek var mı? Yoksa gerçek bir üst simge karakterinin üretilmesine izin verilir mi (örneğin, TeX’te bir cevap için)?
Tutleman

3
@KevinCruijssen Ben OP değilim, ama söyleyemem çünkü çoğu insan böyle yazmaz.
ShreevatsaR

2
@ManishKundu Evet, girişi dizge olarak alabildiğinizden emin olun.
Oisín Moran

1
OisínMoran Hiçbir şey korkak @, sadece emin bir basit hale 1x-> xyedek değişmez 21x^2içine 2x^2.
DLosc

Yanıtlar:


10

Retina 0.8.2 , 56 bayt

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

\b1x
x
x.1 
x 
 0

 -
-
 
+

Çevrimiçi deneyin! Link, test durumlarını içerir. Açıklama:

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

xDahil x^1ancak olmasın tüm güçlerini ekleyin x^0.

\b0x.\d+ 

xSıfır katsayılı tüm güçleri silin , ancak bir son değil 0(henüz).

\b1x
x

Çarpanını silin 1(ancak sabit değil 1).

x.1 
x 

Sil ^1OF x^1.

 0

Geriye kalan tek şey değilse, 0 sabitini silin.

 -
-

Boşluktan önce silme a -.

 
+

Kalan boşlukları +s olarak değiştirin.


6

JavaScript (ES6), 107 106 bayt

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

Çevrimiçi deneyin!

Nasıl?

Çıktı, her katsayı için aşağıdaki formülleri uygulayarak oluşturulur c giriş dizisi bir a [] , mevcut üs takip ederken e .

1. formül: artı işareti

Katsayı kesinlikle pozitif ise ve bu çıktı ifadesindeki ilk terim değilse, a eklenir +. Aksi takdirde, hiçbir şey eklemeyiz.

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

2. formül: eksi işareti ve katsayısı

Üssü sıfırsa veya katsayının mutlak değeri 1'e eşit değilse, katsayısı ekleriz (ki bu bir satır aralığı içerebilir -). Aksi takdirde, -(katsayı negatifse) ya da hiçbir şey ekleriz.

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

3. formül: değişken ve üs

Üssü 0 ise, hiçbir şey eklemeyiz. Üssü 1 ise, ekleriz x. Aksi takdirde x^üs , ardından üs ekleriz.

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

Bu durumda başarısız olur: [0,1,35,0], + x ^ 2 ile
sonuçlanacaktır

2
@Makotosan Bunu bildirdiğin için teşekkürler! Şimdi iyi olmalı.
Arnauld,

5

Stax , 37 bayt

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

Çevrimiçi çalıştırın ve hata ayıklayın

İşte paketlenmemiş, sürümsüz versiyonu.

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

Bunu çalıştır


5

Python 3, 279 277 258 251 bayt

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

Dizelerin bir listesi olarak girdi alır. Bu çözüm henüz pek golf oynamadı. Bu temelde, çıktı formatına uygun olanları değiştirerek çalışır, bu da bayt sayısını arttırır.

Çevrimiçi Deneyin!

Ovs ve NK1406'ya özel teşekkürler .


Tüm hatalar düzeltildi.
Manish Kundu

Bunları yapmak için size eşitlik kontrolleri yeniden sıralayabilirsiniz if'0'!=ive if'-1'==i.
Zacharý


teşekkür @ovs çok
Manish Kundu



4

APL (Dyalog Classic) , 114 113 109 107 106 bayt

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

Çevrimiçi deneyin!

@Dzaima sayesinde -4 bayt!

Bu kesinlikle daha fazla golf oynayabilir. Bu gerektirir⎕IO←0


Sonunda bu iki
byte'ı

3

Pip , 78 bayt

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

Katsayıları komut satırı argümanları olarak alır. Çevrimiçi deneyin!

Formdan bir şey üretmek için ME(map-enumerate) ve J(join) kullanır 0x^3+-1x^2+35x^1+0x^0ve ardından bunu uygun formata dönüştürmek için bir grup regex değiştirmesi yapar.



3

Python 3, 161 162 bayt

Ovs sayesinde bir hata düzeltildi.

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'

Expanded:

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 bayt

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'ye Hoşgeldiniz!
Martin Ender

3

Temiz , 172 bayt

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

Çevrimiçi deneyin!


@ BMO geçici olarak daha fazla golf beklemede kaldı.
Büyük

3

Wolfram Dili / Mathematica, 39 bayt

TraditionalForm@Expand@FromDigits[#,x]&

Çevrimiçi deneyin!

Doğru sırayla almak için bir yerleşik olduğu ortaya çıkıyor.

Önceki çözüm:

Wolfram Dili / Mathematica, 93 bayt

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

En azından benim için, bu matematiksel manipülasyon için tasarlanmış bir dil için şaşırtıcı derecede uzun. İşe Expand@FromDigits[#,x]&yarayacak gibi görünüyor , ancak polinomlar için varsayılan sıralama, sorunun ne gerektirdiğinin tersidir, bu yüzden bazı ekstra finagling gereklidir.

açıklama

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

Gerekmiyor SringReplaceolmak StringReplace?
Scott Milner

@ScottMilner Üzerine kopyalarken hata yapmış olmalıyım. Fark ettiğiniz için teşekkürler!
DanTheMan

3

Python3: 150 146 bayt

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'

(önceki uygulamalar):

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'

Şunları yapabilirsiniz çevrimiçi denemek

Kudos şunun için: @Benjamin


1
Arhg, anladım! Bazı boşlukları kaldırarak 4 ile aşağı indirdi: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 5 -a , 94 bayt

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

Çevrimiçi deneyin!


Son (sabit) katsayısı 1 veya -1 ise, doğru çalışmıyor gibi görünüyor.
nwellnhof

Dang. Ben golf oynarken kırmış olmalı. Birkaç byte ile düzeltildi.
Xcali

2

Retina 0.8.2 , 113 bayt

\w+
a$'b$&
a( [^b ]*)*?b(\d+)
$2x^$#1
(\^1|x\^0)(?!\d)

(?<= |-|^)(1(?=x)|0[^ -]*)

([ -])*
$1
[ -]$|^ 

^$
0
 
+

Çevrimiçi deneyin!

Eminim burada golf oynayacak çok şey var.


2

Haskell , 166 163 bayt

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"

Çevrimiçi deneyin! Örnek kullanım: g [0,-1,35,0]verim "-x^2+35x".


Önceki 166 byte çözüm, ki biraz daha iyi okunabilir:

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"

Çevrimiçi deneyin!


2

Ruby , 111 bayt

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

Çevrimiçi deneyin!

Bunu Ruby'de çözmek, temelde çoğu dilde olduğu gibi, Ruby'de (neredeyse) her şeyin asılsız olmasından dolayı 0-s ve boş dizeler de dahil olmak üzere, biraz sinir bozucu olduğu ortaya çıktı. kadar kısa x?.

İpin yapımında çeşitli yöntemler kullandım ve nihayetinde birkaç yaklaşımın karışımına yerleştim:

  • 0 katsayılı terimler basit bir koşullu
  • +ve -işaretler, zorunlu işaret ile sözdizimi biçimlendirilerek üretilir:%+d
  • Doğru form veya x^iroket operatörü indeksleme kullanılarak seçilir[...][i<=>1]
  • Önde gelen + ve gereksiz 1-ler, regex değişimleriyle kaldırılır

2

Kabuk , 44 43 41 40 bayt

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

Çevrimiçi deneyin!

Bu biraz tıknaz hissediyor; Kabuk, dize manipülasyonu için optimize edilmemiş. Stax'ın cevabından bazı fikirler aldım .

açıklama

         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 bayt

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

Çevrimiçi deneyin!

Açıklama:

$!=+$_;

$! Geçerli üslerin kaydını tutar.

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

+Sıfır olmayan ilk kişi hariç, pozitif katsayılardan önce ekleyin . $_&&Kısa devre anonim durum değişkeni kesinleştirir $sadece sıfır olmayan katsayı için artırılır. &İle Bool zorlanır zaman birleşme daraltılmış ?.

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

Azaltma $!. Sabit olmadıkça 1 veya -1 katsayısını kesin.

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

Özel durum doğrusal ve sabit terimler. Alıntı koruma << >> yapısının kullanılması, eşdeğer ('','x')ya da eşdeğerinden daha kısa olan bir bayttır 2>$!??'x'x$!!!'x^'~$!.

x?$_

Sıfır terimlerini gizleyin, ancak her zaman --$!yan etki için önceki ifadeyi değerlendirin .

||'0'

0Tüm katsayılar sıfırsa, geri dönün .


2

Java 8, 202 176 174 173 bayt

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 sayesinde 26 bayt .

Açıklama:

Çevrimiçi deneyin.

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 bayt: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 Sadece şimdi tüm girdilerin tamsayı olduğunun farkındayım .. Dize-giriş kullandım çünkü ondalık girişlere izin verildiğini de düşündüm ..>.> Neyse, -26 bayt için teşekkürler. Ve daha değiştirerek golf 2 almaya başladık (j^j--)için 0*j--.
Kevin Cruijssen

2

Python, 165 bayt

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 Bayt

$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'nin istediği gibi komut satırı argümanı (parantez ve virgül içeren tek argüman).

Güzel baskı ve bazı açıklamalar:

$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 bayt

$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
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.