August 13, 2018

4clojure 177 - Balancing Brackets

When parsing a snippet of code it's often a good idea to do a sanity check to see if all the brackets match up. 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.

(ns live.test
  (:require [cljs.test :refer-macros [deftest is run-tests]]))
  
(defn balanced? [s]
  (let [p {\( \) \[ \] \{ \}}
        a (set "()[]{}")]
    (empty?
      (reduce (fn [[t & b :as stack] s]
                (cond (= (p t) s) b
                      (a s) (conj stack s)
                      :else stack))
              () s))))
              
(deftest balanced?-test
  (is (balanced? "This string has no brackets."))
  (is (balanced? "class Test {
      public static void main(String[] args) {
        System.out.println(\"Hello world.\");
      }
    }"))
  (is (not (balanced? "(start, end]")))
  (is (not (balanced? "())")))
  (is (not (balanced? "[ { ] } ")))
  (is (balanced? "([]([(()){()}(()(()))(([[]]({}()))())]((((()()))))))"))
  (is (not (balanced? "([]([(()){()}(()(()))(([[]]({}([)))())]((((()()))))))")))
  (is (not (balanced? "["))))

(run-tests)
Tags: coding exercises KLIPSE 4clojure Clojure parsing