| 1 | (ns adventofcode2019.day10 |
| 2 | [:require [adventofcode2019.lib :refer :all] |
| 3 | [clojure.core.match :refer [match]] |
| 4 | [clojure.set :as set]]) |
| 5 | |
| 6 | (defn to-sightline [[a-x a-y] [b-x b-y]] |
| 7 | (let [dy (- a-y b-y) |
| 8 | dx (- a-x b-x) |
| 9 | slope (if (zero? dx) :inf (rationalize (/ dy dx)))] |
| 10 | [(neg? dy) (neg? dx) slope])) |
| 11 | |
| 12 | (defn order-sightlines [left right] |
| 13 | (let [set-order #(match [%1 %2 %3] |
| 14 | [false false :inf] [1 0] |
| 15 | [false true r] [2 r] |
| 16 | [false true 0] [3 0] |
| 17 | [true true r] [4 r] |
| 18 | [true false :inf] [5 0] |
| 19 | [true false r] [6 r] |
| 20 | [false false 0] [7 0] |
| 21 | [false false r] [8 r])] |
| 22 | (compare (apply set-order left) (apply set-order right)))) |
| 23 | |
| 24 | (defn find-sightlines [center asteroids] |
| 25 | (map (partial to-sightline center) |
| 26 | (disj asteroids center))) |
| 27 | |
| 28 | (defn order-vaporized [s-map] |
| 29 | (let [ordered-keys (sort order-sightlines (keys s-map)) |
| 30 | ordered-vals (map s-map ordered-keys) |
| 31 | sorted-set-nth (fn [n s] |
| 32 | (if (zero? n) |
| 33 | (first s) |
| 34 | (recur (dec n) (rest s)))) |
| 35 | get-all-nths (fn [sets n] |
| 36 | (map (partial sorted-set-nth n) sets))] |
| 37 | (->> (map (partial get-all-nths ordered-vals) (range)) |
| 38 | (take-while (partial some some?)) |
| 39 | (reduce concat) |
| 40 | (remove nil?)))) |
| 41 | |
| 42 | (defn list-by-sightline [center asteroids] |
| 43 | (let [order-asts-in-lines #(compare (manhattan-distance center %1) |
| 44 | (manhattan-distance center %2))] |
| 45 | (reduce (partial merge-with set/union) |
| 46 | (map #(hash-map %1 (sorted-set-by order-asts-in-lines %2)) |
| 47 | (find-sightlines center asteroids) |
| 48 | (disj asteroids center))))) |
| 49 | |
| 50 | (defn day10 [] |
| 51 | (let [input (get-list-from-file (input-file)) |
| 52 | to-points (fn [j l] |
| 53 | (map-indexed (fn [i m] |
| 54 | (if (= \# m) [i j] nil)) l)) |
| 55 | asteroids (->> input |
| 56 | (map-indexed to-points) |
| 57 | (reduce concat) |
| 58 | (filter some?) |
| 59 | (into (sorted-set))) |
| 60 | [mv-ast mv-count] (reduce (partial max-key second) |
| 61 | (map #(vector % (count (set (find-sightlines % asteroids)))) |
| 62 | asteroids)) |
| 63 | [x200 y200] (nth (order-vaporized (list-by-sightline mv-ast asteroids)) 199)] |
| 64 | (part1 mv-count) |
| 65 | (part2 (+ (* 100 x200) y200)))) |