Build Order - Using Clojure to determine build order

less than 1 minute read

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)

Updated: