Hi all!
On Thu, Jul 2, 2009 at 11:09 PM, Laurent PETIT <[email protected]>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 [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
-~----------~----~----~----~------~----~------~--~---