diff --git a/2024/src/day13.clj b/2024/src/day13.clj new file mode 100644 index 0000000..f4eb7f6 --- /dev/null +++ b/2024/src/day13.clj @@ -0,0 +1,61 @@ +(ns day13 + (:require + [core :as c] + [input-manager :refer [get-input-raw]])) + +(def input + (->> (get-input-raw 13) + c/split-on-double-newlines + (map #(c/get-match-groups #"(\d+)" %)) + (c/mmap first) + (c/mmap parse-long) + (map #(map vector [:ax :ay :bx :by :px :py] %)) + (map #(into {} %)) + ; + )) + +(defn push [m k vs] + (if (empty? vs) + m + (update m k #(if (nil? %1) + (set vs) + (into %1 %2)) + vs))) + +(defn get-cost [{:keys [ax ay bx by px py]}] + (loop [costs (sorted-map 0 #{[0 0]}) + i 0] + (let [[cost locs] (first costs) + costs' (dissoc costs cost)] + (if (or (nil? cost) + (> i 1000) + (some (fn [[x y]] + (and (= x px) + (= y py))) + locs)) + costs + (recur (-> costs' + (push (+ cost 3) + (->> locs + (map #(-> % + (update 0 + ax) + (update 1 + ay))) + (filter (fn [[x y]] + (and (<= x px) + (<= y py)))))) + (push (+ cost 1) + (->> locs + (map #(-> % + (update 0 + bx) + (update 1 + by))) + (filter (fn [[x y]] + (and (<= x px) + (<= y py))))))) + (inc i)))))) + +;; part 1 +(->> input + (map get-cost) + (filter identity) + (reduce +)) + diff --git a/2024/src/day15.clj b/2024/src/day15.clj new file mode 100644 index 0000000..248ac4a --- /dev/null +++ b/2024/src/day15.clj @@ -0,0 +1,65 @@ +(ns day15 + (:require + [core :as c] + [input-manager :refer [get-input-raw]] + [clojure.string :as str])) + +;; parse input +(let [[a b] (c/split-on-double-newlines + (get-input-raw 15)) + raw-grid (->> (str/split-lines a) + c/map-by-coords)] + (def instructions (->> (filter #(not= % \newline) b) + (map c/arrow-char->dir))) + (def start (->> (filter #(= (second %) \@) raw-grid) + ffirst)) + (def grid (assoc raw-grid start \.)) + + (def grid-2 (->> (str/replace a "O" ".") + str/split-lines + (mapv #(apply str (interleave % %))) + c/map-by-coords)) + + (def boulders-2 (->> (filter #(= (second %) \O) raw-grid) + (map first) + (map #(update % 0 * 2)) + set)) + + (def walls-2 (->> (filter #(= (second %) \#) grid-2) + (map first) + set))) + +(def step-fns {:up [0 dec] + :down [0 inc] + :right [1 inc] + :left [1 dec]}) +(defn step [loc dir] + (apply update loc (step-fns dir))) + +;; part 1 +(->> instructions + (reduce (fn [{:keys [grid loc] :as acc} + dir] + (let [check (step loc dir) + gap (loop [p check] + (condp = (grid p) + nil nil + \# nil + \O (recur (step p dir)) + \. p))] ; hey look, some space! + (cond + (nil? gap) acc + + (= gap check) (assoc acc :loc check) + + :else {:loc check + :grid (-> grid + (assoc check \.) + (assoc gap \O))}))) + {:grid grid, :loc start}) + :grid + (filter #(= (second %) \O)) + (map first) + (map #(+ (second %) + (* 100 (first %)))) + (reduce +))