2

I'm trying to implement an algorithm to find the depth of a sequence expression through Clojure Zippers.

(zip/seq-zip (+ 1 (* 2 3)))

This is the way I'm interpreting a sequence to be converted into a tree data structure. Is there a direct method to calculate this through Zipper library(the depth to be calculated as 2, from the given example)?

Any suggestions would be appreciated!

Coding active
  • 1,620
  • 3
  • 23
  • 40
  • 2
    My suggestion would be to not use zippers, they are making the matter more complicated. `(fn depth [x] (if (seq? x) (reduce max 0 (map depth x)) 0))`. A zipper solution would we littered with movement commands, burying the lede. – cgrand Jul 07 '15 at 10:29
  • 2
    That will always return 0. (fn depth [x d] (if (seq? x) (apply max (map #(depth % (inc d)) x)) d)). d should be initially 0. – turingcomplete Jul 07 '15 at 10:57
  • 1
    @turingcomplete true, thanks -- that's what I get for not testing code. – cgrand Jul 07 '15 at 11:57

2 Answers2

3

You can use the following recursive approach:

(defn height [s-expr]
  (if-let [sub-trees (seq (filter coll? s-expr))]
    (inc
     (apply max
            (map height sub-trees)))
    0))


=> (height '(+ 1 (* 2 3)))
=> 1

Effectively the above treats collections as branches and everything else as leaves. You can replace coll? with any other branch definition (e.g. list?) that fits your needs.

Symfrog
  • 3,398
  • 1
  • 17
  • 13
  • As ```height``` is a single argument form, you could set the recursive map as ```(map height sub-trees)``` – Frank C. Jul 07 '15 at 12:50
  • FYI. `(apply max (map f s))` can be replaced with `(apply max-key f s) if `f` returns a number. – tnoda Jul 08 '15 at 12:49
0

You might want to compute both the minimum and maximum heights of a tree. In that case you can extend this approach to include a comp function argument to determine that selection criteria.

;; Compute the height (either min or max, according to the `comp` function)
;; of the tree `tree`. Trees must be expressed as nested sequences.
(defn height
  [tree comp]
  (if (coll? tree)
    (inc (apply comp (map #(height % comp) tree)))
    0))

(defn max-height [tree] (height tree max))
(defn min-height [tree] (height tree min))
jverce
  • 36
  • 1
  • 4