Skip to content

Instantly share code, notes, and snippets.

@jesse-c
Last active June 4, 2019 06:00
Show Gist options
  • Save jesse-c/bd7605b53cb4cb9390192475514bf9fb to your computer and use it in GitHub Desktop.
Save jesse-c/bd7605b53cb4cb9390192475514bf9fb to your computer and use it in GitHub Desktop.
(defn step [direction level]
(cond
(identical? direction \U) (+ level 1)
(identical? direction \D) (- level 1)
:else level))
(defn monitor [total direction level]
(if (and (zero? level) (identical? direction \U))
(+ total 1)
total))
(defn cv [n s total level]
(let [direction (first s)
level' (step direction level)]
(if (or (zero? n) (empty? s))
total
(cv (- n 1) (rest s) (monitor total direction level') level'))))
(defn countingValleys [n s]
(cv n s 0 0))
(-> (countingValleys 8 "UDDDUDUU")
(println)) ;; 1
(-> (countingValleys 12 "DDUUDDUDUUUD")
(println)) ;; 2
@Vaelatern
Copy link

I appreciate your kind words, thank you.

As the recur documentation says: Evaluates the exprs in order, then, in parallel, rebinds the bindings of the recursion point to the values of the exprs. So yes, it's tail-call optimization by effectively making it a loop instead of consuming stack. You can control where that binding begins with loop (which is basically let but says "A recur should come back to here").

As for a function for everything, it's really the most common patterns. Incrementing and decrementing happen to be quite useful patterns to understand at a glance. The function I most recently discovered was not=. Finally I could stop writing (not (= a b))! In short, the cheatsheet should stay open while you code: clojure documentation is brilliant.

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