adventofcode

mkvlr 2024-12-02T11:25:59.549579Z

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!

πŸŽ‰ 9
2024-12-02T17:05:38.737239Z

Going live now! https://www.twitch.tv/timpote

πŸš€ 2
2024-12-02T20:42:02.919189Z

Oh missed that, hope to catch it some other day

2024-12-02T20:50:06.148039Z

We'll be there all week

Katja 2024-12-03T12:32:56.765519Z

Thanks for this! I'll keep watching and learning from these! πŸ€—

2024-12-03T12:40:10.182129Z

Hopefully you can stop by today! It'll be 11:00 CST.

πŸ‘ 1
Katja 2024-12-03T12:51:19.524329Z

So should be 7pm here, I just might! πŸ™‚

1
genmeblog 2024-12-02T20:53:05.333419Z

I've just created our new private leaderboard for 2024!: 4534281-b9354839

πŸ™Œ 2
Maravedis 2024-12-03T04:21:02.708569Z

I like it because the monsters haven't joined it yet so I'm ranked better πŸ˜›

πŸ™‚ 1
genmeblog 2024-12-02T20:57:12.447799Z

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

πŸ‘ 1
❀️ 5
Maravedis 2024-12-02T04:08:10.283089Z

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.

πŸ˜„ 4
2024-12-02T05:15:17.984089Z

Day 2 - Solutions

Sam Ferrell 2024-12-02T08:41:42.573519Z

(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 testing

Benjamin 2024-12-02T11:00:27.280599Z

https://github.com/benjamin-asdf/advent-of-code/blob/master/src/Y2024/day2.clj thrashed with this one, but got the right answers

vollcheck 2024-12-02T12:07:05.072219Z

here's mine - elegantly bruteforced: https://github.com/vollcheck/aoc/blob/master/src/y24/day02.clj

2024-12-02T13:41:19.857339Z

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

Jungwoo Kim 2024-12-02T14:24:23.112369Z

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

πŸ‘ 1
tschady 2024-12-02T15:46:23.933379Z

https://github.com/tschady/advent-of-code/blob/main/src/aoc/2024/d02.clj

☝️ 1
Zach 2024-12-02T17:48:13.187699Z

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 πŸ˜„

Felipe 2024-12-02T18:19:14.674989Z

got to use lazy-seq! https://github.com/FelipeCortez/advent-of-code/blob/master/2024/02.clj

❀️ 2
Ben Sless 2024-12-02T19:16:21.378049Z

(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

Ben Sless 2024-12-02T19:17:34.353029Z

@felipecortezfi > (apply < xs) Gorgeous

2
Felipe 2024-12-02T19:28:50.177519Z

@ben.sless TIL about set-test!

πŸ™Œ 1
2024-12-02T20:40:38.419339Z

TIL set-test (and not the only one)

2024-12-02T20:41:23.989849Z

(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 today

Kathryn Isabelle Lawrence 2024-12-02T22:34:45.464699Z

I 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

Chase 2024-12-02T22:54:04.880039Z

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

ghaskins 2024-12-02T23:04:23.445949Z

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.

carnundotcom 2024-12-02T23:43:32.777829Z

Enjoyed this one! https://github.com/CarnunMP/Advent-of-Code/blob/master/src/y2024/d2.clj

carnundotcom 2024-12-02T23:48:57.288119Z

> 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.

carnundotcom 2024-12-02T23:51:08.039119Z

> (apply < xs) > ... > (apply < l) dammit, why'd I partition into pairs... xD

1
ghaskins 2024-12-02T23:57:07.858589Z

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)
=> false

3
πŸ‘€ 1
ghaskins 2024-12-02T23:57:09.086869Z

cool

ghaskins 2024-12-02T23:57:49.283589Z

These AOC puzzles were built for clojure, heh.

1
Ryan Fleck 2024-12-03T04:21:48.864809Z

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.

Ryan Fleck 2024-12-03T04:24:11.758529Z

No kidding.

Benjamin 2024-12-03T07:09:27.668779Z

Love the swag with the 2 'every?' calls by @tws

Daniel Galvin 2024-12-03T10:51:22.727359Z

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

Ingy dΓΆt Net 2024-12-03T23:35:11.551329Z

YAMLScript: https://github.com/ingydotnet/advent-of-code/blob/main/2024/02/part1.ys

Felipe 2024-12-05T09:24:17.579019Z

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

roklenarcic 2024-12-02T05:21:30.432079Z

I got slowed down a bit by the lack of dissoc at index for vector

roklenarcic 2024-12-02T05:28:22.271839Z

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

βž• 2
1
Maravedis 2024-12-02T05:46:58.573799Z

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.clj

1
Andrew Byala 2024-12-02T06:42:09.168849Z

I 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

Max 2024-12-05T02:48:25.858939Z

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

Sam Ferrell 2024-12-05T04:58:42.733669Z

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