This is not too hard with some recursion:
(defn numbers->tree [xs]
(letfn [(step [xs]
(loop [ret [], remainder xs]
(if (empty? remainder)
[ret remainder]
(let [x (first remainder)]
(case x
0 [ret (next remainder)]
-1 (let [[ret' remainder'] (step (next remainder))]
(recur (conj ret ret'), remainder'))
(recur (conj ret x) (next remainder)))))))]
(first (step xs))))
The idea is to have a function (step
) that finds a sub-tree, and returns that tree as well as what numbers are left to be processed. It proceeds iteratively (via loop
) for most inputs, and starts a recursive instance of itself when it runs into a -1
. The only tricky part is making sure to use the remainder
returned from these recursive invocations, rather than proceeding on with the list you were in the middle of.