diff --git a/2017/src/day07.clj b/2017/src/day07.clj new file mode 100644 index 0000000..023a575 --- /dev/null +++ b/2017/src/day07.clj @@ -0,0 +1,67 @@ +(ns day07 + (:require + [clojure.string :as str] + [core :refer [split-whitespace]] + [input-manager])) + +(def input + (->> (input-manager/get-input-raw 2017 7) + str/split-lines + (map (comp split-whitespace + #(str/replace % #"," ""))))) + +;; part 1 +(def base-node + (->> input + (filter (fn [[_ _ _ & children]] children)) + (filter (fn [[node]] + (empty? (filter (fn [[_ _ _ & children]] + (some #(= % node) children)) + input)))) + ffirst)) + +(do + (def get-depth + (memoize (fn [node] + (let [[_ w-str _ & children] (first (filter (fn [[n]] (= node n)) + input)) + w (parse-long (subs w-str 1 (dec (count w-str))))] + (apply + w (map get-depth children)))))) + (def get-weight + (memoize (fn [node] + (let [w-str (->> input + (filter (fn [[n]] (= node n))) + first + second)] + (parse-long (subs w-str 1 (dec (count w-str)))))))) + (def get-children + (memoize (fn [node] (->> input + (filter (fn [[n]] (= node n))) + first + (drop 3)))))) + +(defn get-children-data [node] + (map (juxt identity get-depth get-weight) (get-children node))) + +(defn get-counts [data] + (->> data + (map second) + frequencies + (sort-by second))) + +;; part 2 +(let [[bad-parent bad-node] + (loop [parent nil + node base-node] + (let [data (get-children-data node) + counts (get-counts data) + row (first (filter #(= (second %) (ffirst counts)) data))] + (if (= (count counts) 1) + [parent node] + (recur node (first row))))) + diff (->> bad-parent + get-children-data + get-counts + (map first) + (apply -))] + (- (get-weight bad-node) diff))