Skip to content

Instantly share code, notes, and snippets.

@davidagold
Last active October 7, 2018 16:58
Show Gist options
  • Save davidagold/b94552828f4cf33dd3c8 to your computer and use it in GitHub Desktop.
Save davidagold/b94552828f4cf33dd3c8 to your computer and use it in GitHub Desktop.
Simplify arithmetic expressions
function simplify(e::Expr)
_simplify(e)
end
_simplify(e) = e
function _simplify(e::Expr)
# apply the following only to expressions that call a function on arguments
if e.head == :call
op = e.args[1] # in such expressions, `args[1]` is the called function
simplified_args = [ _simplify(arg) for arg in e.args[2:end] ]
if op == :(*)
in(0, e.args[2:end]) && return 0 # return 0 if any args are 0
simplified_args = simplified_args[simplified_args .!= 1] # remove 1s
elseif op == :(+)
simplified_args = simplified_args[simplified_args .!= 0] # remove 0s
end
length(simplified_args) == 0 ? 0 :
length(simplified_args) == 1 ? simplified_args[1] :
return Expr(:call, op, simplified_args...)
end
end
@davidagold
Copy link
Author

The above can be used to simplify the original expression in this post:

# wrapping code between `:(` and `)` parses the code into an Expr object
julia> e = :( (1 + 0 * x) * 3 + 12 )
:((1 + 0x) * 3 + 12)

julia> simplify(e)
:(+1 * 3 + 12)

julia> eval(ans)
15

But it will also simplify expressions in which arbitrarily complex function calls are passed to + or *:

julia> simplify(:( (0 * f(g(x))) + 2 + (3 * h(x, y)) ))
:(2 + 3 * h(x,y))

@J-Sarnoff
Copy link

Julia, you will do work for me so easily!? That is are all kinds of refreshing.
(regards to your friend, david)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment