(use 'clojure.set) ;; Not actually used here, but will be in exercises. (def answer-annotations (fn [courses registrants-courses] (let [checking-set (set registrants-courses)] (map (fn [course] (assoc course :spaces-left (- (:limit course) (:registered course)) :already-in? (contains? checking-set (:course-name course)))) courses)))) (def domain-annotations (fn [courses] (map (fn [course] (assoc course :empty? (zero? (:registered course)) :full? (zero? (:spaces-left course)))) courses))) (def note-unavailability (fn [courses instructor-count] (let [out-of-instructors? (= instructor-count (count (filter (fn [course] (not (:empty? course))) courses)))] (map (fn [course] (assoc course :unavailable? (or (:full? course) (and out-of-instructors? (:empty? course))))) courses)))) (def annotate (fn [courses registrants-courses instructor-count] (note-unavailability (domain-annotations (answer-annotations courses registrants-courses)) instructor-count))) (def annotate (fn [courses registrants-courses instructor-count] (let [answers (answer-annotations courses registrants-courses) domain (domain-annotations answers)] note-unavailability domain instructor-count))) (def annotate (fn [courses registrants-courses instructor-count] (-> courses (answer-annotations registrants-courses) domain-annotations (note-unavailability instructor-count)))) (def separate (fn [pred sequence] [(filter pred sequence) (remove pred sequence)])) (def visible-courses (fn [courses] (let [[guaranteed possibles] (separate :already-in? courses)] (concat guaranteed (remove :unavailable? possibles))))) (def final-shape (fn [courses] (let [desired-keys [:course-name :morning? :registered :spaces-left :already-in?]] (map (fn [course] (select-keys course desired-keys)) courses)))) (def half-day-solution (fn [courses registrants-courses instructor-count] (-> courses (annotate registrants-courses instructor-count) visible-courses ((fn [courses] (sort-by :course-name courses))) final-shape))) (def solution (fn [courses registrants-courses instructor-count] (map (fn [courses] (half-day-solution courses registrants-courses instructor-count)) (separate :morning? courses))))