day 1
another ramble another year another year another ramble
a lot of you know the jig by now… but for the uninitiated…
this is jack’s advent of code rambles, where i ramble about my own advent of code solution for the day, and then discuss other solutions in comparison to mine / each other / etc.
this will be my fourth year giving this a go, (although 2023 was a farce), and given that this advent of code is 12 days instead of 24… maybe… just maybe… i will get to the end!
however
what a day 1
i think this checks out with being a lesser year, as its not a hard to think about problem, its just a… wonky part 2!
i spent a while trying to get my bound checking solution to work properly, to no avail, hence i’m so late with this post, usually i can pump out a day 1, and by the evening have time to sit down and sort out all of the infra needed in my mun website repo for this to exist
but yeah that didn’t happen this time…
but i still solved it! expand the below if you’re curious to year my approach
click to view my solution
given the sample input:
L68
L30
R48
L5
R60
L55
L1
L99
R14
L82assuming input is the above as one big string,
moves =
input
|> Kino.Input.read()
|> String.split("\n")
|> Enum.map(fn v ->
{dir, val} = String.split_at(v, 1)
{String.to_atom(dir), Integer.parse(val) |> elem(0)}
end)input parsin’
- split on newline
- map over each newline
- split those on the first char, so we get
{"L", "68"}and such - turn the
"L"into:L, because atoms are cool - parse the string as an int, grab the 0th elem (since it returns things not parsed as a number for some reason)
we get:
[L: 68, L: 30, R: 48, L: 5, R: 60, L: 55, L: 1, L: 99, R: 14, L: 82]nice, lets solve the problem
btw, it formats it like this, since it thinks its a keyword list
lets solve the problem
part 1
defmodule Util do
def bounds(cur) when cur < 0, do: bounds(cur + 100)
def bounds(cur) when cur >= 100, do: bounds(cur - 100)
def bounds(cur), do: cur
endi first define this bounds checking system, so i can check to see if i’ve gone past 99 / before 0
using some nice elixir guard syntax, and since i wanted recursion, i could not use an anon function in my solution, sad
moves
|> Enum.reduce({50, 0}, fn {dir, val}, {cur, seen_0} ->
cur = case dir do
:L -> cur - val
:R -> cur + val
end
cur = Util.bounds(cur)
if cur == 0 do
{cur, seen_0 + 1}
else
{cur, seen_0}
end
end)nice little reduce, take {50, 0} (starting value stated in the problem, and amount of zeros so far, starting at zero)
handle adding to / taking away the value from the current value, depending on the direction atom
use our bound utility to wrap it between 0-99
did we land on 0? yeah? + 1 to the seen_0
this gets the answer!
part 2
and of course part 2 is tricky
here we have to check if it loops around and hits zero during a loop
i spent a while trying to come up with a solution similar to the above, but one that would handle counting more spins within the bounds check, but i’d either be too high, or too low…
so, i did it a way that feels stupid, but works:
Enum.reduce(moves, {50, 0}, fn {dir, val}, {cur, seen_0} ->
1..val
|> Enum.reduce({cur, seen_0}, fn _x, {cur, seen_0} ->
cur = if dir == :L, do: cur - 1, else: cur + 1
cur = cond do
cur > 99 -> 0
cur < 0 -> 99
true -> cur
end
seen_0 = if cur == 0, do: seen_0 + 1, else: seen_0
{cur, seen_0}
end)
end)this is the entire solution, no need for a util
you’ll see we now have a nested reduce, that operats on 1..val, which means i’m adding / subtracting 1 one at a time,
and then i’m doing the seen_0 check in that…
this one is ‘smaller’, and more quaint, but obviously does not spark performance joy
but its a solution, and i’m onto looking at other peoples stuff
the full solution can be found [here]
as usual, i go through people who had repos in previous years, and see who’s still active doing 2025, and maybe add a few more that i see being posted around
we’ve got another assortment we do it seems!
others
[Keenan-Nicholson/AdventOfCode] python[mynameisgump/advent-of-code] pythonfor line in input1: comb_in = convert_to_int(line) pos += comb_in if mod100(pos) == 0: count += 1nice part 1 solution, don’t bother wrapping and just do mod on the value
and part 2…
for line in input2: comb_in = convert_to_int(line) prev_rotations = rotations rotations += comb_in mod_count += abs(rotations // 100 - prev_rotations // 100) dial_pos = rotations % 100store prev rotations, calculate new one, which… means you’re also just calculating the thing you need not caring about bounding the value
i think
dial_posisn’t even needed in here you just needmod_countno?very clean
me when i do a math degree and can do math
[evaan/AdventOfCode] python# 5984 Too Much # 5978?? # 5789 Nope # 5974 Don't know # 5329 too lowthis was me in part 2… glad to see i was not the only one
pretty verbose but gets the job done python approach
doing some mod stuff here, i think all of the print debugging if it was cleaned up would make this nice
good to have another year of gump
[nint8835/advent-of-code] f#a part 1 & 2 done in the same loop, short enough to include fully here inline
pos = 50 part1 = 0 part2 = 0 with open("input.txt") as f: for line in f: initialPos = pos l = line.strip() dist = int(l[1:]) direction = l[0] == "L" pos += dist * (-1 if direction else 1) part2 += dist // 100 pos -= (dist // 100) * 100 * (-1 if direction else 1) if initialPos != 0 and pos < 0: part2 += 1 elif pos > 100: part2 += 1 pos %= 100 if pos == 0 and initialPos != 0: part1 += 1 part2 += 1 print("Part 1", part1) print("Part 2", part2)tidy tidy TIDY!
i think this one is closer to what was in my head when i was thinking about this, the entire was i just at 0?, if so don’t count again sort of vibe
evan aoc even aoc
[ncashin/aoc2025] elixirhello mr f#
i see you’ve upgraded from
.fsxto.fs, you pulling out modules herei like this solution
i forget what
.folddoes, therefore i do not understand iti think you explained this to me for a previous aoc, but alas
brain is a siv
[STollenaar/AdventOfCode] go & javanatalie will be doing elixir, but cooked a day 1 solution in ruby, as per mwln’s request
this is nice
line 6 and 13 are a bit code golf though
good nat ruby
[djrideout/advent2025] rustsven back at it again with the go, i would expect nothing less
as always, some straightforward nice go, similar to evan’s solution
more verbose since its go, but also more tidy?
[OscarFKE/aoc2025] janetrusty dj back again
doing the parsing right next to handling the logic
#[aoc(day1, part1)]is always cool syntax to see with the cargo aoc packagei like the difference between part 1 & 2 being a
count_allvariable, tidyoh and you don’t add the single count at the end when you end up on zero when you are counting all!
if next == 0 && !count_all { count += 1; }nice and tidy
[Mudkip/AdventOfCode] elixiri saw a link to janet solution, so i just had to include it here
(def- lock-rotation-grammar (peg/compile ~{:main (some :rotation) :rotation (* (+ :left :right) :newline?) :left (* "L" (/ (<- :d+) ,make-left)) :right (* "R" (/ (<- :d+) ,make-right)) :newline? (? "\n")}))right off the bat we’ve got this, amazin’
peg/compilehere is so cool…Parsing Expression Grammars
…
PEGs, or Parsing Expression Grammars, are another formalism for recognizing languages. PEGs are easier to write than a custom parser and more powerful than regular expressions. They also can produce grammars that are easily understandable and fast. PEGs can also be compiled to a bytecode format that can be reused. Janet offers the peg module for writing and evaluating PEGs.
Janet’s peg module borrows syntax and ideas from both LPeg and REBOL/Red parse module. Janet has no built-in regex module because PEGs offer a superset of the functionality of regular expressions.
quite based to be like, we have this thing that is better than regex, no regex for you in stdlib
based
(defn- apply-rotations-count-zeros [starting-position rotations] (var dial-position starting-position) (seq [r :in rotations] (let [prev-dial-position dial-position new-dial-position (+ dial-position r)] (set dial-position (normalize-dial-position new-dial-position)) (sum (map |(if (zero? $0) 1 0) (iterate-clicks prev-dial-position new-dial-position))))))however then you get here
and even though i can understand the variables here, i lose focus
i respect, but comprehension crashes
i did try janet once, not for very long…
still though, hyped to see more here as the days progress
[terales/aoc-elixir] elixirnow here is a more proper elixir solution
|> Enum.reduce({50, 0, 0}, fn {d, v}, {acc, crossings, lands} ->the reducer counting both part 1 & 2 is better, i like the difference here in variables from crossing / lands!
and again, the trick where a right is just a div, but a left is a more busy one… i did not clock this…
mudkip ‘lixir
(also your timezone is currently more aligned to aoc how dare you)
alex came to my gdg st. john’s talk, and asked a good question, of which i felt like i had a pretty good response, to which his response was just to do:
so of course when i see
Solved in Elixir, inspired by Jack.
its going in the rant!
nice shared input parsing, good module usage, and clever floor / rem usage…
i feel like every other solution has stunted on me
but thats ok
any thoughts about any of the above?
reach out: