| 1 | (ns adventofcode2019.day06 |
| 2 | [:require [adventofcode2019.lib :refer :all] |
| 3 | [clojure.string :as str]]) |
| 4 | |
| 5 | (defn a-orbits-b [orbits-map [b a]] |
| 6 | (if (contains? orbits-map b) |
| 7 | (-> (assoc orbits-map a {:parent b, :children (get-in orbits-map [a :children] [])}) |
| 8 | (update-in [b :children] conj a)) |
| 9 | (-> (assoc orbits-map b {:parent nil, :children []}) |
| 10 | (a-orbits-b [b a])))) |
| 11 | |
| 12 | (defn distances-from [tree node] |
| 13 | (letfn [(path-rc [dist tree node] |
| 14 | (let [seen? #(some? (get-in tree [% :dist])) |
| 15 | neighbors (remove (some-fn nil? seen?) |
| 16 | (cons (get-in tree [node :parent]) |
| 17 | (get-in tree [node :children])))] |
| 18 | (as-> tree it |
| 19 | (assoc-in it [node :dist] dist) |
| 20 | (reduce #(path-rc (inc dist) %1 %2) it neighbors))))] |
| 21 | (path-rc 0 tree node))) |
| 22 | |
| 23 | (defn assign-depth [tree] |
| 24 | (let [is-root? #(nil? (get-in tree [% :parent])) |
| 25 | root (first (filter is-root? (keys tree)))] |
| 26 | (letfn [(depth-rc [depth tree root] |
| 27 | (as-> tree it |
| 28 | (assoc-in it [root :depth] depth) |
| 29 | (reduce #(depth-rc (inc depth) %1 %2) |
| 30 | it (get-in tree [root :children]))))] |
| 31 | (depth-rc 0 tree root)))) |
| 32 | |
| 33 | (defn day06 [] |
| 34 | (let [input (map #(str/split % #"\)") (get-list-from-file (input-file))) |
| 35 | orbits-map (reduce a-orbits-b {} input) |
| 36 | with-depths (assign-depth orbits-map)] |
| 37 | (part1 (reduce + (map :depth (vals with-depths)))) |
| 38 | (part2 (- (get-in (distances-from orbits-map "YOU") ["SAN" :dist]) 2)))) |