Skip to content

Instantly share code, notes, and snippets.

@PEZ
Last active April 11, 2023 15:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PEZ/6b8d50ee0811042bdc646dc9060037e8 to your computer and use it in GitHub Desktop.
Save PEZ/6b8d50ee0811042bdc646dc9060037e8 to your computer and use it in GitHub Desktop.
Balancing Brackets – Rich 4Clojure Problem 177 – See: https://github.com/PEZ/rich4clojure
(ns rich4clojure.medium.problem-177
(:require [hyperfiddle.rcf :refer [tests]]))
;; = Balancing Brackets =
;; By 4Clojure user: daowen
;; Difficulty: Medium
;; Tags: [parsing]
;;
;; 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.
(def __ :tests-will-fail)
(comment
)
(tests
"This string has no brackets." :=
"class Test {
public static void main(String[] args) {
System.out.println(\"Hello world.\");
}
}" :=
(__ "(start, end]") :=
(__ "())") :=
(__ "[ { ] } ") :=
"([]([(()){()}(()(()))(([[]]({}()))())]((((()()))))))" :=
(__ "([]([(()){()}(()(()))(([[]]({}([)))())]((((()()))))))") :=
(__ "[") :=)
;; To participate, fork:
;; https://github.com/PEZ/rich4clojure
;; Post your solution below, please!
@StanTheBear
Copy link

(defn __
  "truthy all square [] round () and curly {} brackets properly paired legally nested"
  [col]
  (let [close                   ;; test if start end brks match
        (fn close
          [start end]
          (case [start end]
            ([\[ \]], [\( \)], [\{ \}])  true false))
        pred #{\[ \] \( \) \{ \}}
        brk-step
        (fn brk-step
          ([c] (brk-step c []))
          ([c stack]
           (let [fil (filter pred c)]
             (if (zero? (count fil)) true              ; fil 0 brks so true
                 (when-let [s (seq fil)]               ; > 0 brks get seq s
                   (if (= 1 (count s))                 ; last in s  
                     (close (peek stack) (first s)) ; true if stack matches this brk
                     (if (close (first s) (second s))
                       (recur (rest (rest s)) stack)
                       (if (close (peek stack) (first s)) ; stack and 1st s = bracket
                         (recur (rest s) (pop stack))     ; pop stack and rest s
                         (recur (rest s) (conj stack (first s))); solo s, push on stack
                         ))))))))]
    (brk-step col)))

@StanTheBear
Copy link

StanTheBear commented Oct 18, 2022

Worked a reduce version.

(defn m__
  "truthy all square [] round () and curly {} brackets properly paired legally nested"
  [col]
  (let [close (fn close                 ;; test if start end brks match
                [start end] (case [start end] ([\[ \]], [\( \)], [\{ \}])  true false))
        pred #{\[ \] \( \) \{ \}}
        fil (filter pred col)]
    (not (seq (reduce
               #(if (close (peek %1) %2) ; stack and this s = bracket
                  (pop %1)     ; pop stack drop this s
                  (conj %1 %2)); solo this s, push on stack
               []  ; stack as accumulator
               fil)))))

@onstop4
Copy link

onstop4 commented Apr 11, 2023

(def opening-brackets {\( \), \[ \], \{ \}})
(def closing-brackets (set (vals opening-brackets)))

(defn __ [s]
    (let [result (reduce
        (fn [[f & r :as together] c]
            (cond
                (opening-brackets c) (cons c together)
                (= (opening-brackets f) c) r
                (not (closing-brackets c)) together
                :else (reduced false))
        ) '() s)]
        (or (nil? result) (and result (empty? result)))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment