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 <[email protected]> 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 [email protected]
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected].
> 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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.