Grundlegende algebraische Erweiterung

8

Problem

Ich habe ein GROSSARTIGES neues Programm, das die Art und Weise verändern wird, wie wir über Mathematik im Computer denken, algebraische Funktionen aufnehmen und ERSTAUNLICHE Dinge damit machen! Das einzige Problem ist, dass ich nur bestimmte Algebra analysieren kann, sonst faltet sich das Universum in sich zusammen, was schlecht ist. Glücklicherweise brauche ich nur ein paar grundlegende Operationen in der Eingabe dieses erstaunlichen neuen Programms, aber ich brauche es immer noch erweitert!

Regeln

  • Eine Antwort muss die folgenden Ausdrücke vereinfachen können

    • 2+2 sollte auf reduzieren 4
    • (5+x)+6 sollte auf reduzieren x+11
    • (x+2)^2 sollte auf reduzieren x^2+4*x+4
    • (x-5)*(3+7*x) sollte auf reduzieren 7*x^2-32*x-15
    • 5*x+9*x sollte auf reduzieren 14*x
    • (2*x^2)*x^3 sollte auf reduzieren 2*x^5
  • Antworten müssen in der Lage sein, Klammern VOLLSTÄNDIG zu entfernen, was bedeutet, dass die gesamte Verteilung stattfinden muss.

  • Answers sollte in der Lage sein, alle folgenden Operatoren und Standard-Token zu verarbeiten:

    • + (Die Additionsfunktion)
    • - (Die Subtraktionsfunktion)
    • * (Die Multiplikationsfunktion)
    • ( (Die linke Klammer zur Angabe einer Gruppe)
    • ) (Die rechte Klammer gibt das Ende der zuletzt gestarteten Gruppe an.)
    • x (Die Standardvariable)
    • [0-9]+ (wörtliche nichtnegative Zahlen)
  • Die Antworten müssen mindestens quadrieren können, wobei die Notation expr ^ 2 einschließlich (expr) ^ 2 rekursiv verwendet wird, da (expr) selbst ein Ausdruck ist;)

  • Eine Lösung muss in einer Standard-Infix-Notation vorliegen, kein RPN-Unsinn!

  • Keine Bibliotheksfunktionen wie Mathematica Simplifyerledigen dies für Sie.

  • Die Lösung sollte eine Funktion sein, die ein einzelnes Argument aufnimmt und die erweiterte Version zurückgibt

Da dies Code-Golf ist, gewinnt die Antwort mit den wenigsten (Schlüssel-) Schlägen, 1 Woche nach OP.

Anmerkungen

Natürlich gibt es in dieser Welt der Mathematik keine Räume! Nur Klammern.

Es ist also keine Division erforderlich, um vor dem Factoring zu sparen

Es gilt die Standardreihenfolge.

Ich bin mir bewusst , dass einige , was ich frage Vereinfachung ist (zB 2+2=4) , wo andere Teile eigentlich das Gegenteil sind, wie zum Beispiel den Ausbau (x+1)^2zu sein x^2+2x+1. Dies ist beabsichtigt. :) :)

-25 Striche für eine Lösung, die (Ausdruck) ^ n anstelle von nur (Ausdruck) ^ 2 ausführen kann

-15 Striche für eine Lösung, die in der Lage ist, nebeneinander stehende Multiplikationen zu bewerten, z. B. 4x+5x== 9xoder 4(x+1)=4x+4

-5 Striche für eine Lösung, die mehrere Variablen verarbeiten kann (Eine Variable ist genau ein Kleinbuchstaben)

-5 Striche für eine Lösung, die führende Nullen entfernen kann ( 007nur 7[Nicht heute, Bond!] [Herrgott, jetzt habe ich das Gefühl, ich schreibe Lisp])

Christopher Wirt
quelle
Ich glaube, dass (x-5) * (3 + 7 * x) (1 * x + -5) * (7 * x + 3) 7 * x ^ 2 + (3-35) * x + - ist 15 oder 7 * x ^ 2-32 * x-15
Jeff Grigg
Wie soll Input bereitgestellt werden? Kommandozeilenargumente? Standardeingabe? Sollte wahrscheinlich angegeben werden.
Frxstrem
@ JeffGrigg Deshalb brauche ich das Programm;) Hehe, ich habe tatsächlich das 7 * x hinzugefügt, um mehr Komplexität anzuzeigen, und vergessen, die Lösung zu aktualisieren. Vielen Dank! Und ich hätte schwören können, dass sie als Argument für eine Funktion dienen sollten
Christopher Wirt
1
Ich habe fast eine funktionierende Lösung dafür in J, ich muss nur negative Zahlen richtig analysieren. Es ist wahrscheinlich das hässlichste, hackigste, was ich je geschrieben habe, aber zum Glück ist es fast vorbei.
Algorithmushai
1
@ssdecontrol ohne Division, wir sprechen von Polynomen. Fügen Sie die Abteilung hinzu und es ist eine ganz andere Sache
edc65

Antworten:

2

J - 350 Zeichen - 25 = 325 Punkte

Vergib mir, Roger Hui, denn ich habe gesündigt.

x=:0 1
f=:(('+_';'-';'_';'-')rplc~' '-.~'+'}.@,@|.@,.s(}.@]`(,&":)@.t'*x'"_`('*x^',":)`(''"_)@.t=.*@<:@[)/"1@#~0~:0{|:@s=.,.i.@#)@p=:(0{::'()'+/@,:&,e'+'@((+/@,:&,-)~e'-')@(*/a e'*')@('^'(*/(a=.+//.@)/@#,:e=:2 :'(<@; ::({:u/&.>{.)/.~i.@#-i.@#(>+>:)(<,v){.@i.~])^:_'))@:(([^:(''-:])". ::])&.>)@([-.~;@]<@(p^:(1<#));.1~1,0=2*/\[:+/\(*0,}:@)1 _1 0{~i.)&;:])

Die obige Monstrosität definiert eine Anzahl von Variablen, von denen die Variable feine Funktion ist, die die Einschränkungen in der obigen Frage erfüllt. Ich beanspruche den "Ausdruck" -Bonus für 25 Punkte.

Hier ist der Golf in Aktion bei der J REPL.

   x=:0 1
   f=:(('+_';'-';'_';'-')rplc~' '-.~'+'}.@,@|.@,.s(}.@]`(,&":)@.t'*x'"_`('*x^',":)`(''"_)@.t=.*@<:@[)/"1@#~0~:0{|:@s=.,.i.@#)@p=:(0{::'()'+/@,:&,e'+'@((+/@,:&,-)~e'-')@(*/a e'*')@('^'(*/(a=.+//.@)/@#,:e=:2 :'(<@; ::({:u/&.>{.)/.~i.@#-i.@#(>+>:)(<,v){.@i.~])^:_'))@:(([^:(''-:])". ::])&.>)@([-.~;@]<@(p^:(1<#));.1~1,0=2*/\[:+/\(*0,}:@)1 _1 0{~i.)&;:])

   f '2+2'
4
   f '(5+x)+6'
x+11
   f '(x+2)^2'
x^2+4*x+4
   f '(x-5)*(3+7*x)'
7*x^2-32*x-15
   f '5*x+9*x'
14*x
   f '(2*x^2)*x^3'
2*x^5
   f '(2*x+3)^(2+3)*2^3'   NB. bonus
256*x^8+1920*x^7+5760*x^6+8640*x^5+6480*x^4+1944*x^3

Hier ist der Kern dessen, was los ist.

  • '()'...@([-.~;@]<@(p^:(1<#));.1~1,0=2*/\[:+/\(*0,}:@)1 _1 0{~i.)&;:- Zerlegen Sie den Ausdruck rekursiv anhand seiner in Klammern gesetzten Unterausdrücke und werten Sie sie (das ...unten zu beschreibende Bit) aus, sobald sie fertig sind. ;:führt die Tokenisierung durch.
  • (([^:(''-:])". ::])&.>)- Atome auswerten. Wenn das Atom numerisch ist, wird es in eine skalare Zahl umgewandelt. Wenn das Atom ein Operator ist, bleibt es wie es ist. Wenn das Atom die Variable ist x, wird es in den Vektor umgewandelt 0 1. (Deshalb definieren wir x=:0 1zu Beginn.) Im Allgemeinen speichern wir das Polynom a*x^n + b*x^(n-1) + ... + c*x + dals n+1-item-Liste d c ... b a.
  • e=:2 :'(<@; ::({:u/&.>{.)/.~i.@#([->+>:){.@i.&(<,v))^:_'- Diese merkwürdige Konjunktion nimmt links ein Verb und rechts ein Zeichen. Es findet die erste Instanz dieses Zeichens in seiner tokenisierten, parenlosen Eingabe und wertet sie mit den Argumenten um sie herum aus und wiederholt sie, bis keine solchen Zeichen mehr zu finden sind. Daher vereinfachen wir den Ausdruck iterativ, wobei die Reihenfolge der Operationen durch die Reihenfolge der Anwendung von gesteuert wird e.
  • Und dann ist das ganze Zeug auf der Vorderseite nur eine hübsche Druckausgabe. rplcist eine Standardbibliotheksfunktion zum Ersetzen von Teilzeichenfolgen. Wir können weitere drei Zeichen speichern, wenn wir die Begriffe mit dem niedrigsten Grad anstelle der höchsten zuerst setzen dürfen, indem wir die entfernen @|..

Ich bin mir ehrlich gesagt nicht sicher, ob ich noch mehr Charaktere aus diesem Golf herausholen kann. Ich kann mir keinen anderen Ansatz vorstellen, der kein ähnliches Maß an Überentwicklung erfordert, aber das bedeutet nicht, dass es keinen gibt. Auf jeden Fall bin ich mir ziemlich sicher, dass ich alle offensichtlichen Charaktere aus dieser Version herausgepresst habe.

Algorithmushai
quelle
Bravo! Und Sie können die Korrektur der negativen Zahl loswerden, da das -Token nur als Subtraktionsfunktion notiert wird. :)
Christopher Wirt
@ChristopherWirt Hab das nicht verstanden. So oder so, fertig.
Algorithmushai
(2*x+3)^(2+3)*2^3sollte geben 256x^5+1920x^4+5760x^3+8640x^2+6480x+1944oder mir fehlt etwas?
edc65
2

JavaScript (EcmaScript 6) 698 (748-50 Bonus) 725 780 1951

Golfen . Aber ich bin stolz, dass es funktioniert.
(Edit: Bugfix, Probleme mit Klammern und Minus)
(Edit2: mehr Golf gespielt, Fehler in der Ausgabe
behoben ) (Edit3: noch einmal Golf gespielt, letztes Mal verspreche ich)

Kommentar

Grundsätzlich ist die Funktion X ein Infix-Rechner, der mit wörtlichen Polynomen arbeitet.
Jedes Polynom wird als js-Objekt gespeichert, wobei der Schlüssel der Term (x ^ 3y ^ 2) und der Wert der numerische Koeffizient ist. Funktion A, M und E sind Addition, Multiplikation und Exponent.

Golfed Code

(Es kann wahrscheinlich nicht mehr Golf gespielt werden ...) Hinweis: Für die Lesbarkeit (ehm ...) wurden keine Zeilenumbrüche berücksichtigt

K=x=>Object.keys(x).sort(),
A=(p,q,s,t,c)=>[(c=(s+1)*q[t]+~~p[t])?p[t]=c:delete(p[t])for(t in q)],
M=(p,q,t,c,o,u,f,r,v={})=>([A(v,(r={},[(c=p[f]*q[t])&&(r[o={},(u=f+t)&&(u.match(/[a-z]\^?\d*/ig).map(x=>o[x[0]]=~~o[x[0]]+(~~x.slice(2)||1)),K(o,u=k).map(i=>u+=o[i]>1?i+'^'+o[i]:i)),u]=c)for(f in p)],r),k)for(t in q)],v),
E=(p,n)=>--n?M(p,E(p,n)):p,
O=n=>{for(l=0;h(o=s.pop())>=h(n);)a=w.pop(b=w.pop()),o=='*'?a=M(a,b):o>d?a=E(a,b[k]):A(a,b,o),w.push(a);s.push(o,n)},
X=e=>(l=k='',w=[],s=[d='@'],h=o=>'@)+-*^('.indexOf(o),
(e+')').match(/\D|\d+/g).map(t=>(u=h(t))>5?(l&&O('*'),s.push(d)):u>1?O(t):~u?s.pop(s.pop(O(t)),l=1):(l&&O('*'),l=1,w.push(v={}),t<d?v[k]=t|0:v[t]=1)),
K(p=w.pop()).map(i=>(k+=(c=p[i])>1?s+c+i:c<-1?c+i:(c-1?'-':s)+(i||1),s='+')),k||0)

Test In FireFox Konsole

['2+2','(5+x)+6','(x+2)^2','(a+b)(a-b)','(a+b)*(a-b)','(a-b)(a-b)', '(x-5)*(3+7*x)','5*x+9*x','(2*x^2)*x^3','(2*x+3)^(2+3)*2^3']
.map(x => x + ' => ' + X(x)).join('\n')

Ausgabe

2+2 => 4
(5+x)+6 => 11+x
(x+2)^2 => 4+4x+x^2
(a+b)(a-b) => a^2-b^2
(a+b)*(a-b) => a^2-b^2
(a-b)(a-b) => a^2-2ab+b^2
(x-5)*(3+7*x) => -15-32x+7x^2
5*x+9*x => 14x
(2*x^2)*x^3 => 2x^5
(2*x+3)^(2+3)*2^3 => 1944+6480x+8640x^2+5760x^3+1920x^4+256x^5

Boni

25: 2*x+3)^(2+3)*2^3 => 1944+6480x+8640x^2+5760x^3+1920x^4+256x^5
15: 4x+5x => 9x
5: 007x+05x^(06+2) => 7x+5x^8
5: (a+b)(a-b) => a^2-b^2

Ungolfed Code

Show=(p)=>(
  Object.keys(p).sort().map(i=>(c=p[i])-1?c+1?c+i:'-'+i:i).join('+').replace(/\+-/g,'-')
)
AddMonoTo=(poly, term, coeff, c)=>(
  (c = coeff + ~~poly[term]) ? poly[term]= c : delete(poly[term])
)
AddPolyTo=(p1, p2, s, t)=>(
  [ AddMonoTo(p1, t, (s+1)*p2[t]) for (t in p2)]
)
MulTerm=(t1, t2, o={})=>(
  (t1+=t2)&&
  (t1.match(/[a-z](\^\d+)?/g).every(x=>o[x[0]]=(~~x.slice(2)||1)+(~~o[x[0]])),
  Object.keys(o,t1='').sort().every(i=>t1+=o[i]>1?i+'^'+o[i]:i)),
  t1  
)
MulMono=(poly, term, coeff, c, r={}, t)=>(
  [(c = poly[p]*coeff) && (r[MulTerm(p,term)] = c) for (p in poly) ],r
)  
MulPoly=(p1, p2, r={}, p)=>(
  [AddPolyTo(r,MulMono(p2, p, p1[p]),'') for (p in p1)],r
)
ExpPoly=(p,n,r=p)=>{
  for(;--n;)r=MulPoly(r,p);
  return r
}
Expand=ex=>
{
  var tokens = ex.match(/\D|\d+/g).push(')')
  var t,a,b,v,LastV=0
  var vstack=[]
  var ostack=['_']
  var op={ '+': 3, '-':3, '*':4, '^':6, '(':8, _: 1, ')':2}
  var OPush=o=>ostack.push(o)
  var OPop=_=>ostack.pop()
  var VPush=v=>vstack.push(v)
  var VPop=v=>vstack.pop()

  var Scan=i=>
  {
    LastV=0 ;
    for (; (t=tokens[i++]) && (t != ')'); )
    {
      if (t == '(')  
      {
        if (LastV) CalcOp('*')
        OPush('_'), i=Scan(i)
      }
      else if (op[t])
        LastV=0, CalcOp(t)
      else
      {
        if (LastV) CalcOp('*')
        LastV = 1
        VPush(v={})
        t < 'a' ? v[''] = t|0 : v[t] = 1
      }
    }
    CalcOp(t);
    OPop();
    OPop();
    LastV=1;
    return i;
  }
  var CalcOp=nop=>
  {
    for (; op[po = OPop()] >= op[nop];)
      b=VPop(), a=VPop(), CalcV(a,b,po);
    OPush(po), OPush(nop);
  }
  var CalcV=(a,b,o)=>
  {
    if (op[o] < 4) 
      AddPolyTo(a,b,o)
    else if (o == '*')
      a=MulPoly(a,b)
    else // ^
      a=ExpPoly(a,b['']) // only use constant term for exp
    VPush(a)
  }
  Scan(0)

  return Show(vstack.pop())
}
edc65
quelle
Verwenden Sie Semikolons nur an einigen Stellen? Ist es wegen des fehlenden Rahmens, dass Sie sie brauchen? Ich bin nicht sehr EcmaScript-konform mit meinem JS;)
Christopher Wirt
Kommas separater Ausdruck, Semikolon separate Anweisungen. Es ist klarer in for(i1,i2,i3; c1,c2; s1,s2,s3). Ich habe nur ein Semikolon in Golf Colde, um eine Anweisung in einer for (Funktion O) zu schließen. Warum Kommas? Zwei Staubblätter müssen mit {} gruppiert werden, während zwei oder mehr Ausdrücke einfach aufgelistet werden können.
edc65
1

Mathematica: 56 - 25 - 15 - 5 - 5 = 6

Natürlich fungiert keine Bibliothek als Expandoder Distribute, nur das Ersetzen von Mustern. Mathematica macht fast alles für uns (hax!), Was bleibt, sind nur Regeln für die Verteilung und Leistungserweiterung. Die einzigen nicht trivialen Beispiele sind daher (x-5)*(3+7*x)und (x+2)^2.

f=#//.{x_ y_Plus:>(x #&/@y),x_Plus^n_:>(x #&/@x)^(n-1)}&

Beispiele

(x-5)*(3+7*x) // f
-15 - 32 x + 7 x^2

(x + 2)^2 // f
4 + 4 x + x^2
swish
quelle
Sie haben in beiden Beispielen einige sehr seltsame Charaktere. Kannst du es aufräumen?
edc65
@ edc65 M10 benimmt sich seltsam mit Kopieren / Einfügen, denke ich.
Swish
Ich hätte Mathematica wahrscheinlich alles andere als verbieten sollen;) Gute Arbeit
Christopher Wirt