Skip to content

Instantly share code, notes, and snippets.

@technomancy
Last active August 4, 2022 03:03
Show Gist options
  • Save technomancy/e6bf7910ab0c53ba59cac76c1e32bf4e to your computer and use it in GitHub Desktop.
Save technomancy/e6bf7910ab0c53ba59cac76c1e32bf4e to your computer and use it in GitHub Desktop.
;; For this, please write a program which takes in a CLI arg for a string
;; expression such as “1 + 2 - 3” and have it interpret the expression
;; and print the result to stdout. Only support for + and - is needed, to
;; avoid precedence.
(fn evaluate [input]
;; first for regularity, we prepend a + to the input string; this way we end
;; up just looping thru a series of operator/number pairs instead of having
;; numbers with operators between them.
(let [input (.. "+ " input)]
;; the accumulate macro works the same way reduce would in most languages
;; with two important differences: one is that it's a macro, so instead of
;; accepting a reducer function, the body of the macro runs with the
;; bindings set up in the square brackets. our accumulator sum starts at
;; zero, while the op and n values are bound to successive matches to the
;; two things found by the regex.
(accumulate [sum 0
;; the other difference is that instead of iterating over a
;; list, it accepts an iterator, which makes it easy to use
;; with tables but also easy to swap in things like gmatch
;; which yields successive hits to a regex across a string.
op n (input:gmatch "([-+%*/]) ([^ ]+)")]
;; we do a pattern match on the operator from the string match. pattern
;; matching can do a lot more than what we're doing here which could be
;; accomplished with "case" in conventional languages, but for this
;; problem that's all we need.
(match op
;; the requirements say we only need to support + and -, but we might as
;; well extend it to multiplication and division and throw operator
;; precedence out the window, because operator precedence is bogus.
:- (- sum (tonumber n))
:+ (+ sum (tonumber n))
:* (* sum (tonumber n))
:/ (/ sum (tonumber n))))))
(evaluate "1 + 2 - 3") ; -> 0
(evaluate "6 / 2 * 4 - 2 + 99.2") ; -> 109.2
(evaluate "0 + 0 + 1 + 0") ; -> 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment