Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ES7 Code Golf Progression
- This time, I have a program that takes numerical expressions with the parentheses, exponentiation, multiplication, division, addition, and subtraction and outputs each successive step used to solve the expression using order of operations. Example inputs:
- ```
- 1+1
- (51*5)/8
- 63/(91*(5+779))
- ```
- Spaces are the only types of whitespace allowed.
- Before I start, I almost always think about the algorithm I will use to solve the problem:
- - Take an input using the browser prompt, cleaning out whitespace.
- - If there are parentheses, jump to the innermost nested parentheses and begin evaluation.
- - Recursively replace (in order) exponents, multiplication/division, and addition/subtraction in the form of "[number][operation][number]=[result]".
- - Replace the innermost parentheses with the result from step 3 and go back to step 2 unless the result is only a number.
- - Of course, this algorithm is subject to change, but it should be enough to get going.
- ##INITIAL PROGRAM
- ```js
- i=c=prompt().replace(/\s/g,'')
- R=(t,r)=>{
- T=t.replace(r,a=>(alert(a+`=`+eval(a)),eval(a)))
- return t!=T?R(T,r):t
- }
- while(isNaN(i)){
- z=(x=c.match(/\(([^()]+)\)/))?(c=x[1]):0
- c=R(R(R(c,/\d+\*\*\d+/),/\d+[*\/]\d+/),/\d+[+-]\d+/)
- i=c=z?i.replace(/\(([^()]+)\)/,c):c
- }
- ```
- I always shorten the variables down before code-golfing to save time and effort. If you have trouble keeping track of the variables, just comment what they do:
- ```js
- // R => recursive replace & output function
- // i => input (will become output)
- // c => copy of i, used to evaluate innermost parentheses
- // z => checks if i has any parentheses left
- ```
- I also did some light golfing in my initial program to save time later on.
- ##FIRST GOLFS
- At this point, I'll do some easy saves.
- Lambdas can return the last statement, which means this:
- ```js
- R=(t,r)=>(T=t.replace(r,a=>(alert(a+`=`+eval(a)),eval(a))),t!=T?R(T,r):t)
- ```
- Some rearrangements make the lambda even shorter:
- ```js
- R=(t,r,T=t.replace(r,a=>(alert(a+`=`+eval(a)),eval(a))))=>t!=T?R(T,r):t
- ```
- Aliasing is useful (both for "replace" and the parentheses regex):
- ```js
- i=c=prompt()[b='replace'](/\s/g,'')
- R=(t,r,T=t[b](r,a=>(alert(a+`=`+eval(a)),eval(a))))=>t!=T?R(T,r):t
- while(isNaN(i)){
- z=(x=c.match(p=/\(([^()]+)\)/))?(c=x[1],1):0
- c=R(R(R(c,/\d+\*\*\d+/),/\d+[*\/]\d+/),/\d+[+-]\d+/)
- i=c=z?i[b](p=/\(([^()]+)\)/,c):c
- }
- ```
- isNaN(i) can be shortened in this case:
- ```js
- while(!+i){...}
- ```
- ##BIG GOLF #1
- At this point, I see a possible big save in byte count.
- ```js
- b='replace'
- i=`(${prompt()[b](/\s/g,'')})`
- R=(t,r,o=a=>(alert(a+`=`+eval(a)),eval(a)),T=t[b](r,o))=>t!=T?R(T,r,o):t
- R(i,/\(([^()]+)\)/,(X,Y)=>R(R(R(Y,/\d+\*\*\d+/),/\d+[*\/]\d+/),/\d+[+-]\d+/))
- ```
- Changes made:
- - Completely took out the while loop, using the recursive replace to parse the parentheses.
- - Modified R to also have a function argument (which defaults to alerting the expression and result).
- - Wrapped the input in parentheses before passing it to R to evaluate the last expression correctly.
- ##FINAL GOLFS
- Aliasing "replace" now costs instead of saves bytes, so I'll take that out:
- ```js
- i=`(${prompt().replace(/\s/g,'')})`
- R=(t,r,o=a=>(alert(a+`=`+eval(a)),eval(a)),T=t.replace(r,o))=>t!=T?R(T,r,o):t
- R(i,/\(([^()]+)\)/,(X,Y)=>R(R(R(Y,/\d+\*\*\d+/),/\d+[*\/]\d+/),/\d+[+-]\d+/))
- ```
- Since i is only used one other time, I'll just inline it:
- ```js
- R=(t,r,o=a=>(alert(a+`=`+eval(a)),eval(a)),T=t.replace(r,o))=>t!=T?R(T,r,o):t
- R(`(${prompt().replace(/\s/g,'')})`,/\(([^()]+)\)/,(X,Y)=>R(R(R(Y,/\d+\*\*\d+/),/\d+[*\/]\d+/),/\d+[+-]\d+/))
- ```
- I can save a few bytes using a lambda rather than prompt for input:
- ```js
- I=>(R=(t,r,o=a=>(alert(a+`=`+eval(a)),eval(a)),T=t.replace(r,o))=>t!=T?R(T,r,o):t,R(`(${I.replace(/\s/g,'')})`,/\(([^()]+)\)/,(X,Y)=>R(R(R(Y,/\d+\*\*\d+/),/\d+[*\/]\d+/),/\d+[+-]\d+/)))
- ```
- I can also replace the second replace with R:
- ```js
- I=>(R=(t,r,o=a=>(alert(a+`=`+eval(a)),eval(a)),T=t.replace(r,o))=>t!=T?R(T,r,o):t,R(`(${R(I,' ','')})`,/\(([^()]+)\)/,(X,Y)=>R(R(R(Y,/\d+\*\*\d+/),/\d+[*\/]\d+/),/\d+[+-]\d+/)))
- ```
- And that's the final, fully-golfed program at 177 bytes, much shorter than the ~270-byte initial program.
- Annotated:
- ```js
- I=>(
- R= // recursive replace/expression output
- (t, // string to be modified
- r, // regex
- o=a=>(alert(a+`=`+eval(a)),eval(a)), // replacement function
- // defaults to expression output + return eval'd result
- T=t.replace(r,o) // the crucial replacement part
- )=>t!=T?R(T,r,o):t, // keep replacing t until it has no replacements left
- R(`(${R(I,' ','')})`, // take the input, strip all spaces, and wrap in parentheses
- /\(([^()]+)\)/, // evaluate expressions in parentheses inside-out
- (X,Y)=>R(R(R(Y, // replace innermost parentheses with result of:
- /\d+\*\*\d+/), // eval **
- /\d+[*\/]\d+/), // eval * /
- /\d+[+-]\d+/) // eval + -
- )
- )
- ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement