+ [clojure.set :as set]])
+
+(defn to-sightline [[a-x a-y] [b-x b-y]]
+ (let [dy (- a-y b-y)
+ dx (- a-x b-x)
+ slope (if (zero? dx) :inf (rationalize (/ dy dx)))]
+ [(neg? dy) (neg? dx) slope]))
+
+(defn order-sightlines [left right]
+ (let [set-order #(match [%1 %2 %3]
+ [false false :inf] [1 0]
+ [false true r] [2 r]
+ [false true 0] [3 0]
+ [true true r] [4 r]
+ [true false :inf] [5 0]
+ [true false r] [6 r]
+ [false false 0] [7 0]
+ [false false r] [8 r])]
+ (compare (apply set-order left) (apply set-order right))))
+
+(defn find-sightlines [center asteroids]
+ (map (partial to-sightline center)
+ (disj asteroids center)))
+
+(defn order-vaporized [s-map]
+ (let [ordered-keys (sort order-sightlines (keys s-map))
+ ordered-vals (map s-map ordered-keys)
+ sorted-set-nth (fn [n s]
+ (if (zero? n)
+ (first s)
+ (recur (dec n) (rest s))))
+ get-all-nths (fn [sets n]
+ (map (partial sorted-set-nth n) sets))]
+ (->> (map (partial get-all-nths ordered-vals) (range))
+ (take-while (partial some some?))
+ (reduce concat)
+ (remove nil?))))
+
+(defn list-by-sightline [center asteroids]
+ (let [order-asts-in-lines #(compare (manhattan-distance center %1)
+ (manhattan-distance center %2))]
+ (reduce (partial merge-with set/union)
+ (map #(hash-map %1 (sorted-set-by order-asts-in-lines %2))
+ (find-sightlines center asteroids)
+ (disj asteroids center)))))