The easiest way would be to factor out the bracket matching code, since that's the only thing that changes between your different case statements. For instance:
(defn valid-parens? [s] (let [opening-brackets {\( \), \[ \], \{ \}} closing-brackets (clojure.set/map-invert opening-brackets)] (loop [cs (seq s), stack []] (if-not cs (empty? stack) (let [c (first cs), cs (next cs)] (if (opening-brackets c) (recur cs (conj stack c)) (if-let [b (closing-brackets c)] (if (= (peek stack) b) (recur cs (pop stack)) false) (recur cs stack))))))) Another way you could do it is to replace your recursive call with a continuation. - James On 26 June 2016 at 13:43, Botond Balázs <balazsbot...@gmail.com> wrote: > Hi, > > Here is my solution to 4clojure problem #177: > > Write a function that takes in a string and returns truthy if all square [ >> ] round ( ) and curly { } brackets are properly paired and legally nested, >> or returns falsey otherwise. >> > > (defn valid-parens? > [s] > (loop [[ch & chs] s stack []] > (if (nil? ch) > (empty? stack) > (case ch > (\( \[ \{) (recur chs (conj stack ch)) > \) (if (= (peek stack) \() > (recur chs (pop stack)) > false) > \] (if (= (peek stack) \[) > (recur chs (pop stack)) > false) > \} (if (= (peek stack) \{) > (recur chs (pop stack)) > false) > (recur chs stack))))) > > This works but I don't like the repetition in the case branches. But the > repeated code contains a recur call so I can't simply refactor it into a > helper function. How can I achieves something like the following, but > without consuming the stack? > > (defn valid-parens? > ([s] > (valid-parens? s [])) > ([[ch & chs] stack] > (if (nil? ch) > (empty? stack) > (letfn [(match? [p] > (if (= (peek stack) p) > (valid-parens? chs (pop stack)) > false))] > (case ch > (\( \[ \{) (valid-parens? chs (conj stack ch)) > \) (match? \() > \] (match? \[) > \} (match? \{) > (valid-parens? chs stack)))))) > > Thanks! > Botond > > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.