Commit 2024.clj and 2025.clj

This commit is contained in:
Joseph Ferano 2025-12-01 19:16:05 +07:00
commit 79d521ffba
2 changed files with 347 additions and 0 deletions

290
2024.clj Normal file
View File

@ -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))
,)

57
2025.clj Normal file
View File

@ -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))
:-)