Hilfe! Mein Rechner ist kaputt! (Ganzzahlausdruck in Taschenrechner-Tastenanschläge umwandeln)

30

Einführung

Hilfe! Ich habe versehentlich meinen TI-84-Taschenrechner aus dem Fenster geworfen (frag nicht wie) und er ist kaputt gegangen. Ich habe morgen einen Mathe-Test und der einzige Taschenrechner, den ich finden kann, ist einer mit diesen Knöpfen:

7 8 9 +
4 5 6 -
1 2 3 *
0   = /

Mein Mathe-Test ist ein Überprüfungstest zur Bewertung von Ausdrücken. Ich benötige ein Programm, um einen Ausdruck wie zum Beispiel 1+(5*4)/7in die Tastenanschläge umzuwandeln, die zum Lösen auf meinem Ersatzrechner erforderlich sind. (Und falls Sie sich fragen, ist mir das tatsächlich passiert).

Herausforderung

Bei einer nicht-leere Eingabezeichenfolge enthält , nur die Zeichen 0-9, (, ), +, -, *, und /, gibt die Tastenanschläge in einem Raum getrennten Zeichenfolge (z. 1 + 3 / 3 =). Am Ende der Ausgabe muss immer ein Gleichheitszeichen stehen. Standardlücken sind nicht erlaubt.

Beispiele:

  • Eingabe:, 1+(5*4)/7Ausgabe:5 * 4 / 7 + 1 =
  • Eingabe:, 6*(2/3)Ausgabe:2 / 3 * 6 =
  • Eingabe:, (7-3)/2Ausgabe:7 - 3 / 2 =

Um diese Herausforderung zu vereinfachen:

  • Sie können davon ausgehen, dass mit der Eingabe eine Reihe von Tastenanschlägen verknüpft sind, für die kein Löschen des Rechners erforderlich 1-(7*3)ist ( ist nicht gültig, da Sie erst suchen 7 * 3und dann den Rechner löschen müssen) 1 - 21. Alle obigen Beispiele sind gültig, da es einen gibt , kontinuierliche Ausgabe, bei der der Benutzer den Taschenrechner nicht löschen und sich eine Zahl merken muss).
  • Sie können davon ausgehen, dass es nach a nur eine einzelne Ganzzahl gibt /, da diese eine Eingabe hat, 21/(7*3)die auch die erste Annahme nicht erfüllt.
  • Sie können davon ausgehen, dass *zwischen einer Ganzzahl und einer linken Klammer immer ein (Valid 6*(7):, Invalid:) steht 6(7).
  • Sie können davon ausgehen, dass die Eingabe immer eine Ganzzahlausgabe erzeugt.
  • Sie können davon ausgehen, dass die Eingabe nur drei Klammerstufen enthält.

Nichtbeispiele

  • 2-(14/2)wie du tun müsstest 14 / 2, dann klar , dann 2 - 7.
  • 36/(2*3)wie du tun müsstest 2 * 3, dann klar , dann 36 / 6.
  • 1024*4/(1*2+2)wie du tun müsstest 1*2+2, dann klar , dann 1024 * 4 / 4.

Boni

  • -5%, wenn Ihr Programm die Multiplikation in Klammern erkennt (das weiß es 6(7)=6*(7)).
  • -5% , wenn Sie die Programmeingabe mit Dezimalzahlen verarbeiten kann ( 3.4, 2.75, 7.8) und die Ausgabe enthält .(wie es sein , muss .in diesem Fall Schlüssel auf meinem Ersatzrechner).
  • -5%, wenn Ihr Programm eine unbegrenzte Anzahl von Klammern verarbeiten kann.

Dies ist , der kürzeste Code in Bytes (einschließlich der Boni) gewinnt!

Bestenlisten

Hier ist ein Stack-Snippet, um sowohl eine reguläre Rangliste als auch eine Übersicht der Gewinner nach Sprache zu generieren.

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

## Language Name, N bytes

Wo Nist die Größe Ihres Beitrags? Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Wenn Sie mehrere Zahlen in Ihre Kopfzeile aufnehmen möchten (z. B. weil Ihre Punktzahl die Summe von zwei Dateien ist oder wenn Sie die Strafen für Interpreter-Flags separat auflisten möchten), stellen Sie sicher, dass die tatsächliche Punktzahl die letzte Zahl in der Kopfzeile ist:

## Perl, 43 + 2 (-p flag) = 45 bytes

Sie können den Namen der Sprache auch als Link festlegen, der dann im Leaderboard-Snippet angezeigt wird:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

var QUESTION_ID=61751,OVERRIDE_USER=141697;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

GamrCorps
quelle
Sie dürfen Programme ausführen, können sie jedoch nicht zum Ausführen der eigentlichen Gleichung verwenden? 0.o
Downgoat
6
@ Vɪʜᴀɴ Du musst meinen Mathematiklehrer danach fragen, ich habe es auch nicht verstanden.
GamrCorps
Müssen wir die Reihenfolge der Operationen regeln?
Lirtosiast
1
Können wir längere, kompliziertere Testfälle mit etwa zehn Operationen haben?
Lirtosiast
1
Es gibt einen Tippfehler. In dem Text , dass zu sagen 6(7)wird nicht passieren, es sagt auch , dass das Zeichen ?in 6?(7)immer sein wird *.
Wizzwizz4

Antworten:

11

Python 3. 337 327 - 10% = 295 Bytes

Unterstützt Gleitkommazahlen und eine unbegrenzte Anzahl von Klammern, qualifiziert sich also für einen Bonus von -10%.

import re
def v(s):
 if s[:1]=='(':l,s=e(s[1:]);return l,s[1:]
 m=re.match(r"\d+\.?\d*|\.\d+",s)
 if m:return[m.group()],s[m.end():]
def b(s,f,*O):
 l,s=f(s)
 while s[:1]in O:
  o=s[0]
  r,s=f(s[1:])
  if len(r)>1:l,r=r,l
  l+=[o]+r
 return l,s
m=lambda s:b(s,v,'*','/')
e=lambda s:b(s,m,'+','-')
print(' '.join(e(input())[0]))
mjmt
quelle
2
???
Katze
5
@sysreq Dies funktioniert, Sie müssen nur Befehlszeilenargumente verwenden. Ersetzen sys.argv[1]mit input()funktioniert in Ideone (und ist Shoter - Hinweis Hinweis)
GamrCorps
Gibt es irgendwo Richtlinien, die Dinge klar machen, wie zum Beispiel, dass Eingaben gelesen und nicht als Argument weitergegeben werden sollen? (Btw @GamrCorps du meinst raw_input (), was mir nur 4 Zeichen ersparen würde: "sys".) Um die letzten Zeichen nicht abzuschaben, wollte ich eigentlich nur den Ball ins Rollen bringen und die Lösungen anderer Leute sehen. vor allem, wenn sie etwas interessanteres tun als rekursive Abstammung.
mjmt
Die Eingabe von @mjmt kann in jeder Methode erfolgen: Befehlszeilenargumente, input () usw.
GamrCorps
1
@mjmt GamrCorps bedeutet, input()dass dies Python 3 ist! Python 2's raw_input() ===Python 3's input()!
wizzwizz4
8

TI-BASIC, 605,2 Byte

Berechtigt für die TI-BASIC-Prämie von Lirtosiast unter Passende, aber ungeeignete Sprachen .

Qualifiziert sich für alle 3 Boni 712 - 15% = 605.2. Hier und da gibt es einige Möglichkeiten zum Golfen, aber ich wollte dies zuerst herausfinden, da einige der möglichen Golfplätze nicht trivial sind. Bitte beachten Sie, dass TI-BASIC eine Token-Sprache ist und das Folgende eine Textdarstellung dieses Programms ist. Somit ist das Programm nicht 1182 Bytes, da dieses Programm nicht unter UTF-8 codiert ist. Beachten Sie, dass dies ~gleichbedeutend mit der unären Negation und ->dem STO>Operator ist. Die Ausgabe ist eine Zeichenfolge, die von Ansoder abgerufen werden kann Str1.

Das folgende Programm ist das Ergebnis von ein paar Programmierstunden, die über einige Wochen verteilt sind.

Input "",Str1
0->dim(L1
0->dim(L2
1->I
DelVar S
While I<length(Str1
DelVar T
".->Str3
1->C
While C and I<length(Str1
sub(Str1,I,1->Str2
inString("0123456789.",Str2->C
If C:Then
I+1->I
1->T
Str3+Str2->Str3
End
End
If T=0:Str3+Str2->Str3
sub(Str3,2,length(Str3)-1->Str3
If T=1:Then
expr(Str3->L2(1+dim(L2
End
inString("*+/-",Str3->M
If M:Then
I+1->I
2->T
1->C
While C
dim(L1->C
If C:Then
2fPart(L1(dim(L1))/2)>2fPart(M/2->C
If C:Then
~L1(dim(L1->L2(1+dim(L2
dim(L1)-1->dim(L1
End
End
End
M->L1(1+dim(L1
End
If Str3="(":Then
If S=1:Then
sub(Str1,1,I-1)+"*"+sub(Str1,I,length(Str1)-I+1)->Str1
Else
I+1->I
0->L1(dim(L1)+1
End
End
If Str3=")":Then
I+1->I
While L1(dim(L1
~L1(dim(L1->L2(1+dim(L2
dim(L1)-1->dim(L1
End
dim(L1)-1->dim(L1
End
T->S
End
augment(L2,-seq(L1(X),X,dim(L1),1,-1)->L2
0->dim(L1
1->C
{0,1->L3
For(I,1,dim(L2
L2(I->M
If M>=0:Then
M->L1(dim(L1)+1
Else
If C:Then
L1(dim(L1)-1
Goto S
Lbl A
Ans->Str1
L1(dim(L1->L1(dim(L1)-1
dim(L1)-1->dim(L1
0->C
End
Str1+" "+sub("*+/-",-M,1)+" ->Str1
L1(dim(L1
Goto S
Lbl B
Str1+Ans->Str1
dim(L1)-1->dim(L1
End
End
Goto F
Lbl S
L3Ans->L4
LinReg(ax+b) L3,L4,Y1
Equ►String(Y1,Str2
sub(Str2,1,length(Str2)-3
If C:Goto A
Goto B
Lbl F
Str1

Allgemeine Erklärung

Hier ist der Schlüssel, mit dem ich bei der Entwicklung des Programms gearbeitet habe:

Str1        The input string.
Str2        Counter variable (e.g. current character)
Str3        The current token being built.
L1          The operator stack
L2          The output queue
L3          Temporary list
L4          Temporary list
I           Iterator index
T           Type of token (enum)
S           Type of previous token (enum)
M           Temporary variable
C           Conditional variable


Token Types (T)
0           Undefined
1           Number
2           Operator
3           Open Parenthesis

Operator Elements
0           left parenthesis ("(")
1           multiplication ("*")
2           addition ("+")
3           division ("/")
4           subtraction ("-")
5           right parenthesis (")")

Precedence Rule: Remainder(prec, levelno)
0 - add, sub
1 - mul, div
(levelno = 2)

Und hier ist der entsprechende handgeschriebene JavaScript-Code, den ich zum Testen und Entwickeln dieses Programms verwendet habe.

let Str1, Str2, Str3, L1, L2, I, S, T, M, C;

let error = (type, ...args) => {
    let message = "ERR:" + type + " (" + args.join("; ") + ")";
    throw new Error(message);
};

let isInteger = (n) => n == Math.floor(n);

let inString = (haystack, needle, start=1) => {
    if(start < 1 || !isInteger(start)) {
        error("DOMAIN", haystacak, needle, start);
    }
    let index = haystack.indexOf(needle, start - 1);
    return index + 1;
};

let sub = (string, start, length) => {
    if(start < 1 || length < 1 || !isInteger(start) || !isInteger(length)) {
        error("DOMAIN", string, start, length);
    }
    if(start + length > string.length + 1) {
        error("INVALID DIM", string, start, length);
    }
    return string.substr(start - 1, length);
}

let fPart = (value) => value - Math.floor(value);

// Input "", Str1
Str1 = process.argv[2];
// 0->dim(L1
L1 = [];
// 0->dim(L2
L2 = [];
// 1->I
I = 1;
// DelVar S
S = 0;
// While I<=length(Str1
while(I <= Str1.length) {
    // DelVar T
    T = 0;
    // Disp "Starting",I
    console.log("Starting, I =", I);

    // " read token
    // ".->Str3
    Str3 = ".";
    // 1->C
    C = 1;
    // While C and I<=length(Str1
    while(C && I <= Str1.length) {
        // sub(Str1,I,1->Str2
        Str2 = sub(Str1, I, 1);
        // inString("0123456789",Str2->C
        C = inString("0123456789", Str2);
        // If C:Then
        if(C) {
            // I+1->I
            I++;
            // 1->T
            T = 1;
            // Str3+Str2->Str3
            Str3 += Str2;
        }
    }
    // If T=0:
    if(T == 0) {
        // console.log("Huh?T=0?", Str3, Str2);
        // Str3+Str2->Str3
        Str3 += Str2;
    }

    // " remove placeholder character
    // sub(Str3,2,length(Str3)-1->Str3
    Str3 = sub(Str3, 2, Str3.length - 1);

    // " number
    // If T=1:Then
    if(T == 1) {
        // expr(Str3->L2(1+dim(L2
        L2[L2.length] = eval(Str3);
    }

    // Disp "Str3",Str3
    console.log("post processing, Str3 = \"" + Str3 + "\"");

    // inString("*+/-",Str3->M
    M = inString("*+/-", Str3);
    // " operator
    // If M:Then
    if(M) {
        // I+1->I
        I++;
        // 2->T
        T = 2;
        // Disp "op",M,dim(L1
        console.log("op", M, L1.length);
        // " parse previous operators
        // 1->C
        C = 1;
        // While C
        while(C) {
            // dim(L1->C
            C = L1.length;
            // If C:Then
            if(C) {
                // 2fPart(L1(dim(L1))/2)>2fPart(M/2->C
                C = 2 * fPart(L1[L1.length - 1] / 2) > 2 * fPart(M / 2);
                // If C:Then
                if(C) {
                    // ~L1(dim(L1->L2(1+dim(L2
                    L2[L2.length] = -L1[L1.length - 1];
                    // dim(L1)-1->dim(L1
                    L1.length--;
                }
            }
        }
        // " push current operator
        // M->L1(1+dim(L1
        L1[L1.length] = M;
    }
    // If Str3="(":Then
    if(Str3 == "(") {
        // 3->T
        T = 3;
        // If S=1:Then
        if(S == 1) {
            // sub(Str1,1,I-1)+"*"+sub(Str1,I,length(Str1)-I+1)->Str1
            Str1 = sub(Str1, 1, I - 1) + "*" + sub(Str1, I, Str1.length - I + 1);
        }
        // Else
        else {
            // I+1->I
            I++;
            // 0->L1(dim(L1)+1
            L1[L1.length] = 0;
        }
        // End
    }
    // If Str3=")":Then
    if(Str3 == ")") {
        // I+1->I
        I++;
        // While L1(dim(L1
        while(L1[L1.length - 1]) {
            // ~L1(dim(L1->L2(1+dim(L2
            L2[L2.length] = -L1[L1.length - 1];
            // dim(L1)-1->dim(L1
            L1.length--;
        }
        // End
        // dim(L1)-1->dim(L1
        L1.length--;
    }
    // Disp "Ending",I
    console.log("Ending", I);
    // T->S
    S = T;
    // Pause
    console.log("-".repeat(40));
}

// augment(L2,-seq(L1(X),X,dim(L1),1,-1)->L2
L2 = L2.concat(L1.map(e => -e).reverse());

// Disp L1, L2
console.log("L1", L1);
console.log("..", "[ " + L1.map(e=>"*+/-"[e-1]).join`, ` + " ]");
console.log("L2", L2);
console.log("..", "[ " + L2.map(e=>e<0?"*+/-"[~e]:e).join`, ` + " ]");

// post-processing
let res = "";
// 0->dim(L1
L1.length = 0;
// 1->C
C = 1;
// For(I,1,dim(L2
for(I = 1; I <= L2.length; I++) {
    // L2(I->M
    M = L2[I - 1];
    // If M>=0:Then
    if(M >= 0) {
        // M->L1(dim(L1)+1
        L1[L1.length] = M;
    }
    // Else
    else {
        // If C:Then
        if(C) {
            // L1(dim(L1)-1
            // Goto ST
            // Lbl A0
            // Ans->Str1
            res += L1[L1.length - 2];
            // L1(dim(L1->L1(dim(L1)-1
            L1[L1.length - 2] = L1[L1.length - 1];
            // dim(L1)-1->dim(L1
            L1.length--;
            // 0->C
            C = 0;
        }
        // End
        // Str1+" "+sub("*+/-",-M,1)+" ->Str1
        res += " " + "*+/-"[-M - 1] + " ";
        // L1(dim(L1
        // Goto ST
        // Lbl A1
        // Str1+Ans->Str1
        res += L1[L1.length - 1];
        // dim(L1)-1->dim(L1
        L1.length--;
    }
}
// Goto EF
// Lbl ST
// L3Ans->L4
// LinReg(ax+b) L3,L4,Y1
// Equ►String(Y1,Str2
// sub(Str2,1,length(Str2)-3
// If C:Goto A0
// Goto A1
// Lbl EF
// Str1
console.log(res);

Sobald ich sicher bin, dass ich mit dem Golfen fertig bin, werde ich eine ausführlichere Erklärung geben. In der Zwischenzeit kann dies jedoch zu einem flüchtigen Verständnis des Codes beitragen.

Conor O'Brien
quelle
Sie können frisch TI-84 + CE - Rechner übernehmen, so Input "",Str1 0->dim(L1 0->dim(L2 1->I DelVar Skann sein Prompt Str1:SetUpEditor :1->I, und Sie können toString verwenden (auch einige überflüssige Pars haben..
lirtosiast
@lirtosiast Guter Punkt zum frischen Rechner, den ich nicht einbeziehen wollte, toStringda ich selbst kein CE habe. Ich werde die Emulation untersuchen, um die Gültigkeit des Programms sicherzustellen.
Conor O'Brien
7

Javascript (ES6), 535 - 80 (15% Bonus) = 455 Bytes

f=z=>{a=[],i=0;c=n=>{while(n[M='match'](/\(/)){n=n[R='replace'](/\(([^()]+)\)/g,(q,p)=>{m=++i;a[m]=c(p);return'['+m+']'})}n=n[R](/(\](?=\[|[\d])|[\d](?=\[))/g,'$1*');n=n[R](/\[?[\d\.]+\]?[*/]\[?[\d\.]+\]?/g,q=>{a[++i]=q;return'['+i+']'});n=n[R](/([\d.]+)\+(\[[\d]+\])/g,'$2+$1');while(n[M](/\[/)){n=n[R](/(\[?[\d\.]+\]?)\*(\[?[\d\.]+\]?)/g,(q,p,r)=>{t=a[r[R](/[\[\]]/g,'')];return r[M](/\[/)?(t&&t[M](/\+|\-/)?(r+'*'+p):q):q});n=n[R](/\[(\d+)\]/g,(q,p)=>{return a[p]+(a[p][M](/\+|-/)?'=':'')})}return n};return c(z)[R](/./g,'$& ')+'='}

Ich bin mir sicher, dass dies keine minimale Lösung ist, aber sie ist ziemlich vollständig und lässt alle drei Boni zu. In einigen Fällen muss die Gleichheitstaste mehrmals gedrückt werden, der Inhalt des Taschenrechners muss jedoch nicht gelöscht werden. (zB 3,5,6 & 7 in Geige)

Link zu JSFiddle mit einigen Tests: https://jsfiddle.net/2v8rkysp/3/

Hier ist ein Teil des entfalteten, halb-verschleierten Codes mit ein paar Kommentaren zur besseren Übersicht.

function f(z) {
var a=[],i=0;
function c(n) {
    //// Tokenize parentheses groups recursively
    while (n.match(/\(/)) {
    n = n.replace(/\(([^()]+)\)/g, function(q,p) {
      m = ++i;
      a[m]=c(p);
      return '['+m+']';
    });
    }

    //// Allow implied multiplication with parentheses
    n = n.replace(/(\](?=\[|[\d])|[\d](?=\[))/g, '$1*');

    //// Tokenize mult/division
    n = n.replace(/\[?[\d\.]+\]?[*\/]\[?[\d\.]+\]?/g, function(q) {
      a[++i]=q;
      return '['+i+']';
    });

    //// Move addition tokens to the front
    n = n.replace(/([\d.]+)\+(\[[\d]+\])/g,'$2+$1');

    //// Detokenize
    while (n.match(/\[/)) {
        //// If a token includes addition or subtraction,
        ////   move it to the front of other tokens 
        n = n.replace(/(\[?[\d\.]+\]?)\*(\[?[\d\.]+\]?)/g,function(q,p,r) {
          t=a[r.replace(/[\[\]]/g,'')];
          return r.match(/\[/)?(t&&t.match(/\+|\-/)?(r+'*'+p):q):q;
        });
        //// If a token includes addition or subtraction,
        ////   add the equals keypress
        n = n.replace(/\[(\d+)\]/g, function(q,p) {
           return a[p]+(a[p].match(/\+|-/)?'=':'');
        });
    }
    return n;
}
//// Add spaces and final equals keypress
return c(z).replace(/./g, '$& ')+'=';
}
Styletron
quelle