Skip to content

Instantly share code, notes, and snippets.

@heralden
Created May 5, 2018 15:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heralden/e900ef67a3c95aca2b26ac42a72ca47e to your computer and use it in GitHub Desktop.
Save heralden/e900ef67a3c95aca2b26ac42a72ca47e to your computer and use it in GitHub Desktop.
(defn v->m [pers]
"Helper to quickly create persons maps"
(mapv (fn [v] {:weight (first v), :floor (second v)}) pers))
(defn nextv [v]
"Cheating next that returns vector"
(subvec v 1))
(defn total-weight [elevator]
(reduce + (map :weight elevator)))
(defn ground-elevator? [floors]
(or (empty? floors)
(= (peek floors) :G)))
(defn full-elevator? [elevator next-person max-load max-count]
(let [next-elevator (conj elevator next-person)
next-load (total-weight next-elevator)
next-count (count next-elevator)]
(or (> next-load max-load)
(> next-count max-count))))
(defn active-elevator? [elevator floors]
(and (not (empty? elevator))
(not (ground-elevator? floors))))
(defn load-elevator [floors ground elevator]
[(if (ground-elevator? floors) floors (conj floors :G))
(nextv ground)
(conj elevator (first ground))])
(defn unload-elevator [floors ground elevator]
[(conj floors (:floor (first elevator)))
ground
(nextv elevator)])
(defn elevator-stops [max-load max-count persons]
(loop [[floors ground elevator] [[] persons []]]
(cond
(and (empty? ground) (empty? elevator)) (conj floors :G)
(or (empty? ground)
(full-elevator? elevator (first ground) max-load max-count)
(active-elevator? elevator floors))
(recur (unload-elevator floors ground elevator))
:else (recur (load-elevator floors ground elevator)))))
; user=> (elevator-stops 200 3 (v->m [[60 2] [80 3] [40 5]]))
; [2 3 5 :G]
; user=> (elevator-stops 200 2 (v->m [[60 2] [80 3] [40 5]]))
; [2 3 :G 5 :G]
; user=> (elevator-stops 180 3 (v->m [[110 3] [80 3] [40 5] [50 4] [40 2]]))
; [3 :G 3 5 4 :G 2 :G]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment