in case anyone is looking to do AoC with Clerk, just updated the https://github.com/nextjournal/advent-of-clerk. Thanks @alex.shulgin for pointing out the issues with it!
Oh missed that, hope to catch it some other day
We'll be there all week
Thanks for this! I'll keep watching and learning from these! π€
Hopefully you can stop by today! It'll be 11:00 CST.
So should be 7pm here, I just might! π
I've just created our new private leaderboard for 2024!: 4534281-b9354839
I like it because the monsters haven't joined it yet so I'm ranked better π
set the channel topic: Happy AOC 2024! Please put answers in the pinned threads or create one if it does not exist yet. | Private leaderboard with code 4534281-b9354839 (old: 217019-4a55b8eb) | https://github.com/adventofcode-clojurians/adventofcode-clojurians
Who woke up at 4:55, thinking that it unlocked at 5, forgot DST and has to wait an hour? Me. It's me. God*mmit.
Day 2 - Solutions
(defn exactly? [xs]
(and (or (apply > xs) (apply < xs))
(loop [xs xs]
(if (and (seq xs) (seq (rest xs)))
(if (<= (abs (- (first xs) (second xs))) 3)
(recur (rest xs))
false)
true))))
(defn tolerated? [xs]
(loop [hd xs tl (list)]
(if (exactly? (into hd (rest tl))) true
(if (seq hd)
(recur (rest hd) (conj tl (first hd)))
false))))
(let [in (line-seq (java.io.BufferedReader. *in*))
xf (fn [pred]
(comp (map (fn [ln] (re-seq #"\d+" ln)))
(map (fn [ln] (map parse-long ln)))
(filter pred)
(map (constantly 1))))]
(println "Part A:" (transduce (xf exactly?) + in))
(println "Part B:" (transduce (xf tolerated?) + in)))
Not very interesting just kept two lists that I piece together to drop elements for testinghttps://github.com/jramosg/advent-of-code/blob/master/src/advent_of_code/year_2024/day02.clj
https://github.com/benjamin-asdf/advent-of-code/blob/master/src/Y2024/day2.clj thrashed with this one, but got the right answers
https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2024/day02.clj
here's mine - elegantly bruteforced: https://github.com/vollcheck/aoc/blob/master/src/y24/day02.clj
Also brute forced day 2 part 2
(ns stuartstein777.2024.day2
(:require [clojure.string :as str]
[stuartstein777.utils :as utils]))
(defn parse [line]
(->> line
(slurp)
(str/split-lines)
(mapv (fn [l] (->> (str/split l #" ")
(mapv (fn [x] (Integer/parseInt x))))))))
(defn is-safe? [record]
;; check if each is either ascending or descending and the gap between each item is between 1 and 3
(and (or (apply > record) (apply < record))
(->> (map #(Math/abs (- %1 %2)) record (rest record))
(every? (fn [x] (<= 1 x 3))))))
(defn part-one [record]
(is-safe? record))
(defn part-two [record]
;; generate each permutation. e.g. [1 2 3 4 5], [2 3 4 5] [1 3 4 5] [1 2 4 5] ... Then check
;; if any of the permutations is safe.
(let [permutations (map (partial utils/remove-value-at record) (range (count record)))]
(->> permutations
(map is-safe?)
(filter true?)
(count)
(not= 0))))
(->> "puzzle-inputs/2024/day2"
(parse)
(mapv part-one)
(filter true?)
(count)) ;; 463
(->> "puzzle-inputs/2024/day2"
(parse)
(mapv part-two)
(filter true?)
(count)) ;; 514
;; utils
(defn remove-value-at [xs n]
(into (subvec xs 0 n) (subvec xs (inc n))))https://github.com/jungwookim/aoc-exercise/blob/master/src/aoc/2024/day2.clj
I spent a time to solve a part 2. I wanted to find a elegant way but I just used a keep-indexed
https://github.com/ghaskins/adventofcode/blob/main/src/aoc/2024/day2.clj
https://github.com/tschady/advent-of-code/blob/main/src/aoc/2024/d02.clj
Great problems. I'm still somewhat new to clojure so part 2 felt weird. My first reaction was to grab a for loop and variables but I ended up with the brute force solution (which seems popular).
(def reports
(let [input (aoc.io/load-input 2)]
(for [line (clojure.string/split-lines input)]
(->> line
(re-seq #"\d+")
(map parse-long)
(vec)))))
;; ### Part 1
(defn mapply
[f coll]
(map #(apply f %) coll))
(defn safe-report?
[report]
(let [diffs (mapply - (partition 2 1 report))
diff-set (set diffs)]
(or (clojure.set/subset? diff-set #{1 2 3})
(clojure.set/subset? diff-set #{-1 -2 -3}))))
(tests
(safe-report? [7 6 4 2 1]) := true
(safe-report? [1 2 7 8 9]) := false
(safe-report? [9 8 6 2 1]) := false
(safe-report? [8 6 4 4 1]) := false
(safe-report? [1 3 6 7 9]) := true)
(defn D2P1 [reports]
(count (filter safe-report? reports)))
;; ### Part 2
(defn dampener-reports
[report]
(for [i (range (count report))]
(safe-report?
(concat (subvec report 0 i) (subvec report (inc i))))))
(defn safe-report2?
[report]
(some true? (dampener-reports report)))
(tests
(safe-report2? [7 6 4 2 1]) := true
(safe-report2? [1 2 7 8 9]) := nil
(safe-report2? [9 8 6 2 1]) := nil
(safe-report2? [8 6 4 4 1]) := true
(safe-report2? [1 3 6 7 9]) := true)
(defn D2P2 [reports]
(count (filter safe-report2? reports)))
Also, I saw @carnunmp was using rcf on the last problem so I decided to give it a go... it's great πgot to use lazy-seq! https://github.com/FelipeCortez/advent-of-code/blob/master/2024/02.clj
(ns day2
(:require
[ :as io]
[clojure.string :as str]
[clojure.test :refer [set-test is]]))
(defn safe-delta [l1 l2]
(let [delta (abs (- l1 l2))]
(and (<= 1 delta)
(<= delta 3))))
(defn all-increasing? [levels]
(every? (fn [[n m]] (and (< n m) (safe-delta n m))) (partition 2 1 levels)))
(defn all-decreasing? [levels]
(every? (fn [[n m]] (and (> n m) (safe-delta n m))) (partition 2 1 levels)))
(defn safe? [levels]
(or (all-increasing? levels)
(all-decreasing? levels)))
(set-test
safe?
(is (safe? [7 6 4 2 1]))
(is (not (safe? [1 2 7 8 9])))
(is (not (safe? [9 7 6 2 1])))
(is (not (safe? [1 3 2 4 5])))
(is (not (safe? [8 6 4 4 1])))
(is (safe? [1 3 6 7 9])))
(def input
(->> "input/2"
io/resource
slurp
str/split-lines
(mapv #(mapv parse-long (str/split % #"\s+")))))
(count (filter safe? input))
;; => 334
(defn butnth
[xs n]
(concat (subvec xs 0 n) (subvec xs (inc n) (count xs))))
(defn droppings
[xs]
(for [n (range (count xs))]
(butnth xs n)))
(droppings '[a b c d])
;; => ((b c d) (a c d) (a b d) (a b c))
(defn safeish?
[levels]
(some safe? (droppings levels)))
(set-test
safeish?
(is (safeish? [7 6 4 2 1]))
(is (not (safeish? [1 2 7 8 9])))
(is (not (safeish? [9 7 6 2 1])))
(is (safeish? [1 3 2 4 5]))
(is (safeish? [8 6 4 4 1]))
(is (safeish? [1 3 6 7 9])))
(count (filter safeish? input))
;; => 400
TIL set-test (and not the only one)
(ns aoc.2024.day02
(:require
[clojure.edn :as edn]
[clojure.string :as str]))
(def test-input "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")
(def input (slurp "src/aoc/2024/day02"))
(defn parse-input [input]
(into []
(comp
(map #(str "[" % "]"))
(map edn/read-string))
(str/split-lines input)))
(defn monotone? [l]
(or (apply < l)
(apply > l)))
(defn safe-diff? [l]
(every? #(< 0 (abs (- (first %) (second %))) 4)
(partition 2 1 l)))
(defn safe1 [l]
(and (monotone? l)
(safe-diff? l)))
(defn safe2 [l]
(->> (range (count l))
(mapv #(concat (take % l)
(drop (inc %) l)))
(some #(and (monotone? %)
(safe-diff? %)))))
;; part 1
(->> (parse-input input)
(filter safe1)
count)
; part 2
(->> (parse-input input)
(filter #(or (safe1 %) (safe2 %)))
count)
I felt not smart todayI was way overthinking part 2 for a while π got there in the end (also by brute force) https://github.com/lawreka/aoc24/blob/master/src/aoc24/2.clj
Only had time for a non cleaned up run at Part 1 (I think my safe? fn could be simplified) before real work got in the way. Got busy (in a great way) right as AOC started this year but I might try and catch up on the weekend
https://github.com/chase-lambert/aoc-clojure/blob/main/src/aoc/2024/day_02.clj
FWIW, mine is also brute-force style. I donβt apologize for that, and I donβt think anyone else should, either. The problem data set simply doesnβt warrant the engineering effort, so the fastest path to implementation wins, in my opinion.
Enjoyed this one! https://github.com/CarnunMP/Advent-of-Code/blob/master/src/y2024/d2.clj
> Also, I saw @carnunmp was using rcf on the last problem so I decided to give it a go... it's great π > β @dingelsz3 Yes! Really fun little library. Love that it's just one notch above the Rich Comment forms I'm already writing.
> (apply < xs)
> ...
> (apply < l)
dammit, why'd I partition into pairs... xD
I completely missed the point on this comment earlierβ¦I had used #(apply < %) on pairs and so I thought that is what people were talking about. I never realized this worked
(< 1 2 3 4)
=> true
(< 1 2 3 2)
=> falsecool
These AOC puzzles were built for clojure, heh.
https://github.com/RyanFleck/aoc24/blob/master/src/aoc24/day2.clj Gosh, I learned a ton looking through the other solutions after hitting the answer with brute force. If I had time next up would be finishing my attempt at providing the indice that made one of the checks fail and just re-running that.
No kidding.
Love the swag with the 2 'every?' calls by @tws
https://github.com/Lambdaphile/aoc/blob/main/2024/clojure/src/aoc/days/02/core.clj
Looks like my solution for the dampening wasnt the most effective, but job gets done In (explode) i realize the seq as vecs to produce all output options, there may have been a lazier approach with (butlast) and/or (take) calls think_beret
(defn parse-input [input]
(for [line (str/split-lines input)]
(map parse-long (str/split line #"\s"))))
(def day2-input (-> "resources/aoc2024/day2.txt"
slurp
parse-input))
(defn difference [x y]
(abs (- x y)))
(defn safe? [floor]
(let [differences (map difference (rest floor) floor)]
(and (or (apply > floor) (apply < floor))
(every? #(<= 0 % 3) differences))))
(defn task1 []
(count (filter true? (map safe? day2-input))))
(defn explode [coll]
(let [input (into [] coll)]
(for [i (range (count input))]
(concat (subvec input 0 i) (subvec input (inc i))))))
(defn extra-safe?
([floor]
(or (safe? floor)
(some safe? (explode floor)))))
(defn task2 []
(count (filter true? (map extra-safe? day2-input))))https://github.com/bhauman/adv2024/blob/main/src/adv2024/day02/sol.clj
YAMLScript: https://github.com/ingydotnet/advent-of-code/blob/main/2024/02/part1.ys
@mail191 @max.r.rothman I did the same, but using a lazy-seq. was surprised by how similar our solutions are
(require '[clojure.string :as str])
(defn valid-report? [xs]
(and (or (apply < xs) (apply > xs))
(every? (fn [[x y]] (<= 1 (abs (- x y)) 3))
(partition 2 1 xs))))
(defn dampen-problems
([xs]
(cons xs (dampen-problems [] xs)))
([before [head & tail]]
(if (seq tail)
(lazy-seq (cons (into before tail)
(dampen-problems (conj before head) tail)))
[before])))
(let [reports
(->> (slurp "2024/02.in")
(str/split-lines)
(map (fn [line] (map parse-long (re-seq #"\d+" line)))))]
[(count (filter valid-report? reports))
(count (filter #(some valid-report? (dampen-problems %)) reports))])https://gitlab.com/maximoburrito/advent2024/-/blob/main/src/day02/main.clj?ref_type=heads
https://gist.github.com/RokLenarcic/6e51bff2f201f553d1f3ba29fab8c4ed
I got slowed down a bit by the lack of dissoc at index for vector
This condition in unnecessary because if it is safe then itβs also safe when dropping the first item, so the second condition is sufficient https://gitlab.com/maximoburrito/advent2024/-/blob/main/src/day02/main.clj?ref_type=heads#L32
Grossly inefficient. I first tried to do it with a reduce and a flip-flop state, but the removal of the head tripped me up. Ended up with this monstrosity:
(defn safe? [report]
(and (or (apply > report)
(apply < report))
(every? #(< 0 (abs (apply - %)) 4) (partition 2 1 report))))
(defn safe?2 [report]
(some safe?
(for [i (range 0 (count report))]
(into (subvec report 0 i) (subvec report (inc i))))))
(defn part1 [path]
(u/count-if safe? (u/read-file-list path u/nums)))
(defn part2 [path]
(u/count-if safe?2 (u/read-file-list path u/nums)))
https://github.com/Maravedis/advent_code/blob/master/src/advent_of_code/2024/02.cljI liked today's puzzle - nice and clean, and I'm getting to use my utility functions from a previous year multiple times so far! β’ Blog: https://github.com/abyala/advent-2024-clojure/blob/main/docs/day02.md β’ Source; https://github.com/abyala/advent-2024-clojure/blob/main/src/advent_2024_clojure/day02.clj
Was I the only one who used a zipper-like approach for getting the without-one-item permutations?
(defn without-any-1 [l]
(loop [[cur & rst] l, before [], accum '()]
(if cur
(recur rst (conj before cur) (conj accum (concat before rst)))
accum)))
I think this is similar? I popped elements from the report and added it to another list then put them back together again to test
(defn tolerated? [xs]
(loop [hd xs tl (list)]
(if (exactly? (into hd (rest tl))) true
(if (seq hd)
(recur (rest hd) (conj tl (first hd)))
false))))