Hi all!

On Thu, Jul 2, 2009 at 11:09 PM, Laurent PETIT <laurent.pe...@gmail.com>wrote:

> (def push conj)
> (def closing-counterpart { \( \), \[ \] })
> (def opening-char? closing-counterpart)
> (defn matching-pair? [left right] (= right (closing-counterpart left)))
>
> (defn consume-one [stack c]
>  (if (or (opening-char? c)
>          (not (matching-pair? (peek stack) c)))
>    (push stack c)
>    (pop stack)))
>
> (defn balanced? [s]
>  (empty? (reduce consume-one [] s)))
>
> (defn main []
>  (apply print (map balanced? *command-line-args*)))
>
> (when *command-line-args*
>  (main))
>

I think you don't need opening-char?

(defn balanced? [s]
  (let [tr {\( \) \[ \]}]
    (empty?
      (reduce #(if (= (peek %1) %2)
                 (pop %1)
                 (conj %1 (tr %2))) [] s))))

I push "transposed" characters on the stack, thus only \] \) or nil can be
on the stack.
Since nil isn't equal to a character, it will never be popped and thus it
ensures the stack will not be empty.



> It's the second time I wish I had a version of reduce that allows to
> quit the reduction early.



You're not alone Laurent but I'm not sure that's a simple reduce-while is
possible (I can't decide which values to test for early exit (accumulated
result or accumulated result + item) and when (before or after calling the
reducing function)).



-- 
Professional: http://cgrand.net/ (fr)
On Clojure: http://clj-me.blogspot.com/ (en)

--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to