code-reviews

Michael Sims 2025-01-15T07:06:30.550219Z

Hi, Some coworkers and I are working through Advent of Code 2015 at a very relaxed pace and I've decided to use Clojure. I've only been learning the language for a week or two, going through Clojure for the Brave and True (at the end of chap 4 now). The first puzzle is naturally very simple, but even so I made many judgement calls in how to approach it, and I'm mainly wondering how close my code is to being idiomatic. If anyone could take a look, I would be very grateful. Thank you! https://github.com/MichaelSims/sims-aoc-2015-clj/blob/main/clojure/day01.clj

Michael Sims 2025-01-15T08:03:11.095359Z

Thanks, I will give that a shot. I did try that originally but I ran into some error. I don't have my IDE up at the moment, but I'll take a crack at it tomorrow and I may bug you again in this thread if I hit another wall w/that.

Michael Sims 2025-01-15T08:03:45.533789Z

(The error was related to the way conj works w/vectors vs lists)

teodorlu 2025-01-15T17:45:32.831819Z

Welcome to Clojure!

(defn solve-part-one []
  (reduce
   (fn [current-floor character] ((if (= character "(") inc dec) current-floor))
   0
   (get-input-list)))
I generally prefer to work with map and filter over reduce, then it's easier to see what's happening step by step. To map ( and ) to floor movement, we can use maps as functions:
(map {\( 1 \) -1} "(()(()(")
;; => (1 1 -1 1 1 -1 1)
... which we can finally reduce to get the sum.
(reduce + (map {\( 1 \) -1} "(()(()("))
;; => 3
That line is a bit long, so I prefer to split it up with ->>. ->> is made for composing functions that pass sequences as the last argument to the function. Examples here: https://clojuredocs.org/clojure.core/-%3E%3E With ->> in our toolbelt, the code becomes
(->> "(()(()("
     (map {\( 1 \) -1})
     (reduce +))
;; => 3
, which I'd consider idiomatic 🙂

Michael Sims 2025-01-15T17:46:48.128619Z

Awesome, and thank you, this is great. I did use ->> for part 2.

👍 1
teodorlu 2025-01-15T17:47:27.610629Z

Right, I just read part 1 👍

👍 1
teodorlu 2025-01-15T17:51:27.507539Z

For part 2, have you seen the function reductions before? https://clojuredocs.org/clojure.core/reductions

Michael Sims 2025-01-15T17:52:59.037829Z

I have not

Michael Sims 2025-01-15T17:53:27.578849Z

Excellent

❤️ 1
teodorlu 2025-01-15T17:53:46.158349Z

It was looking a bit like you were re-implementing reductions 🙂

Michael Sims 2025-01-15T17:53:50.867889Z

definitely

teodorlu 2025-01-15T18:00:47.027679Z

I took a stab at part 2 myself, and I ended up with almost exactly the same as your code, except I used reductions. So I'd consider the rest of that solution nice too 🙂

Michael Sims 2025-01-15T18:01:15.111889Z

Thank you! very helpful. I will rework it a bit later

🎉 1
teodorlu 2025-01-15T18:01:34.906749Z

any time 🙂

Chase 2025-01-15T23:03:26.744079Z

For another reference, here was my solution from back in the day: https://github.com/chase-lambert/aoc-clojure/blob/main/src/aoc/2015/day_01.clj Looks like I also ended up using reductions. I used apply instead of reduce but some discourage that is I think it is not as performant as reduce. Another little idiomatic Clojure thing is to use inc instead of (+ 1 ...). There is also a #adventofcode channel but I'm not sure how easy it would be to go back and see other solutions from that far back. A great resource I always refer to is: https://clojure.org/api/cheatsheet You can find so many handy stdlib functions.

👍 1
Michael Sims 2025-01-15T23:11:01.205619Z

Awesome. Very helpful. Yeah, I don't know why I didn't inc in part 2 given that I had already used that elsewhere

Michael Sims 2025-01-15T23:13:05.303359Z

I do some some messages popping up when I search #adventofcode for 2015 so I'll check those too as I go forward

2025-01-15T07:27:44.069259Z

Start the reduce with a vector, then you don't need to reverse