### re: Advent of Code 2019 Solution Megathread - Day 6: Universal Orbit Map VIEW POST

Part 1 was a no-brainer in clojure:

``````; Returns the number of orbits the given object is contained in (i.e. direct orbit + indirect orbits)
(defn orbit-centers [orbit-map object]
(count (take-while some? (drop 1 (iterate orbit-map object)))))

; Returns the sum of the orbit centers for each object in the orbit map.
(defn direct-and-indirect-orbits [orbit-map]
(apply + (map (partial orbit-centers orbit-map) (keys orbit-map))))

; Parses the input format into a map of object -> orbit center
(defn parse-orbit-map [raw]
(apply hash-map (flatten (map (comp reverse #(.split #"\)" %)) (.split #"\n" raw)))))

(def input (parse-orbit-map (slurp (first *command-line-args*))))
(println "Total number of (in)direct orbits:" (direct-and-indirect-orbits input))
``````

I kinda got stuck on part 2, so the solution for this isn't really optimal (takes around half a second):

``````; Returns a sequence of objects that orbit the given center
(defn orbiting [orbit-map center]
(map first (filter #(= (% 1) center) orbit-map)))

; Calculates the minimum amount of traversals required in an orbit map to move from object to destination
; (This is currently very inefficient and bad, I might still improve it)
(defn traversals [orbit-map object destination]
(condp = object
nil Integer/MIN_VALUE
destination -2
(inc (apply max (traversals (dissoc orbit-map object) (orbit-map object) destination)
(for [orbit-obj (orbiting (dissoc orbit-map object) object)]
(traversals (dissoc orbit-map orbit-obj) orbit-obj destination))))))

(println "Traversals required to get from you to santa:" (traversals input "YOU" "SAN"))
``````

Fun one nonetheless!

I am fake upset you didn't break out the clojure zipper library for this! (it's like using a cannon for flies in this case)

Oh, I will definitely look into that, thanks for the suggestion.
I'm still a newbie in clj.

Zipper is extremely powerful for navigating trees efficiently.

I vastly improved it without using zippers now.

``````; Counts the amount of elements in coll before element appears. Returns (count coll) if it doesn't appear at all.
(defn count-until [element coll]
(count (take-while (partial not= element) coll)))

; Calculates the minimum amount of traversals required in an orbit map to move from object to destination
(defn traversals [orbit-map object destination]
(let [object-centers (orbit-centers orbit-map object)
destination-centers (orbit-centers orbit-map destination)
first-common-center (some (set destination-centers) object-centers)]
(+ (count-until first-common-center object-centers)
(count-until first-common-center destination-centers))))
``````

I just fetch the first common center of both objects and add the steps it takes to get there for both.

Code of Conduct Report abuse