I'm getting started this year - I used to program in Clojure at CircleCI full time, and since changing jobs I no longer use Clojure at work. Doing advent of code in Clojure each year is a lovely reprieve from the day to day C# and TypeScript.
Welcome back!
Thanks! Trying to remember how to paredit 😭
Are we using the same leaderboard as last year?
Let's do this. It's not full.
Day 1 - Solutions
fun little math problem in part 2 https://github.com/Ramblurr/advent-of-code/blob/main/src/aoc/2025/day01.clj
https://github.com/jaspya/advent-of-code/blob/main/2025/clojure/src/day1.clj I like these type of puzzles, no crazy performance issues just some numbers to play around with 😎
Used loop/recur for my solution
I don't like that (not (zero? curr)) check, feel like it maybe there's a more elegant formula that would work
My pet-peeve: people, instead of Integer/parseInt please start using parse-long .
Sorry, it seems like I annoyed you with my solution
Nah, it takes much more to annoy me 😉 This is just a tip for everybody.
Thanks for the tip
Updated my solution
https://mateuszmazurczak.com/aoc?lang=en#solution-7360ecc6-2896-45bb-89fe-150a682a30ca
here is mine: https://github.com/genmeblog/advent-of-code/blob/master/src/advent_of_code_2025/day01.clj
Here's my notebook: https://narimiran.github.io/aoc2025/src/day01/ Black Friday sale: For the price of one, you get two different solutions for Part 2!
https://github.com/tschady/advent-of-code/blob/main/src/aoc/2025/d01.clj
I'll try and clean up the if
ah! @ramblurr your zero crossings is clever. I'll still search for a non if sol'n though.
I tried to do an analytical solution for part 2 but my brain got fried. brute force works well enough https://github.com/FelipeCortez/advent-of-code/blob/master/2025/01.cljc
oooh, (< pos' 0 pos) is nicer than my (and (pos? ...) (neg? ...))
@narimiran I knew there had to be a better way than Integer/parseInt. Ty.
@ramblurr, skimming trough your solution: wouldn't it be better to use mapcat instead of map + flatten?
@norman nice idea with using iterate in the count-clicks function!
@narimiran yea that would be more idiomatic
oh my, just realized (looking at @jasperjm's solution), i don't have to have two separate conditions when to increment the result; (if (> start 0 (dec end)) 1 0) will cover both!
EDIT: and (>= start 1 0 end) might be a more readable version of the same thing
@tsulej nice usage of str/escape, i haven't seen that one yet! 👍
It is decidedly a Bad Idea, but just for fun I figured I'd share that for Part 1, I used (cycle (range 100)) and nthrest to handle moving the dial
(let [ns (for [v (str/split-lines (slurp "input"))
:let [direction (first v)
n (parse-long (apply str (rest v)))]]
(condp = direction
\L (mod (- n) 100)
n))]
(first (reduce (fn [[pass res] n]
(let [rotation (nthrest res n)]
(if (zero? (first rotation))
[(inc pass) rotation]
[pass rotation])))
[0 (nthrest (cycle (range 100)) 50)]
ns)))
wonky, but a different way of thinking about the dial movement originally was thinking of a giant cycled seq where i could move left and right, but wound up just moving right
i guess you could produce left and right cycled sequences from a position p, and then literally move n ticks from there, counting zeros along the way
0x434C49434B -> "CLICK"
@tws yes! 0x43 C, 0x4C L and so on. giggled when I tried this out in a hex to ascii tool
(def parsed-inputs
(for [v (str/split-lines (slurp "input"))
:let [direction (first v)
n (parse-long (apply str (rest v)))]]
[direction n]))
(def right-dial (cycle (range 100)))
(def left-dial (cycle (range 99 -1 -1)))
(defn make-position [p]
{:p p
:right (nthrest right-dial p)
:left (nthrest left-dial (- 99 p))})
(reduce (fn [[pass position] [direction n]]
(let [dial (if (= direction \L) :left :right)
clicks (take (inc n) (get position dial))
zeros (count (filter zero? (rest clicks)))]
[(+ pass zeros) (make-position (last clicks))]))
[0 (make-position 50)]
parsed-inputs)decided to do part 2 using cycled sequences as mentioned above
did a wacky transducer thing idk why. (edit: made it more terse for code-golf fun reasons)
it's good to do wacky on AoC 🙂
save your boring code for interviews
Extremely simple approach.
Full solution + utils in github: https://github.com/Maravedis/advent_code/blob/master/src/advent_of_code/2025/01.clj
the concision is strong with this one
Just figured out that my functions for part 1 and part 2 differ only in one line (how to count zeros), and I can easily make a function that solves both parts at once:
(ns net.lewisship.aoc25.day1
(:require [clojure.math :as math]
[net.lewisship.aoc25.util :refer [read-lines]]))
(defn parse-line
[s]
(let [[_ prefix digits] (re-matches #"(L|R)(\d+)" s)
sign (if (= prefix "L") -1 1)]
(* sign (parse-long digits))))
(defn turn-by
[dials rotation]
(let [dial (last dials)
new-dial (mod (+ dial rotation) 100)]
(conj dials new-dial)))
(defn stage1 [file-name]
(->> (read-lines file-name)
(map parse-line)
(reduce turn-by [50])
(filter zero?)
count))
(defn process-turn
[state rotation]
(let [{:keys [dial]} state
new-dial (+ dial rotation)
dial' (mod new-dial 100)
adjust? (or (zero? dial')
(and (not (zero? dial))
(not= dial' new-dial)))]
(cond-> (assoc state :dial dial')
adjust? (update :zeros inc))))
(defn expand-rotations
[rotation]
(if (< (abs rotation) 100)
[rotation]
(let [sign (if (pos? rotation) 1 -1)
n (math/floor-div (abs rotation) 100)
last-rotation (rem rotation 100)]
(-> (repeat n (* sign 100))
(conj last-rotation)))))
(defn stage2 [file-name]
(->> (read-lines file-name)
(map parse-line)
(mapcat expand-rotations)
(reduce process-turn {:dial 50
:zeros 0})
:zeros))
My solution to part 2 and spins > 100 is to expand a single spin of, say, 2007, to 20 spins of 100 and a spin of 7.My solution for today. Just finished adding compatibility with some of the other Clojure platforms. https://github.com/brandoncorrea/advent-of-code/blob/master/clojure/src/aoc/y2025/day01.cljc
https://github.com/benfle/advent-of-code/blob/main/src/advent_of_code/2025/01.clj very similar to some of the solutions already posted
I forgot to upload my solution from yesterday, so here it is. I always try to make a single reusable solve function that part1 and part2 share; it looks a little silly this time, but it's still succinct so I'll take it.
• https://github.com/abyala/advent-2025-clojure/blob/main/docs/day01.md
• https://github.com/abyala/advent-2025-clojure/blob/main/src/advent_2025_clojure/day01.clj
Clojure semi-noob here. Here's my solution. Not a huge fan of the "negative move" special case handling in Part 2, so I was interested to see everyone else's solutions to that
This is an embarrassing start, but I'm too tired to actually do this well. Maybe in the morning... https://gitlab.com/maximoburrito/advent2025/-/blob/main/src/day01/main.clj
https://github.com/samcf/advent-of-code/blob/main/2025-01-secret-entrance.clj This just reduces over the turns as positive or negative integers and maintains a position and a sum of stops (or passes over) zero. Figuring out how many multiples of 100 between two numbers was a head scratcher.
New to Clojure (partially using aoc to learn) so go easy 😜 But had fun with day 1!