Build Order - Using Clojure to determine build order
Code
;; build_order.clj
(def graph {:h []
:c [:a :b]
:e [:d :f]
:g [:c :e]})
(defn has-no-dependency? [node graph]
(empty? (get graph node [])))
(defn all-build-steps [graph]
(let [graph-keys (keys graph)
graph-vals (apply concat (vals graph))
all-builds (concat graph-keys graph-vals)]
all-builds))
(defn remove-element [list element]
(remove #(= % element) list))
(defn remove-key [graph key]
(dissoc graph key))
(defn remove-value [graph key value]
(update graph key remove-element value))
(defn remove-values [graph value]
(let [graph-keys (keys graph)]
(reduce #(remove-value %1 %2 value) graph graph-keys)))
(defn remove-key-and-values [graph element]
(remove-values (remove-key graph element) element))
(defn recommend-build-step [graph]
(let [all-steps (all-build-steps graph)]
(first (filter #(has-no-dependency? % graph) all-steps))))
(defn build-order ([graph build-steps]
(let [build-step (recommend-build-step graph)]
(if (nil? build-step)
build-steps
(recur (remove-key-and-values graph build-step)
(conj build-steps build-step)))))
([graph] (build-order graph [])))
(build-order graph)