(ns adventofcode2019.day06 [:require [adventofcode2019.lib :refer :all] [clojure.string :as str]]) (defn a-orbits-b [orbits-map [b a]] (if (contains? orbits-map b) (-> (assoc orbits-map a {:parent b, :children (get-in orbits-map [a :children] [])}) (update-in [b :children] conj a)) (-> (assoc orbits-map b {:parent nil, :children []}) (a-orbits-b [b a])))) (defn distances-from [tree node] (letfn [(path-rc [dist tree node] (let [seen? #(some? (get-in tree [% :dist])) neighbors (remove (some-fn nil? seen?) (cons (get-in tree [node :parent]) (get-in tree [node :children])))] (as-> tree it (assoc-in it [node :dist] dist) (reduce #(path-rc (inc dist) %1 %2) it neighbors))))] (path-rc 0 tree node))) (defn assign-depth [tree] (let [is-root? #(nil? (get-in tree [% :parent])) root (first (filter is-root? (keys tree)))] (letfn [(depth-rc [depth tree root] (as-> tree it (assoc-in it [root :depth] depth) (reduce #(depth-rc (inc depth) %1 %2) it (get-in tree [root :children]))))] (depth-rc 0 tree root)))) (defn day06 [] (let [input (map #(str/split % #"\)") (get-list-from-file (input-file))) orbits-map (reduce a-orbits-b {} input) with-depths (assign-depth orbits-map)] (part1 (reduce + (map :depth (vals with-depths)))) (part2 (- (get-in (distances-from orbits-map "YOU") ["SAN" :dist]) 2))))