From 79d521ffba2809ded806f96f5afe37369ab4f429 Mon Sep 17 00:00:00 2001 From: Joseph Ferano Date: Mon, 1 Dec 2025 19:16:05 +0700 Subject: [PATCH] Commit 2024.clj and 2025.clj --- 2024.clj | 290 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2025.clj | 57 +++++++++++ 2 files changed, 347 insertions(+) create mode 100644 2024.clj create mode 100644 2025.clj diff --git a/2024.clj b/2024.clj new file mode 100644 index 0000000..6872127 --- /dev/null +++ b/2024.clj @@ -0,0 +1,290 @@ +(ns aoc2024 + (:require [clojure.string :as str])) + +(comment + (clojure.core/refer-clojure) + ,) + +(defn get-input [day] (slurp (str "input-files/day" day "-input.txt"))) + +(defn remove-at [i coll] + (concat (take i coll) (drop (inc i) coll))) + +;; _____ __ +;; | __ \ /_ | +;; | | | | __ _ _ _ | | +;; | | | |/ _` | | | | | | +;; | |__| | (_| | |_| | | | +;; |_____/ \__,_|\__, | |_| +;; __/ | +;; |___/ + +(def day1-input-test +"3 4 +4 3 +2 5 +1 3 +3 9 +3 3") + +(defn day1-parse-input [input] + (->> input + str/split-lines + (map #(str/split % #"\s+")) + (map (fn [pair] (map read-string pair))) + (apply map list))) + +(defn day1-p1 [input] + (->> (day1-parse-input input) + (map sort) + (apply map (comp abs -)) + (reduce +))) + +(defn day1-p2 [input] + (let [[coll1 coll2] (day1-parse-input input) + freq-coll2 (frequencies coll2)] + (reduce (fn [acc n] (+ acc (* n (get freq-coll2 n 0)))) + 0 coll1))) + +(comment + (day1-p1 day1-input-test) ;; => 11 + (day1-p1 (get-input 1)) ;; => 2057374 + (day1-p2 day1-input-test) ;; => 31 + (day1-p2 (get-input 1)) ;; => 23177084 + ,) + +;; _____ ___ +;; | __ \ |__ \ +;; | | | | __ _ _ _ ) | +;; | | | |/ _` | | | | / / +;; | |__| | (_| | |_| | / /_ +;; |_____/ \__,_|\__, | |____| +;; __/ | +;; |___/ + +(def day2-input-test + "7 6 4 2 1 +1 2 7 8 9 +9 7 6 2 1 +1 3 2 4 5 +8 6 4 4 1 +1 3 6 7 9") + +(defn day2-parse-input [input] + (->> input + str/split-lines + (map #(str/split % #"\s+")) + (map #(map Integer/parseInt %)))) + +(defn day2-safe-p [coll] + (and (or (every? neg? coll) + (every? pos? coll)) + (every? #(<= 1 (abs %) 3) coll))) + +(defn day2-p1 [input] + (->> input + (map #(map - % (rest %))) + (filter day2-safe-p) + count)) + +(defn day2-find-safe [coll] + (loop [i 0] + (cond + (>= i (count coll)) false + (let [coll (remove-at i coll)] + (day2-safe-p (map - coll (rest coll)))) true + :else (recur (inc i))))) + +(defn day2-p2 [input] + (->> input + (filter day2-find-safe) + count)) + +(comment + (day2-parse-input day2-input-test) + (day2-safe-p '(1 2 2 4)) + (day2-find-safe [1 2 2 5 10]) + (day2-p1 (day2-parse-input day2-input-test)) ;; => 2 + (day2-p1 (day2-parse-input (get-input 2))) ;; => 591 + (day2-p2 (day2-parse-input day2-input-test)) ;; => 4 + (day2-p2 (day2-parse-input (get-input 2))) ;; => 621 + ,) + +;; _____ ____ +;; | __ \ |___ \ +;; | | | | __ _ _ _ __) | +;; | | | |/ _` | | | | |__ < +;; | |__| | (_| | |_| | ___) | +;; |_____/ \__,_|\__, | |____/ +;; __/ | +;; |___/ + +(def day3-input-test-p1 "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))") +(def day3-input-test-p2 "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))") + +(defn day3-p1 [input] + (->> input + (re-seq #"mul\(\d+,\d+\)") + (map #(re-seq #"\d+" %)) + (map #(map Integer/parseInt %)) + (map #(reduce * %)) + (reduce +))) + +(defn day3-p2 [input] + (->> input + (#(str/replace % "\n" "")) + (#(str/replace % #"don't\(\).*?(?:do\(\)|$)" "")) + (re-seq #"mul\(\d{1,3},\d{1,3}\)") + (map #(re-seq #"\d+" %)) + (map #(map Integer/parseInt %)) + (map #(reduce * %)) + (reduce +))) + +(comment + (re-seq #"mul\(\d{1,3},\d{1,3}\)" day3-input-test-p1) + (day3-p1 day3-input-test-p1) ;; => 161 + (day3-p1 (get-input 3)) ;; => 166905464 + (day3-p2 day3-input-test-p2) ;; => 48 + (day3-p2 (get-input 3)) ;; => 72948684 + ,) + + +;; _____ _ _ +;; | __ \ | || | +;; | | | | __ _ _ _ | || |_ +;; | | | |/ _` | | | | |__ _| +;; | |__| | (_| | |_| | | | +;; |_____/ \__,_|\__, | |_| +;; __/ | +;; |___/ + +(def day4-input-test + "MMMSXXMASM +MSAMXMSMSA +AMXSXMAAMM +MSAMASMSMX +XMASAMXAMM +XXAMMXXAMA +SMSMSASXSS +SAXAMASAAA +MAMMMXMMMM +MXMXAXMASX") + +(defn day4-parse-input [input] + (->> input + (str/split-lines) + (map vec) + vec)) + +(def day4-directions {:N [-1 0] :S [1 0] :W [0 -1] :E [0 1] + :NW [-1 -1] :NE [-1 1] :SW [1 -1] :SE [1 1]}) + +(defn day4-map-xmax [mat [dy dx] row col] + (for [i (range 4) ;; count of XMAS + :let [r (+ row (* i dy)) + c (+ col (* i dx))]] + (get-in mat [r c]))) + +(defn day4-map-x-max [mat row col] + (for [[dy dx] (map day4-directions [:NW :NE :SW :SE])] + (get-in mat [(+ row dy) (+ col dx)]))) + +(defn day4-p1 [mat] + (->> (for [row (range (count mat)) + col (range (count (first mat))) + :when (= (get-in mat [row col]) \X) + dir (vals day4-directions)] + (day4-map-xmax mat dir row col)) + (filter #(= % '(\X \M \A \S))) + count)) + +(defn day4-p2 [mat] + (->> (for [row (range (count mat)) + col (range (count (first mat))) + :when (= (get-in mat [row col]) \A)] + (day4-map-x-max mat row col)) + (filter #{[\M \M \S \S] [\M \S \M \S] [\S \S \M \M] [\S \M \M \S]}) + count)) + +(comment + (get-in (day4-parse-input day4-input-test) [0 3]) + + (day4-map-xmax (day4-parse-input day4-input-test) (:E day4-directions) 0 0) + (day4-map-x-max (day4-parse-input day4-input-test) 1 2) + + (day4-p1 (day4-parse-input day4-input-test)) ;; => 18 + (day4-p1 (day4-parse-input (get-input 4))) ;; => 2654 + (day4-p2 (day4-parse-input day4-input-test)) ;; => 9 + (day4-p2 (day4-parse-input (get-input 4))) ;; => 1990 + + ,) + + +;; _____ _____ +;; | __ \ | ____| +;; | | | | __ _ _ _ | |__ +;; | | | |/ _` | | | | |___ \ +;; | |__| | (_| | |_| | ___) | +;; |_____/ \__,_|\__, | |____/ +;; __/ | +;; |___/ + + +(def day5-input-test + "47|53 +97|13 +97|61 +97|47 +75|29 +61|13 +75|53 +29|13 +97|29 +53|29 +61|53 +97|53 +61|29 +47|13 +75|47 +97|75 +47|61 +75|61 +47|29 +75|13 +53|13 + +75,47,61,53,29 +97,61,53,29,13 +75,29,13 +75,97,47,61,53 +61,13,29 +97,13,75,29,47") + +(defn day5-parse-input [text] + (let [[pages rules] (str/split text #"\n\n")] + [(->> pages + str/split-lines + (map #(str/split % #"\|")) + (map #(mapv Integer/parseInt %))) + (->> rules + str/split-lines + (map #(str/split % #",")) + (map #(mapv Integer/parseInt %)))])) + +(defn ordering-rules [pages] + (->> pages + (group-by first) + (map (fn [[k vs]] [k (map second vs)])) + (into {}))) + +(defn day5-p1 [pages rules] + '()) + +(comment + (get (ordering-rules (first (day5-parse-input day5-input-test))) 47) + (second (day5-parse-input day5-input-test)) + (apply day5-p1 (day5-parse-input day5-input-test)) + + + ,) + diff --git a/2025.clj b/2025.clj new file mode 100644 index 0000000..5afa14d --- /dev/null +++ b/2025.clj @@ -0,0 +1,57 @@ +(ns aoc2025 + (:require [clojure.string :as str])) + +(defn get-input [day] (slurp (str "2025/day" day "-input.txt"))) + +(def day1-input-test + "L68 +L30 +R48 +L5 +R60 +L55 +L1 +L99 +R14 +L82") + +(defn day1-get-sequence [input] + (map (fn [line] + [(if (= "R" (str (first line))) + #'+ + #'-) + (Integer/parseInt (str/join (rest line)))]) + (str/split-lines input))) + +(defn day1-p1 [input] + (let [sequence (day1-get-sequence input)] + (loop [s sequence + curr 50 + zero-count 0] + (if (not (seq s)) + zero-count + (let [[f amount] (first s) + new-dial-pos (mod (f curr amount) 100)] + (recur (rest s) new-dial-pos (if (zero? new-dial-pos) (inc zero-count) zero-count))))))) + +(defn day1-p2 [input] + (let [sequence (day1-get-sequence input)] + (loop [s sequence + curr 50 + zero-count 0] + (if (not (seq s)) + zero-count + (let [[f amount] (first s) + new-dial-pos (mod (f curr amount) 100) + spins (if (and (neg? (f amount)) + (not (zero? curr))) + (quot (+ (- 100 curr) amount) 100) + (quot (+ curr amount) 100))] + (recur (rest s) new-dial-pos (+ zero-count spins))))))) + +(comment + (day1-p1 day1-input-test) + (day1-p1 (get-input 1)) + (day1-p2 day1-input-test) + (day1-p2 (get-input 1)) + :-)