(ns adventofcode2019.day10 [:require [adventofcode2019.lib :refer :all] [clojure.core.match :refer [match]] [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))))) (defn day10 [] (let [input (get-list-from-file (input-file)) to-points (fn [j l] (map-indexed (fn [i m] (if (= \# m) [i j] nil)) l)) asteroids (->> input (map-indexed to-points) (reduce concat) (filter some?) (into (sorted-set))) [mv-ast mv-count] (reduce (partial max-key second) (map #(vector % (count (set (find-sightlines % asteroids)))) asteroids)) [x200 y200] (nth (order-vaporized (list-by-sightline mv-ast asteroids)) 199)] (part1 mv-count) (part2 (+ (* 100 x200) y200))))