|
| 1 | +(ns clj-adventofcode-2019.day11 |
| 2 | + (:require |
| 3 | + [clojure.java.io :as io] |
| 4 | + [clojure.math.numeric-tower :as math] |
| 5 | + [clojure.string :as str])) |
| 6 | + |
| 7 | + |
| 8 | +(defn parse-line [index line] |
| 9 | + [index { :pos |
| 10 | + (into {} |
| 11 | + (map (fn [[k v]] [(keyword k) (read-string v)]) |
| 12 | + (map |
| 13 | + (fn [v] (str/split v #"=")) |
| 14 | + (str/split (str/replace (str/replace line "<" "") ">" "") #", ")))) |
| 15 | + :vel {:x 0 :y 0 :z 0} |
| 16 | + }]) |
| 17 | + |
| 18 | +(def puzzle-input (slurp (io/resource "day12_input.txt"))) |
| 19 | + |
| 20 | +(def initial-input |
| 21 | + (into {} |
| 22 | + (map-indexed parse-line (str/split-lines puzzle-input)))) |
| 23 | + |
| 24 | + |
| 25 | +; initial-input |
| 26 | +; <x=-1, y=0, z=2> |
| 27 | +; <x=2, y=-10, z=-7> |
| 28 | +; <x=4, y=-8, z=8> |
| 29 | +; <x=3, y=5, z=-1> |
| 30 | +(def sample-moon-positions-1 |
| 31 | + {0 {:pos {:x -1 :y 0 :z 2} |
| 32 | + :vel {:x 0 :y 0 :z 0}} |
| 33 | + 1 {:pos {:x 2 :y -10 :z -7} |
| 34 | + :vel {:x 0 :y 0 :z 0}} |
| 35 | + 2 {:pos {:x 4 :y -8 :z 8} |
| 36 | + :vel {:x 0 :y 0 :z 0}} |
| 37 | + 3 {:pos {:x 3 :y 5 :z -1} |
| 38 | + :vel {:x 0 :y 0 :z 0}}}) |
| 39 | + |
| 40 | +(defn adjust-all-axis [a b] |
| 41 | + (into {} (for [axis [:x :y :z]] |
| 42 | + [axis (+ (get a axis) (get b axis))]) |
| 43 | + )) |
| 44 | + |
| 45 | +(comment |
| 46 | + (adjust-all-axis {:x 0 :y 0 :z 10} {:x 5 :y -2 :z 0}) |
| 47 | + ;; => {:x 5, :y -2, :z 10} |
| 48 | + ) |
| 49 | + |
| 50 | +(defn calc-vel [moon-index moons-data] |
| 51 | + (let [other-moons-data (filter (fn [[i _]] (not= i moon-index)) moons-data) |
| 52 | + other-moons-positions (map (fn [[_ data]] (:pos data)) other-moons-data) |
| 53 | + current-moon-pos (:pos (get moons-data moon-index)) |
| 54 | + current-velocity (:vel (get moons-data moon-index)) |
| 55 | + velocity-changes-grouped (group-by first (for [axis [:x :y :z] |
| 56 | + other-moon-pos other-moons-positions] |
| 57 | + (let [o (get other-moon-pos axis) |
| 58 | + c (get current-moon-pos axis)] |
| 59 | + (cond |
| 60 | + (= o c) [axis 0] |
| 61 | + (> o c) [axis 1] |
| 62 | + (< o c) [axis -1])))) |
| 63 | + |
| 64 | + velocity-changes-summed |
| 65 | + (into {} |
| 66 | + (map |
| 67 | + (fn [[axis v]] [axis (reduce + (map second v))]) |
| 68 | + velocity-changes-grouped)) |
| 69 | + new-velocity (adjust-all-axis current-velocity velocity-changes-summed) |
| 70 | + ] |
| 71 | + new-velocity)) |
| 72 | + |
| 73 | +(comment |
| 74 | + (calc-vel 3 sample-moon-positions-1) |
| 75 | + ) |
| 76 | + |
| 77 | +(defn step [moons-data] |
| 78 | + (into {} |
| 79 | + (let [indexes (keys moons-data)] |
| 80 | + (for [index indexes] |
| 81 | + (let [new-velocity (calc-vel index moons-data) |
| 82 | + new-position (adjust-all-axis (:pos (get moons-data index)) new-velocity)] |
| 83 | + [index {:pos new-position :vel new-velocity}]))))) |
| 84 | + |
| 85 | +(comment |
| 86 | + (step sample-moon-positions-1) |
| 87 | + ;; => {0 {:pos {:x 2, :y -1, :z 1}, :vel {:x 3, :y -1, :z -1}}, |
| 88 | + ;; 1 {:pos {:x 3, :y -7, :z -4}, :vel {:x 1, :y 3, :z 3}}, |
| 89 | + ;; 2 {:pos {:x 1, :y -7, :z 5}, :vel {:x -3, :y 1, :z -3}}, |
| 90 | + ;; 3 {:pos {:x 2, :y 2, :z 0}, :vel {:x -1, :y -3, :z 1}}} |
| 91 | + |
| 92 | + (last (take 11 (iterate step sample-moon-positions-1))) |
| 93 | + ;; => {0 {:pos {:x 2, :y 1, :z -3}, :vel {:x -3, :y -2, :z 1}}, |
| 94 | + ;; 1 {:pos {:x 1, :y -8, :z 0}, :vel {:x -1, :y 1, :z 3}}, |
| 95 | + ;; 2 {:pos {:x 3, :y -6, :z 1}, :vel {:x 3, :y 2, :z -3}}, |
| 96 | + ;; 3 {:pos {:x 2, :y 0, :z 4}, :vel {:x 1, :y -1, :z -1}}} |
| 97 | + ) |
| 98 | + |
| 99 | + |
| 100 | +(defn energy [pos] |
| 101 | + (reduce + (map (fn [[_ v]] (math/abs v)) pos))) |
| 102 | + |
| 103 | + |
| 104 | +(defn total-energy [moon-data] |
| 105 | + (* (energy (:pos moon-data)) |
| 106 | + (energy (:vel moon-data)))) |
| 107 | + |
| 108 | + |
| 109 | +(comment |
| 110 | + (energy {:x 5 :y 1 :z -5}) |
| 111 | + ;; => 1 |
| 112 | + |
| 113 | + (total-energy |
| 114 | + (get |
| 115 | + (last |
| 116 | + (take 11 (iterate step sample-moon-positions-1))) 0)) |
| 117 | + ;; => 36 |
| 118 | + (map (fn [[_ moon-data]] (total-energy moon-data)) |
| 119 | + (last (take 11 (iterate step sample-moon-positions-1)))) |
| 120 | + ;; => (36 45 80 18) |
| 121 | + (reduce + |
| 122 | + (map (fn [[_ moon-data]] (total-energy moon-data)) |
| 123 | + (last (take 11 (iterate step sample-moon-positions-1))))) |
| 124 | + ;; => 179 |
| 125 | +) |
| 126 | + |
| 127 | +(step initial-input) |
| 128 | +;; => Execution error (NullPointerException) at clj-adventofcode-2019.day11/adjust-all-axis$iter$fn$fn (form-init7063701141190084591.clj:40). |
| 129 | +;; null |
| 130 | + |
| 131 | +;; => {0 {:x 3, :y 3, :z 0}, 1 {:x 4, :y -16, :z 2}, 2 {:x -10, :y -6, :z 5}, 3 {:x -3, :y 0, :z -13}} |
| 132 | + |
| 133 | + |
| 134 | +; part1 solution |
| 135 | +(reduce + |
| 136 | + (map (fn [[_ moon-data]] (total-energy moon-data)) |
| 137 | + (last (take 1001 (iterate step initial-input))))) |
| 138 | +;; => 12351 |
| 139 | + |
| 140 | +(defn does-history-really-repeat-itself [initial] |
| 141 | + (loop [tries 0 |
| 142 | + input initial |
| 143 | + ] |
| 144 | + (if (and (> tries 0) (= input initial)) {:tries tries :input input} |
| 145 | + (recur (inc tries) (step input))) |
| 146 | + )) |
| 147 | +;; => #'clj-adventofcode-2019.day11/does-history-really-repeat-itself |
| 148 | + |
| 149 | +;; => #'clj-adventofcode-2019.day11/Does-history-really-repeat-itself |
| 150 | + |
| 151 | +(does-history-really-repeat-itself sample-moon-positions-1) |
| 152 | +;; => {:tries 2772, |
| 153 | +;; :input |
| 154 | +;; {0 {:pos {:x -1, :y 0, :z 2}, :vel {:x 0, :y 0, :z 0}}, |
| 155 | +;; 1 {:pos {:x 2, :y -10, :z -7}, :vel {:x 0, :y 0, :z 0}}, |
| 156 | +;; 2 {:pos {:x 4, :y -8, :z 8}, :vel {:x 0, :y 0, :z 0}}, |
| 157 | +;; 3 {:pos {:x 3, :y 5, :z -1}, :vel {:x 0, :y 0, :z 0}}}} |
| 158 | + |
| 159 | + |
| 160 | +;;(does-history-really-repeat-itself initial-input) |
| 161 | + |
| 162 | +(defn get-axis [state axis] |
| 163 | + (map (fn [[i v]] [i {:pos (get (:pos v) axis) |
| 164 | + :vel (get (:vel v) axis)}]) state) |
| 165 | + ) |
| 166 | +(get-axis initial-input :x) |
| 167 | + |
| 168 | +(defn does-history-really-repeat-itself-axis [initial axis] |
| 169 | + (loop [tries 0 |
| 170 | + input initial] |
| 171 | + (if (and (> tries 0) |
| 172 | + (= (get-axis input axis) (get-axis initial axis))) |
| 173 | + {:tries tries :input input} |
| 174 | + (recur (inc tries) (step input))))) |
| 175 | + |
| 176 | + |
| 177 | +(does-history-really-repeat-itself-axis initial-input :x) |
| 178 | +;; => {:tries 22958, |
| 179 | +;; :input |
| 180 | +;; {0 {:pos {:x 3, :y 36, :z 582}, :vel {:x 0, :y 18, :z 6}}, |
| 181 | +;; 1 {:pos {:x 4, :y -247, :z -85}, :vel {:x 0, :y -10, :z -1}}, |
| 182 | +;; 2 {:pos {:x -10, :y 557, :z -300}, :vel {:x 0, :y -19, :z -2}}, |
| 183 | +;; 3 {:pos {:x -3, :y -365, :z -203}, :vel {:x 0, :y 11, :z -3}}}} |
| 184 | + |
| 185 | +(does-history-really-repeat-itself-axis initial-input :y) |
| 186 | +;; => {:tries 286332, |
| 187 | +;; :input |
| 188 | +;; {0 {:pos {:x 4, :y 3, :z 137}, :vel {:x 9, :y 0, :z -3}}, |
| 189 | +;; 1 {:pos {:x -2, :y -16, :z 156}, :vel {:x -4, :y 0, :z -59}}, |
| 190 | +;; 2 {:pos {:x -18, :y -6, :z -308}, :vel {:x -15, :y 0, :z 37}}, |
| 191 | +;; 3 {:pos {:x 10, :y 0, :z 9}, :vel {:x 10, :y 0, :z 25}}}} |
| 192 | + |
| 193 | +(does-history-really-repeat-itself-axis initial-input :z) |
| 194 | +;; => {:tries 231614, |
| 195 | +;; :input |
| 196 | +;; {0 {:pos {:x -85, :y 477, :z 0}, :vel {:x 12, :y 1, :z 0}}, |
| 197 | +;; 1 {:pos {:x -10, :y -659, :z 2}, :vel {:x -5, :y 33, :z 0}}, |
| 198 | +;; 2 {:pos {:x -5, :y 220, :z 5}, :vel {:x 8, :y -26, :z 0}}, |
| 199 | +;; 3 {:pos {:x 94, :y -57, :z -13}, :vel {:x -15, :y -8, :z 0}}}} |
| 200 | + |
| 201 | +(defn gcd |
| 202 | + [a b] |
| 203 | + (if (zero? b) |
| 204 | + a |
| 205 | + (recur b, (mod a b)))) |
| 206 | + |
| 207 | + |
| 208 | +(defn lcm |
| 209 | + [a b] |
| 210 | + (/ (* a b) (gcd a b))) |
| 211 | + |
| 212 | +(defn lcmv [& v] (reduce lcm v)) |
| 213 | + |
| 214 | +; part2 solution |
| 215 | +(lcmv 231614 286332 22958) |
| 216 | +;; => 380635029877596 |
0 commit comments