-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproblem_177.clj
52 lines (45 loc) · 1.9 KB
/
problem_177.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
(ns paren_match
"This is my solution to 4Clojure problem #177, 'Balancing Brackets'.
See http://www.4clojure.com/problem/177 .
(Also see my Haskell solution,
~/Development/Haskell/Misc.Play/is-string-valid.hs .)
-- Tyler"
(:require [clojure.test :refer :all]))
(defn balanced?
"Decides whether or not the given string is balanced with respect to the
Char pairs in mates. The nil value is used internally to register failure.
Consequently, although the given expression may be a collection of characters
instead of a string, it must not contain nil."
[expression]
(let [mates {\( \), \[ \], \{ \}} ; Characters that must balance.
is-closing-char (set (vals mates)) ; Truthy iff char arg. closes expr.
step (fn [targets x]
(cond
(= x (first targets)) (rest targets) ; Hit the target.
(is-closing-char x) [nil] ; Forbidden. FAIL
:else (if-let [mate (mates x)]
(cons mate targets) ; New target.
targets))) ; Ordinary char.
]
(empty? (reduce step [] expression))))
(deftest ballanced?-tests
(are [expression result]
(= (balanced? expression) result)
"" true
"This string has no brackets."
true
"class Test {
public static void main(String[] args) {
System.out.println(\"Hello world.\");
}
}
" true
"(start, end]" false
"())" false
"[ { ] } " false
"([]([(()){()}(()(()))(([[]]({}()))())]((((()()))))))"
true
"([]([(()){()}(()(()))(([[]]({}([)))())]((((()()))))))"
false
"[" false
))