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)
)
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 theeval-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 pressALT+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))))))
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 :|
Edit: Part 2!
Top comments (2)
Its been a month
Ha ha!
Thanks for the reminder :)