diff --git a/day17/part1.clj b/day17/part1.clj new file mode 100644 index 0000000..220e408 --- /dev/null +++ b/day17/part1.clj @@ -0,0 +1,34 @@ +(def target-area [[169 -8] [206 -108]]) +;(def target-area [[20 -5] [30 -10]]) +(def initial-pos [0 0]) + +(defn beyond-target? [[[tbx tby] [tex tey]] [x y]] + (or (> x tex) (< y tey))) + +(defn within-target? [[[tbx tby] [tex tey]] [x y]] + (and (>= x tbx) (<= x tex) (<= y tby) (>= y tey))) + +(defn apply-velocity [[pos vel]] + [[(+ (first pos) (first vel)) (+ (second pos) (second vel))] + [(cond-> (first vel) (> (first vel) 0) dec (< (first vel) 0) inc) (dec (second vel))]]) + +(defn path-builder [vel] (iterate apply-velocity [initial-pos vel])) + +(defn build-path [target vel] + (map first + (take-while (comp not (partial beyond-target? target) first) + (path-builder vel)))) + +(defn path-height [target vel] + (let [path (build-path target vel)] + (when (within-target? target (last path)) + (apply max (map second path))))) + +(def tnum-seq (iterate #(do [(+ (first %) (second %)) (inc (second %))]) [0 1])) + +(let [x (second (last (take-while #(< (first %) (first (first target-area))) tnum-seq)))] + (println + (apply max + (filter some? + (for [y (range -2000 2000)] (path-height target-area [x y])))))) + diff --git a/day17/part2.clj b/day17/part2.clj new file mode 100644 index 0000000..234818f --- /dev/null +++ b/day17/part2.clj @@ -0,0 +1,44 @@ +(def target-area [[169 -68] [206 -108]]) +;(def target-area [[20 -5] [30 -10]]) +(def initial-pos [0 0]) + +(defn beyond-target? [[[tbx tby] [tex tey]] [x y]] + (or (> x tex) (< y tey))) + +(defn within-target? [[[tbx tby] [tex tey]] [x y]] + (and (>= x tbx) (<= x tex) (<= y tby) (>= y tey))) + +(defn apply-velocity [[[px py] [vx vy]]] + [[(+ px vx) (+ py vy)] [(if (pos? vx) (dec vx) 0) (dec vy)]]) + +(defn path-builder [vel] (iterate apply-velocity [initial-pos vel])) + +(defn build-path [target vel] + (->> (path-builder vel) + (take-while (comp not (partial beyond-target? target) first)) + (map first))) + +(defn path-height [target vel] + (let [path (build-path target vel)] + (when (within-target? target (last path)) + (apply max (map second path))))) + +; Used to determine best x velocity for highest path +(def tnum-seq (iterate #(do [(apply + %) (inc (second %))]) [0 1])) + +(let [[tb te] target-area + lowest-x (second (last (take-while #(< (first %) (first tb)) tnum-seq))) + lowest-y (second te) + valid-paths (filter (comp some? first) + (for [y (range lowest-y 2000)] + [(path-height target-area [lowest-x y]) y])) + highest-path (reduce #(if (> (first %1) (first %2)) %1 %2) valid-paths)] + (println (first highest-path)) + (println + (count + (filter (partial within-target? target-area) + (let [ys [(second te) (second highest-path)]] + (for [x (range lowest-x (inc (first te))) + y (range (apply min ys) (inc (apply max ys)))] + (last (build-path target-area [x y])))))))) +