Advent of Code 2015 in Clojure

andyn

AN

Posted on December 2, 2022

Advent of Code 2015 in Clojure

Yes, you read that right; 2015.

I envy people who have the time to do these things as they happen but life seems to have a habit of getting in the way. I would describe my progress as "glacial".

But anyhoo, I thought I'd try completing each of the 2015 puzzles in Clojure as I'm learning it at present. I won't be marking spoilers as these puzzles are ~7 years old already and I'll likely just talk about solving them at a higher level than a blow by blow...

The Setup

I'm just running VSCode and using the calva plugin so I can just directly run Clojure code within my IDE. There is a deps.edn file which just has a {} in it. Nothing special.

Day One

Part One

Essentially we're given a string of open and close bracket characters as "elevator instructions" where ( means "go up a floor" and ) means "go down". Our first task is simply to take a sequence of these chars and determine which floor our elevator ends up on.

So this is my solution for that first part:


(defn eval-instr [floor instr]
  (+ floor ({\( 1 \) -1} instr)))

(defn eval-elevator [instructions]
  (reduce eval-instr 0 instructions))

(def puzzle-input (slurp "1.input"))

(comment
  (eval-elevator "(()))")
  (eval-elevator puzzle-input)
  )
Enter fullscreen mode Exit fullscreen mode

A few notes:

  • eval-instr takes a floor and an instruction, returning a new floor. Originally it was part of eval-elevator, but it's a little tidier this way.
  • I liked doing the floor command mapping using a map. I like often defining these transformations as data.
  • eval-elevator takes the instruction list and reduces it with the eval-instr to get the final floor number. I always have to look up the order of arguments for reduce :(
  • puzzle-input is initialised with the contents of the file "1.input", which is our puzzle input. Every language I think should have a slurp command, did you know it can take a URL also?
  • Finally, I put the tests into a comment tag so they're not evaluated unless I put my cursor over them in calva and press ALT+ENTER. A nice touch.
  • It occurs to me that we could simply count the number of each bracket chars in our puzzle input to get an answer quicker! However as we see in part 2, it's actually useful to not do that yet. But I would have counted if I'd thought about it at the time!

Part 2

The second part of this puzzle requires us to find the index of the first command to take the elevator below the zeroth floor. So we just want to step through our floors until we get to -1:


(defn find-basement [instr]
  (loop [floor 0
         instr instr
         count 1]
    (let [next-floor (eval-instr floor (first instr))]
      (if (== next-floor -1)
        count
        (recur next-floor (rest instr) (inc count))))))
Enter fullscreen mode Exit fullscreen mode

loop ... recur feels close to writing a loop in another language.

See you in a month when I get round to typing up the second day :|

馃挅 馃挭 馃檯 馃毄
andyn
AN

Posted on December 2, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Advent of Code 2015 (day 2)
clojure Advent of Code 2015 (day 2)

February 26, 2024

Advent of Code 2015 in Clojure
clojure Advent of Code 2015 in Clojure

December 2, 2022

Thoughts on Clojure 位
clojure Thoughts on Clojure 位

January 7, 2022

Advent of Code 2019 - Day 5
clojure Advent of Code 2019 - Day 5

December 13, 2019

Advent of Code 2019 - Day 3, Part 1
clojure Advent of Code 2019 - Day 3, Part 1

December 9, 2019