Skip to content

Instantly share code, notes, and snippets.

@jgrodziski
Created November 21, 2013 20:56
Show Gist options
  • Save jgrodziski/7589471 to your computer and use it in GitHub Desktop.
Save jgrodziski/7589471 to your computer and use it in GitHub Desktop.
The source code of the Clojure User Group Paris talk about zipper data structure (nov 2013). Enjoy ! Slides are here : https://speakerdeck.com/jgrodziski/clojure-zipper
(ns zipper.core
(require [clojure.zip :as z]))
(def my-tree ["0" ["1A" "1B" "1C"
["2A" "2B" "2C"
["3A" "3B" "3C"]]
["2D" "2E" "2F"
["3D" "3E"]]
"1D" "1E" "1F"]])
;;creation
(def zip (z/vector-zip my-tree))
;;walking the tree to get 2A : down right down
(-> zip
z/down;;now at "0"
z/right;;now on first branch (this is a vector)
z/down;;now on 1A
z/right;now on 1B
z/right;;now on 1C
z/right;;now on 2nd level branch (this is a vector)
z/down;;now on 2A
z/node;;return the node value
)
;;=> "2A"
;;editing the tree to concatenate λ with "2A" node
;;achtung! return the current loc (need to (root) to get back to the
;;root node (achtung not a loc!)
(z/edit (-> zip z/down z/right z/down z/right z/right z/right z/down) (partial str "λ"))
(z/root (z/edit (-> zip z/down z/right z/down z/right z/right z/right z/down) (partial str "λ")))
;;=> "λ2A"
;;your own walk
(defn my-walk [root-loc f]
(loop [loc root-loc]
(if (z/end? loc)
(z/root loc)
(do
(f (z/node loc))
(recur (z/next loc))))))
;;another way (mundane recursion call) to concatenate λ with "2A" node with indexes
(update-in my-tree [1 3 0] (partial str "λ"))
;;=> ["0" ["1A" "1B" "1C" ["λ2A" "2B" "2C" ["3A" "3B" "3C"]] ["2D" "2E" "2F" ["3D" "3E"]] "1D" "1E" "1F"]]
(defn generate-v-of-v
([depth nodes-nbr] (generate-v-of-v depth nodes-nbr (partial rand-int 100) nil))
([depth nodes-nbr make-node parent]
(let [root []
odd (max 3 (+ (/ nodes-nbr depth) 2))]
(loop [loc root
d 1
n nodes-nbr]
(let [direction (rand-int odd)
down? (and (= 1 direction) (<= d depth))
right? (not down?)]
(cond (<= n 0) loc
down? (let [branch (generate-v-of-v (inc d) n make-node loc)]
(recur (conj loc branch) (inc d) (- n (count branch))))
right? (recur (conj loc (make-node)) d (dec n))
))))))
(def apps-dir (clojure.java.io/file "/Applications"))
(def tmp-dir (clojure.java.io/file "/tmp"))
(defn file-zip [dir]
(z/zipper (fn [f] (.isDirectory f))
(fn [f] (.listFiles f))
(fn [dir files]
(doseq [file files]
(if (string? file)
(.createNewFile (java.io.File. dir file)))))
dir))
(def apps (file-zip apps-dir))
(def tmp (file-zip tmp-dir))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment