Operator-Rangfolge: Wie falsch kann ich sein?

65

Angenommen, ich habe einen Ausdruck:

9 * 8 + 1 - 4

Dieser Ausdruck kann je nach Rangfolge des Operators auf sechs verschiedene Arten interpretiert werden:

(((9 * 8) + 1) - 4) = 69 (* + -)
((9 * 8) + (1 - 4)) = 69 (* - +)
((9 * (8 + 1)) - 4) = 77 (+ * -)
(9 * ((8 + 1) - 4)) = 45 (+ - *)
((9 * 8) + (1 - 4)) = 69 (- * +)
(9 * (8 + (1 - 4))) = 45 (- + *)

Angenommen, ich bin ein Entwickler und möchte mir keine Rangfolgetabellen usw. merken, also rate ich einfach.

In diesem Fall wäre die größte Fehlerquote 45-77, was einer Differenz von 32 entspricht. Dies bedeutet, dass meine Vermutung nur um maximal 32 verfehlt wird.

Die Herausforderung

Bei einem gegebenen Ausdruck , der aus Zahlen und +, -, *, /(Integer - Division) und den %Ausgang der absolute Differenz des größten und kleinsten möglichen Wertes für diesen Ausdruck, auf der Grundlage der Rangfolge der Operatoren.

Spezifikationen

  • Der Eingabeausdruck enthält keine Klammern und jeder Operator ist linksassoziativ.
  • Der Eingabeausdruck enthält nur nicht negative Ganzzahlen. Unterausdrücke können jedoch zu Negativen ausgewertet werden (z 1 - 4. B. ).
  • Sie können den Ausdruck in jedem vernünftigen Format verwenden. Zum Beispiel:
    • "9 * 8 + 1 - 4"
    • "9*8+1-4"
    • [9, "*", 8, "+", 1, "-", 4]
    • [9, 8, 1, 4], ["*", "+", "-"]
  • Die Eingabe enthält mindestens 1 und höchstens 10 Operatoren.
  • Jeder Ausdruck, der eine Division oder ein Modulo durch 0 enthält, sollte ignoriert werden.
  • Sie können davon ausgehen, dass Modulo keine negativen Operanden erhält.

Testfälle

9 * 8 + 1 - 4             32
1 + 3 * 4                  3
1 + 1                      0
8 - 6 + 1 * 0              8
60 / 8 % 8 * 6 % 4 * 5    63
Esolanging Fruit
quelle
1
@AndersKaseorg Es sieht so aus, %als hätten Sie in Ihrem zweiten Beispiel zwei unterschiedliche Prioritäten.
Esolanging Fruit
1
Drei der "sechs" sind identisch, ebenso zwei. Damit bleiben drei Fälle, nicht sechs.
user207421
3
Wie arbeitet der %Operator mit negativen Zahlen? So wie C oder Python oder so?
tsh
8
Nur zu sagen, Sie müssen den Teil "und ich bin faul" nicht zu Ihrer Beschreibung hinzufügen. Nur zu sagen, dass Sie ein Entwickler sind, reicht aus. :)
Gryphon - Reinstate Monica
1
@tsh Beliebiges Verhalten. Mach was du willst. Du kannst Dämonen aus meiner Nase fliegen lassen .
Esolanging Fruit

Antworten:

27

Python 2 , 171 156 Bytes

lambda a:max(e(a))-min(e(a))
u=')%s('
def e(a,t=u):
 try:b=[eval(a)]
 except:b=[]
 return sum([e('(%s)'%a.replace(o,t%o),u%t)for o in"+-*/%"if' '+o in a],b)

Probieren Sie es online!

Wie es funktioniert

Wir umgeben jeden Operator mit einer unterschiedlichen Anzahl von nach außen gerichteten Klammerpaaren, um unterschiedliche Prioritäten (auf alle möglichen Arten) zu simulieren, und umschließen die gesamte Zeichenfolge mit genügend nach innen gerichteten Klammerpaaren, um einen Ausdruck zu erhalten, den wir erhalten können eval. Zum Beispiel mit

+)+(
*))*((
-)))-(((

wir bekommen

9 * 8 + 1 - 4(((9 ))*(( 8 )+( 1 )))-((( 4)))= 77.

Anders Kaseorg
quelle
Sie können 2 Bytes einsparen, indem Sie die orAußenseite von verschieben sum, um eine Ebene mit eckigen Klammern zu entfernen: sum([...],[])or[eval(a)]stattsum([...]or[[eval(a)]],[])
Strigoides
@ Strigoides Ich hatte gedacht, dass das nicht äquivalent ist, weil das sumleer sein kann, ohne dass sein Argument leer ist - aber es ist tatsächlich in Ordnung, weil das evalin diesem Fall fehlschlagen muss. Vielen Dank.
Anders Kaseorg
8

Jelly , 126 Bytes

"Operator-Vorrang? Klammern? Pah, wer braucht das?" - Herausforderungen bei der Verwendung von Jelly für eine Operator-Präzedenzanforderung.

⁾[]i$€Ḥæ%3+\¬œp¹Ḋ€
ǵḟØDO%9µÐṀṪɓœṣ⁹,ṚÑj@¥/
ǵVṾµ1ĿFḟØDḟ”-Lµ?ÐL
5Ḷx@€“]“[”ż⁸j/€,@y³Fɓ³i@€Ṁ’x@“[“]”jÇ
“+_×:%”Œ!Ç€µṾL_L’ỊµÐfV€ṢIS

Probieren Sie es online!

Die Eingabe erfolgt als String, zB "1 + 2_3 × 4: 5% 6". Die Multiplikation verwendet "×" anstelle von "*", die Division ":" anstelle von "/" und die Subtraktion "_" anstelle von "-".

Funktionsweise Das Programm ist in drei Teile unterteilt: Generieren aller Ausdrücke mit unterschiedlicher Operatorpriorität, Auswerten dieser Ausdrücke und Zurückgeben der Differenz zwischen Maximum und Minimum.

Alle Ausdrücke werden mit dem Code generiert:

5Ḷx@€“]“[”ż⁸j/€,@y³Fɓ³i@€Ṁ’x@“[“]”jÇ (4) helper link: returns all outputs given a permutation. Input e.g. "_+:×%"
5Ḷx@€“]“[”           - repeat outer brackets to get ["",""],["]","["],["]]","[["],["]]]","[[["],["]]]]","[[[["]
          ż⁸j/€      - insert the operations in to get "_","]+[","]]:[[","]]]×[[[","]]]]%[[[["
               ,@    - turn this into a mapping equivalent to "_"↦"_","+"↦"]+[",":"↦"]]:[[","×"↦"]]]×[[[","%"↦"]]]]%[[[["
                 y³F - use this mapping to get the right number of outward brackets on each operation. e.g. "1]+[3]]]×[[[4"
ɓ³i@€Ṁ’x@“[“]”j      - add the right number of brackets to the end to get e.g."[[[1]+[3]]]×[[[4]]]"
               Ç     - this calls the link which evaluates the expression
“+_×:%”Œ!Ç€                          (5a) main link. Input e.g. "1+3×4"
“+_×:%”                                 - the string "+_×:%"
       Œ!                               - all permutations
         ǀ                             - apply link (4) to each permutation

Die Links werden dabei ausgewertet (könnte ich wohl mit einer anderen Struktur verbessern):

⁾[]i$€Ḥæ%3+\¬œp¹Ḋ€      (1) Helper link: Outputs a list of expressions within brackets, e.g. "[[[1]+[3]]]×[[[4]]]"↦"[[1]+[3]]","[[4]]"
⁾[]i$€Ḥæ%3                 - map "[" to 2, "]" to -2, and any other character to 0.
          +\¬              - cumulative sum negated: 1s at characters not in brackets (includes opening brackets), 0s otherwise (includes closing brackets)
             œp¹           - partition the input, not including borders, based on the sum to get "[[[1]+[3]]","[[[4]]"
                Ḋ€         - remove opening brackets
ǵḟØDO%9µÐṀṪɓœṣ⁹,ṚÑj@¥/ (2) Return the input to this link with one of the expressions from (1) evaluated
ǵVṾµ1ĿFḟØDḟ”-Lµ?ÐL     (3) link called from part 1: Evaluates expressions
 µ  µ          µ?          - if:
     1ĿFḟØDḟ”-L            - the input contains no operators within brackets:         
  VṾ                         - evaluate this one expression with normal Jelly calculation and return to string
                           - otherwise:
Ç                            - evaluate one subexpression using link (2)
                  ÐL       - repeat this until a single output is determined

Die Differenz zwischen Maximum und Minimum wird mit dem Code in Link (5) berechnet:

µṾL_L’ỊµÐfV€ṢIS (5b) determine difference between minimum and maximum
µ      µÐf        - filter out outputs involving division or modulo by 0. Determined with:
 ṾL_L’Ị           - actual numbers have their unevaled form Ṿ no more than one byte longer than the non-unevaled form.
          V€      - evaluate each of these valid numbers to get integers from strings
            Ṣ     - sort
             IS   - return the sum of all difference between consecutive elements.
fireflame241
quelle
4
Wahrscheinlich die längste Gelee-Antwort (ohne eingebettete Daten), die ich je gesehen habe. Gut gemacht!
Keyu Gan
@KeyuGan Wenn Sie längere Gelee-Antworten wünschen, schauen Sie sich diese Antwort an . Ich kann mir keine anderen langen Gelee-Antworten ohne Komprimierung vorstellen.
Fireflame241
6

Python 2 , 235 234 233 226 Bytes

-1 Byte (und ein Update) dank Anders Kaseorg !

-7 Bytes dank Step Hen !

from itertools import*
def f(e,a=()):
 for o in permutations("+-*/%"):
	l=e[:]
	for c in o:
	 for i in range(len(l),0,-1):
		if l[i-1]==c:l[i-2:i+1]=["("+l[i-2]+l[i-1]+l[i]+")"]
	try:a+=eval(*l),
	except:0
 print max(a)-min(a)

Probieren Sie es online!

notjagan
quelle
1
Funktionsübermittlungen müssen wiederverwendbar sein . Sie können dieses Problem beheben, indem Sie astatt einer Liste ein Tupel angeben und dabei sogar 1 Byte sparen ( a=(), a+=eval(*l),).
Anders Kaseorg
Huh, bis. Danke für den Tipp!
Notjagan
1
Da Sie sich in Python 2 befinden, können Sie einige Bytes speichern, indem Sie Leerzeichen und Tabulatoren zum Einrücken abwechseln (in diesem Fall 2 Leerzeichen -> Tabulatoren, drei Leerzeichen -> Tabulatoren + Leerzeichen, vier Leerzeichen -> zwei Tabulatoren). Probieren Sie es online aus!
Stephen
4

Haskell 582 Bytes

Das lief bei weitem nicht so gut, wie ich gehofft hatte ...

import Data.List
f x=case x of '+'->(+);'-'->(-);'*'->(*);'/'->div;_->rem
e _ s[]=s
e 1 s(')':x:a)|0<-(read$e 0""a),(x=='%'||x=='/')=""|""<-(e 0""s)=""|""<-(e 0""a)=""|0<3=show$(f x)(read$e 0""s)$read$e 0""a
e 1 s")"=e 0""s
e n s(')':a)=e(n-1)(s++")")a
e 0 s('(':a)=e 1 s a
e n s('(':a)=e(n+1)(s++"(")a
e n s(x:a)=e n(s++[x])a
n?s=take n$cycle s
a!b=e 0""(9?"("++(concat$zipWith(++)a(b++[[]]))++9?")")
c#b|l<-[read x|x<-map(c!)(a b),x/=""]=maximum l-minimum l
a c=transpose$map(\x->map((\(Just q)->q).lookup x)$map(\a->zipWith(\x y->(y,x?")"++y:x?"("))[1..5]a)$permutations"+-*%/")c

Probieren Sie es online!

Der Versuch, ein langes Programm zu spielen, bringt mich dazu, schlechten Code zu schreiben :(

Ich habe versucht, Anders 'Algorithmus in Haskell zu verwenden, aber er geriet außer Kontrolle

Die Funktion e ist wie ein spezieller Fall von eval. (#) erstellt eine Liste von Zeichenfolgen, die Ganzzahlen und eine Zeichenfolge von Operatoren darstellen, und gibt die Differenz zwischen den maximal und minimal möglichen Werten zurück. z.B

(#) ["9","8","1","4"] "*+-" => 32
H.PWiz
quelle
1
Wenn Sie umbenannt #zu ##, könnten Sie umbenennen ezu (#), etwa so:(n#s)(x:a)=...
Esolanging Fruit
Wenn Sie die folgenden drei häufig verwendeten Funktionen als Alias ​​verwenden, können Sie weitere 6 Bytes speichern. r=read;j=zipWith;o=mapErsetzen Sie dann diese Funktionen durch die Buchstabenaliase.
maple_shaft
Auch ich zähle 594 Bytes, nicht 582.
maple_shaft
3

Pyth, 45 Bytes

KS.nm.x.vj\ u.nm+*H/kHckHGd]s.iFQY.p_{eQ-eKhK

Ich bin mir sicher, dass noch viel mehr Optimierungsarbeit geleistet werden kann, aber bisher gefällt es mir.

Nimmt die Eingabe wie folgt aus : [9, 8, 1, 4], ["*", "+", "-"].

Probieren Sie es online!

Trebuchette
quelle
2
Können Sie eine Erklärung hinzufügen?
Jim
2

Mathematica, 186 164 159 Bytes

eMax@#-Min@#&[Fold[#//.{m___,x_,#2[[0]],y_,n___}:>{m,x~Last@#2~y,n}&,e,#]&/@Permutations@{"+"@Plus,"-"[#-#2&],"*"@Times,"/"@Quotient,"%"@Mod}/. 0/0|1/0->{}]

\[Function] dauert 3 Bytes.

Einige Alternativen (bytecount bleibt gleich)

#2-#&@MinMax[...] ersetzen Max@#-Min@#&[...]

Head@#2 ersetzen #2[[0]]

Versuchen Sie es online unter http://sandbox.open.wolframcloud.com : Melden Sie sich ( .... )[{60, "/", 8, "%", 8, "*", 6, "%", 4, "*", 5}]mit ....für Testfall durch obige Code ersetzt 60 / 8 % 8 * 6 % 4 * 5. Drücken Sie Shift + enter, um zu bewerten.

user202729
quelle
2

Javascript, 280 Bytes

Hinweis : Die Ganzzahldivision rundet mit der Floor-Funktion, dh negative Zahlen runden von Null ab.

Diese Lösung basiert auf dieser Antwort .

b=>(Math.max(...(f=(a,h="(",i=")",r=[...a[d="replace"](/[^-+*/%]|(.)(?=.*\1)/g,"")])=>(r[0]?(r.map((c,j)=>s=s.concat(f(h+a[d](RegExp("\\"+(n=r.concat()).splice(j,1),"g"),i+c+h)+i,h+"(",i+")",n)),s=[]),s):(a=eval(`(${a})`[d](/\(/g,"Math.floor(")))==a&&1/a?a:r))(b))-Math.min(...f(b)))

Beispielcode-Snippet:

g=

b=>(Math.max(...(f=(a,h="(",i=")",r=[...a[d="replace"](/[^-+*/%]|(.)(?=.*\1)/g,"")])=>(r[0]?(r.map((c,j)=>s=s.concat(f(h+a[d](RegExp("\\"+(n=r.concat()).splice(j,1),"g"),i+c+h)+i,h+"(",i+")",n)),s=[]),s):(a=eval(`(${a})`[d](/\(/g,"Math.floor(")))==a&&1/a?a:r))(b))-Math.min(...f(b)))

for(k=0;k<5;k++)
  v=["9*8+1-4","1+3*4","1+1","8-6+1*0","60/8%8*6%4*5"][k],
  console.log(`g(${v}) = ${g(v)}`)

Herman L
quelle
Wie schwierig wäre es, die Kompatibilität herzustellen, indem Sie das a / b-Gehäuse durch a / b | 0 ersetzen?
Trlkly
@trlkly a/b|0stoppt die Divide / Modulo 0-Fehlerprüfung, hat aber Math.floor(a/b)funktioniert
Herman L
2

Haskell , 254 Bytes

import Data.List.Split
import Data.List
f s=(-)<$>maximum<*>minimum$permutations(zip"+-*/%"[p(+),p(-),p(*),c$div,c$mod])>>=(s!)
p=((pure.).)
c o a b=[o a b|b/=0]
s![]=[read s]
s!((x,o):y)=case splitOn[x]s>>=(!y)of[]->[];l->l?o
[a]?_=[a]
(a:b)?o=b?o>>=o a

Probieren Sie es online!

Die Eingabe ist eine ganze Zeichenfolge, z. B. 4 + 5 * 2. Sie generiert alle Permutationen von Operationen und teilt die Zeichenfolge für jede Permutation rekursiv auf. Mit der Listenmonade werden Divisionen durch 0 gefiltert.

Bartavelle
quelle
(%)ist Moduloperator. Es ist der Rest einer Divisionsoperation zwischen dem linken und dem rechten Argument.
maple_shaft
1

Python 2 , 262 256 254 Bytes

from itertools import*
def r(s,o):
 try:
  while o in s:i=s.index(o)-1;s[i:i+3]=[`eval(''.join(s[i:i+3]))`]
  return s
 except:0
def f(s):
 u=[int(v[0])for v in [reduce(r,O,s.split(' '))for O in permutations('*/%+-')]if v!=None];return abs(max(u)-min(u))

Probieren Sie es online!

Chas Brown
quelle
Sparen Sie einige Bytes, indem Sie auch Tabs verwenden: Probieren Sie es online aus!
Stephen
1
Speichern Sie ein Byte, indem Sie in [auf in[(Leerzeichen wird nicht benötigt)
Zacharý
1

PHP , 316 Bytes

<?for(;$t++<54322;)count_chars($t,3)!=12345?:$p[]=$t;foreach($p as$x){for(list($z,$q)=$_GET,$b=1,$i=0;$y=strtr($x,12345,"/%*+-")[$i++];)while(-1<$k=array_flip($q)[$y]){$n=$k+1;if($b&=$z[$n]||ord($y)%10<6)eval("\$z[$k]=$z[$k]$y$z[$n]^0;");($s=array_splice)($z,$n,1);$s($q,$k,1);}$b?$r[]=$z[0]:0;}echo max($r)-min($r);

Probieren Sie es online!

Expanded
for(;$t++<54322;)
  count_chars($t,3)!=12345?:$p[]=$t;
foreach($p as$x){
  for(list($z,$q)=$_GET,$b=1,$i=0;$y=strtr($x,12345,"/%*+-")[$i++];)
    while(-1<$k=array_flip($q)[$y]){
      $n=$k+1;
      if($b&=$z[$n]||ord($y)%10<6)
        eval("\$z[$k]=$z[$k]$y$z[$n]^0;");
      ($s=array_splice)($z,$n,1);
      $s($q,$k,1);
    }
  $b?$r[]=$z[0]:0;
}
echo max($r)-min($r);
Jörg Hülsermann
quelle
Der letzte Fall ist 63. Ihr Fehler, weil derselbe Operator in verschiedenen Teilen eines Ausdrucks eine unterschiedliche Priorität hat
H.PWiz
0

Python 3 , 284 Bytes

Bearbeiten: Es sieht so aus, als ob etwas mit der Bewertung des letzten Beispiels nicht stimmt. Ich werde es morgen untersuchen.

Eine weitere Antwort von Python. Konnte nicht alle anderen übertreiben, aber ich habe zu lange damit verbracht, es nicht zu ertragen.

from itertools import*
def f(n,o):
 z=[]
 for p in permutations("+-*/%"):
  try:
   p,x,a=[*p],n[:],o[:]
   while(p):
    for i,d in enumerate(a):
     if d==p[0]:x[i+1]=str(eval(x[i]+d+x[i+1]));x.pop(i);a.pop(i)
    p.pop(0)
   z+=x
  except:0
 z=[*map(float,z)];return max(z)-min(z)

Probieren Sie es online!

Wrymug
quelle
1
while(p)kann while pfür ein byte gespeichert werden.
Zacharý
0

Clojure (+ Kombinatorik), 342 377 + 41 = 418 Bytes

+35 Bytes wegen eines Fehlers.

(fn[x y](let[l filter s first z #(l(fn[y]y)%)r(sort(z(for[e(q/permutations[+ - * quot mod])](try(loop[t e m y a x](if(=[]t)(s a)(let[j(s t)i(reverse(keep-indexed #(if(= j %2)%)m))](recur(rest t)(l #(not= j %)m)(loop[d 0 h a](if(=(count i)d)h(let[c(nth i d)f(inc c)](recur(inc d)(vec(z(assoc h c(j(nth h c)(nth h f))f nil)))))))))))(catch Exception _ nil)))))](-(last r)(s r))))

Probieren Sie es online!

Für diese Funktion funktioniert, müssen Sie usedie clojure.math.combinatoricsBibliothek (41 Byte):

(use '[clojure.math.combinatorics :as q])

Nuancen:

Diese Funktion ist eine anonyme Funktion, was bedeutet, dass Sie dies tun müssen, um sie zu verwenden:

((fn[x y]...) numbers operators)

Außerdem verwende ich das Wort quotanstelle von /(da Clojure standardmäßig Bruchteile teilt) und modanstelle von %.

Ungolfed-Programm:

(defn precedence [numbers operators]
  (let [results
        (sort
          (for [permute (c/permutations [+ - * / mod])]
            (loop [p-temp permute
                  o-temp operators
                  n-temp numbers]
              (if (empty? o-temp) (first n-temp)
                (let [first-p (first p-temp)
                      indices (reverse (keep-indexed #(when (= first-p %2) %) o-temp))]
                  (recur
                    (rest p-temp)
                    (filter #(not= first-p %) o-temp)
                    (loop [ind 0
                          n-through n-temp]
                      (if (= ind (count indices)) n-through
                        (let [current-ind (nth indices ind)]
                          (recur
                            (inc ind)
                            (vec
                              (filter #(not (nil? %))
                                (assoc n-through
                                  current-ind (first-p (nth n-through current-ind) (nth n-through (inc current-ind)))
                                  (inc current-ind) nil)))))))))))))]
    (- (last results) (first results))))
Clismique
quelle
Ich denke man kann einfach "Closure + Combinatorics" sagen und muss nicht die useAussage treffen.
Esolanging Fruit
@ Challenger5 Ich glaube, du solltest es besser in die Beschreibung schreiben, weil standardmäßig The characters used to import the library will likely be counted codegolf.meta.stackexchange.com/questions/10225/…
Keyu Gan
@KeyuGan Du hast Recht - ich habe diesen Meta-Konsens falsch verstanden. Ich denke , die requireBedürfnisse werden aufgenommen in dem Code und seine Länge sollte auf die Byte - Zählung hinzugefügt werden.
Esolanging Fruit
@ Challenger5 Also muss ich meinem bytecount 41 Bytes hinzufügen, oder? OKAY.
Clismique
@ Qwerp-Derp Ja, aber der Import ist Teil Ihres Codes und Sie können Golf spielen.
Esolanging Fruit
0

JavaScript (ES6), 210 Byte

Eingabe als Array von Zahlen und Operatoren

k=>(m=n=-k,r=(o,k,j=0)=>{for(o||(m=m>k?m:k,n=n<k?n:k);q=o[j++];(q>'%'&q<'/'||z)&&r(o.slice(0,j-1)+o.slice(j),h))for(h=[...k],z=1;i=h.indexOf(q)+1;h.splice(i-2,3,eval(a=h[i-2]+q+h[i])|0))z*=h[i]})('+-*/%',k)|m-n

Weniger golfen

k=>(
  m = n = NaN,
  r =(o, k, j=0) => {
    // try all operators in o
    for(;q = o[j]; j++)
    {  
      // q : current operator, 
      // look for q inside the expression to evaluate
      for(h = [...k], z = 1; i = h.indexOf(q) + 1;)
      {
        a = h[i - 2]
        b = h[i]
        z *= b // trace if any second operand is zero
        // subst subexpression with its value
        h.splice(i - 2, 3, eval(a + q + b) | 0)
      }
      // now all subexp involving current operator are evaluated
      // the result is ok if current operator is not % or /
      //  OR if no second operand was zero
      (q > '%' & q < '/' || z) && 
        // try again recursively
        // using the remaining operators and the remaining expression
        r(o.slice(0, j) + o.slice(j+1), h) 
    }
    // if no more operators to try, check max and min
    // k is an array with 1 element, can be used like a single number
    o || (
      m = m > k ? m : k, 
      n = n < k ? n : k
    )
  },
  r('+-*/%', k),
  m-n
)

Prüfung

var F=
k=>(m=n=-k,r=(o,k,j=0)=>{for(o||(m=m>k?m:k,n=n<k?n:k);q=o[j++];(q>'%'&q<'/'||z)&&r(o.slice(0,j-1)+o.slice(j),h))for(h=[...k],z=1;i=h.indexOf(q)+1;h.splice(i-2,3,eval(a=h[i-2]+q+h[i])|0))z*=h[i]})('+-*/%',k)|m-n

function update() {
  var input = I.value.match(/\d+|\S/g)
  var result = F(input)
  O.textContent = I.value + ' -> ' + result + ' (max:'+m+' min:'+n+')'
}

update()
<input id=I value="60 / 8 % 8 * 6 % 4 * 5" oninput='update()'>
<pre id=O></pre>

edc65
quelle