Całkiem drukowane wielomiany


38

Wprowadzenie

Ludzie są niezwykłym gatunkiem, ale czasami możemy być bardzo niezręczni, aby zrozumieć - szczególnie w przypadku komputerów. W szczególności lubimy pisać wielomiany w bardzo zawiły sposób z pozornie arbitralnymi regułami.

Jaki jest najkrótszy program, który możesz napisać, aby poprawnie sformatować wielomian przy użyciu tych reguł?

Wyzwanie

Wkład

Lista liczb całkowitych z zakresu od -1000 do 1000 (włącznie), reprezentujących współczynniki wielomianu, przy czym ostatni wpis jest współczynnikiem x ^ 0 (stała), a drugi ostatni jest współczynnikiem x ^ 1 itp.

Wydajność

Ciąg reprezentujący ten wielomian w poprawnie sformatowanym zapisie matematycznym ludzi.

Zasady:

  • Znak na wiodącym współczynniku jest wyświetlany tylko wtedy, gdy jest ujemny.

Right: -x^2+3

Wrong: +x^2+3

  • Składniki o współczynniku 0 nie są drukowane (z wyjątkiem przypadku w rogu, w którym wszystkie współczynniki mają wartość 0 *).

Right: x^5-x^2+3

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

  • Współczynniki -1i +1mają być wyświetlane bez 1, chyba że są stałe.

Right: x^5-x^2+1

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

  • Wykładnik jest wyświetlany tylko wtedy, gdy jest większy niż 1, a zmienna jest wyświetlana tylko wtedy, gdy wykładnik jest większy niż 0.

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

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

  • * Przypadek narożny: podczas gdy wartości zerowe zwykle nie powodują drukowania tego elementu, jeśli wszystkie współczynniki są równe zero, należy wydrukować stałą 0.

Right: 0

Wrong: 0x+0

Wrong: (nothing)

  • To jest golf golfowy, więc zwycięzcą zostanie program z najmniejszą liczbą bajtów.

Przykład wejścia i wyjścia

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

Czekam na Wasze rozwiązania. Baw się dobrze!

EDYTOWAĆ:

  • Jeśli chcesz, możesz otaczać operacje białymi znakami. Więc 3x+5i 3x + 5oba są w porządku. 3x+ 5i 3x +5nie są.
  • Jeśli chcesz tworzyć rzeczywiste znaki wykładnicze (powiedzmy w Tex), jest to dozwolone, ponieważ jest jeszcze bliżej pisania przez ludzi.
  • Współczynniki muszą pojawiać się bez miejsc po przecinku, np. Są 9x^2poprawne, 9.0x^2nie są.

7
Pytanie, które powinienem zadać w piaskownicy, ale nie dało się, czy możemy drukować z odstępami między operatorami? Więc 3x^2 + 4kontra 3x^2+4?
Giuseppe

1
Czy musimy generować wykładniki za pomocą karetek? Czy też dozwolone byłoby tworzenie rzeczywistego znaku górnego (np. Dla odpowiedzi w TeX-ie)?
Tutleman

3
@KevinCruijssen Nie jestem OP, ale powiedziałbym, że nie, ponieważ większość ludzi tak nie pisze.
ShreevatsaR

2
@ManishKundu Tak, możesz wziąć dane wejściowe jako ciągi znaków.
Oisín Moran

1
@ OisínMoran Nic funky, tylko upewnienie się, że prosta 1x-> xzamiana nie zmieni się 21x^2w 2x^2.
DLosc

Odpowiedzi:


10

Retina 0.8.2 , 56 bajtów

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

\b1x
x
x.1 
x 
 0

 -
-
 
+

Wypróbuj online! Link zawiera przypadki testowe. Wyjaśnienie:

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

Wstaw wszystkie uprawnienia x, w tym, x^1ale nie x^0.

\b0x.\d+ 

Usuń wszystkie potęgi o xzerowych współczynnikach, ale nie kończących 0(jeszcze).

\b1x
x

Usuń mnożnik 1(ale nie stałą 1).

x.1 
x 

Usuń ^1z x^1.

 0

Usuń stałą 0, chyba że jest to jedyna rzecz, która pozostała.

 -
-

Usuń spację przed a -.

 
+

Zmień pozostałe spacje na +s.


6

JavaScript (ES6), 107 106 bajtów

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

Wypróbuj online!

W jaki sposób?

Dane wyjściowe są budowane przez zastosowanie następujących wzorów do każdego współczynnika c tablicy wejściowej a [], jednocześnie śledząc bieżący wykładnik e .

Pierwsza formuła: znak plus

Jeśli współczynnik jest ściśle dodatni i nie jest to pierwszy termin w wyrażeniu wyjściowym, dołączamy +. W przeciwnym razie nic nie dodamy.

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

Drugi wzór: znak minus i współczynnik

Jeśli wykładnik wynosi zero lub wartość bezwzględna współczynnika nie jest równa 1, dodajemy współczynnik (który może obejmować interlinię -). W przeciwnym razie dołączamy albo -(jeśli współczynnik jest ujemny), albo nic.

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

Trzecia formuła: zmienna i wykładnik

Jeśli wykładnik wynosi 0, nic nie dodajemy. Jeśli wykładnik wynosi 1, dodajemy x. W przeciwnym razie dodajemy x^wykładnik.

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

Nie udaje się to w tym przypadku: [0,1,35,0], doprowadzi z + x ^ 2
Makotosan

2
@Makotosan Dziękujemy za zgłoszenie tego! Teraz powinno być OK.
Arnauld

5

Stax , 37 bajtów

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

Uruchom i debuguj online

Oto rozpakowana, nie golfowa wersja.

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

Uruchom ten


5

Python 3, 279 277 258 251 bajtów

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

Pobiera dane wejściowe jako listę ciągów. To rozwiązanie nie jest jeszcze dobrze golfowane. Zasadniczo działa to poprzez zastąpienie rzeczy dopasowanych do formatu wyjściowego, co znacznie zwiększa liczbę bajtów.

Wypróbuj online!

Specjalne podziękowania dla ovs i NK1406 .


Naprawiono wszystkie błędy.
Manish Kundu

Możesz zmienić kolejność kontroli równości, aby je wykonać if'0'!=ii if'-1'==i.
Zacharý


@ovs wielkie dzięki
Manish Kundu



4

APL (Dyalog Classic) , 114 113 109 107 106 bajtów

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

Wypróbuj online!

-4 bajty dzięki @dzaima!

Można to zdecydowanie pograć w golfa dalej. To wymaga⎕IO←0


W końcu ogoliłem te dwa bajty ...
Zacharý

3

Pip , 78 bajtów

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

Przyjmuje współczynniki jako argumenty wiersza polecenia. Wypróbuj online!

Używa ME(map-enumerate) i J(join), aby wygenerować coś z formularza 0x^3+-1x^2+35x^1+0x^0, a następnie kilka zamienników wyrażeń regularnych, aby przekształcić to we właściwy format.



3

Python 3, 161 162 bajty

Naprawiono błąd dzięki OV.

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'

Rozszerzony:

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 bajtów

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
Witamy w PPCG!
Martin Ender

3

Czysty , 172 bajty

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

Wypróbuj online!


@BMO naprawiono tymczasowo w oczekiwaniu na więcej golfa.
Οurous

3

Wolfram Language / Mathematica, 39 bajtów

TraditionalForm@Expand@FromDigits[#,x]&

Wypróbuj online!

Okazuje się, że jest wbudowany, aby wejść w odpowiedniej kolejności.

Poprzednie rozwiązanie:

Wolfram Language / Mathematica, 93 bajty

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

Przynajmniej dla mnie jest to zadziwiająco długo jak na język przeznaczony do manipulacji matematycznych. Wygląda na to, że Expand@FromDigits[#,x]&powinno działać, ale domyślna kolejność wielomianów jest odwrotnością tego, czego wymaga pytanie, więc wymagane jest dodatkowe finansowanie.

Wyjaśnienie

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

Nie powinno SringReplacebyć StringReplace?
Scott Milner,

@ScottMilner Musiałem się pomylić, kiedy go kopiowałem. Dzięki za zauważenie tego!
DanTheMan

3

Python3: 150 146 bajtów

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'

(poprzednie wdrożenia):

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'

Możesz spróbować online

Uznanie dla: @Benjamin


1
Arhg, złap mnie! Obniżasz go o 4, usuwając niektóre spacje: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 bajtów

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

Wypróbuj online!


Nie działa poprawnie, jeśli ostateczny (stały) współczynnik wynosi 1 lub -1.
nwellnhof

Dang. Musiałem to złamać, kiedy grałem w golfa. Naprawiono to o kilka dodatkowych bajtów.
Xcali,

2

Retina 0.8.2 , 113 bajtów

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

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

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

^$
0
 
+

Wypróbuj online!

Jestem pewien, że jest tu wiele do golfa ...


2

Haskell , 166 163 bajtów

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"

Wypróbuj online! Przykładowe użycie: g [0,-1,35,0]daje "-x^2+35x".


Poprzednie 166 bajtowe rozwiązanie, które jest nieco lepiej czytelne:

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"

Wypróbuj online!


2

Rubin , 111 bajtów

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

Wypróbuj online!

Rozwiązanie tego w Ruby okazało się nieco frustrujące, głównie dlatego, że w przeciwieństwie do większości języków, w Ruby (prawie) wszystko jest zgodne z prawdą, w tym zera i puste ciągi, tak więc nawet proste sprawdzenie zera nie zbliża się wcale tak krótki jak x? .

Grałem różnymi metodami konstruowania struny i ostatecznie zdecydowałem się na połączenie kilku podejść:

  • Terminy z 0 współczynnikami są usuwane przy użyciu prostego warunku
  • +a -znaki są tworzone przez formatowanie składni ze znakiem wymuszonym:%+d
  • Prawidłową formę lub x^iwybiera się za pomocą indeksowania operatora rakiet[...][i<=>1]
  • Wiodące + i niepotrzebne 1-s są usuwane przez zamienniki wyrażeń regularnych

2

Łuska , 44 43 41 40 bajtów

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

Wypróbuj online!

To wydaje się trochę niezręczne; Łuska nie jest zoptymalizowana do manipulacji ciągami. Pożyczyłem kilka pomysłów od odpowiedzi Staxa .

Wyjaśnienie

         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 bajtów

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

Wypróbuj online!

Wyjaśnienie:

$!=+$_;

$! śledzi bieżący wykładnik potęgi.

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

Dodaj +przed dodatnimi współczynnikami, chyba że jest to pierwszy niezerowy. $_&&Zwarcie daje pewność, że zmienna stan anonimowy $jest zwiększany tylko dla niezerowych współczynników. &Skrzyżowanie jest zwinięty, gdy zmuszona do Bool z ?.

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

Ubytek $!. Posiekaj współczynnik 1 lub -1, chyba że jest stały.

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

Warunki liniowe i stałe w szczególnych przypadkach. Użycie << >> konstruktu chroniącego cytaty jest o jeden bajt krótszy niż odpowiednik ('','x')lub 2>$!??'x'x$!!!'x^'~$!.

x?$_

Ukryj warunki zerowe, ale zawsze oceniaj poprzednie wyrażenie dla --$!efektu ubocznego.

||'0'

Zwróć, 0jeśli wszystkie współczynniki są równe zero.


2

Java 8, 202 176 174 173 bajtów

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");}
  • 26 bajtów dzięki @Nevay .

Wyjaśnienie:

Wypróbuj online.

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 bajtów: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
@Nie wiem, dopiero teraz zdaję sobie sprawę, że wszystkie dane wejściowe są liczbami całkowitymi .. Użyłem danych wejściowych typu String, ponieważ myślałem, że również dane dziesiętne są dozwolone ..>.> W każdym razie dzięki za -26 bajtów. I byłem w stanie zagrać w golfa jeszcze 2, zmieniając (j^j--)na 0*j--.
Kevin Cruijssen

2

Python, 165 bajtów

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 bajtów

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

Argument wiersza poleceń zgodnie z żądaniem OP (pojedynczy argument z nawiasami i przecinkami).

Ładny druk i wyjaśnienie:

$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 bajtów

$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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.