I love AoC! Did it the last 2-3 years in Rust, hanging out in a discord where we all try to make the absolute fastest solutions. Learnt all kinds of crazy performance hacks and some advanced algorithms & SIMD that way.
This time I'm trying to do them in Rust and Golang in an effort to either learn to like/tolerate Golang (because we use it at work) or prove my hypothesis that it sucks and never use it unless I have to.
I've used Go in the past few years (but I never find the time / attention span to get any further than day 6), I really like it for this kind of thing because it's pragmatic, minimal environment setup / "sidequests", most things you need (reading/parsing files, etc) are builtin, performance is great and close to the metal (few hidden performance pitfalls), etc.
I can't compare with Rust though because I've never used it. From a very superficial point of view though, it feels less pragmatic. But since AoC doesn't need memory safety or whatever criteria you have for production software, pragmatism and performance for later challenges are more important than safety.
Same. I am doing rust + clojure this year. Very interested in performance hax, esp around SIMD. I know absolutely nothing at all about rust, this is my first time working with it.
My day 1 rust solution:
cargo solve 1 --
release
Finished `release` profile [optimized] target(s) in 0.05s
Running `target/release/01`
Part 1: 1189304 (95.8µs)
Part 2: 24349736 (120.4µs)
Day 1 clojure solution:
lein run 1
running all tasks for day 1
reading input from resources/day01.txt
running day 1 part 1
part-fn: #'aoc.day-01/part-1
took: 5.511375 ms
result: 1189304
reading input from resources/day01.txt
running day 1 part 2
part-fn: #'aoc.day-01/part-2
took: 1.822334 ms
result: 243497365
I tried doing Rust, but I'm too dumb to figure out if each day should be a module or if I should use lib (I guess?) files for each day and link everything to a main entry point.
Each day is a new module, this way I don't have to think of new names for part1() and part2(). I can still import code from the rest of the crate if I want with `use crate::`.
If you like this style of structuring the project, you may be interested in the generator I use for it - http://github.com/nindalf/aocgen. `aocgen --day 2` will create these files and save you a bit of time. It will even download your problem input if you give it your adventofcode.com cookie.
Also check out https://codspeed.io/advent/day/1 for other Rust solutions that are aimed at being fast. They all use the same project structure. I wouldn't read the top 20 solutions though, they sacrifice readability and idiomaticity for speed.
This years challenge for me: write it in C without the standard library or an allocator. Has to be runnable on an STM32 with 32kb of SRAM.
I tried doing it in Assembly two years ago, ended up spending hours and hours writing an Assembly standard library, then gave up and switched to Rust...
Last year I tried C on a real Amiga 1200 (using DICE, Matt Dillon’s compiler / runtime). I didn’t get very far, lack of memory protection makes things really hard.
This year the Amiga has an 060 upgrade with an MMU, so perhaps I can figure out how to use that and have another go.
Forgive the dumb question... it's been ages since I've done Amiga programming in C. What behaves differently? Is the lower K of memory mapped, such that null pointer deferences cause excitement rather than simply crashing your program? Or is it something else?
> I didn’t get very far, lack of memory protection makes things really hard
What was the issue with lack of memory protection? If you're used to programming in C is there actually that much difference to running on a modern PC or embedded system?
Good luck! Personally, I'm still going with CL but decided to try it in all the languages I "know" for the first day. Including C which doesn't have hash tables (inb4 hsearch)... what a pain, let me tell you.
I don't think there are enough entries to make it worth the cost of a hash. I know it's not "efficient" exactly, but just repeatedly looping through and counting just isn't that slow.
Your restrictions sound quite challenging, good luck!
Last year I solved all the problems in C without external libraries [1] and I enjoyed it a lot. It forced me implement some low-level stuff that I had forgotten how to do (e.g. a heap) and to write some numerical routines myself (easier than you'd think!).
Symmetrically, I would consider only using sh and standard non-Turing-complete CLI tools (grep yes, awk no). About as limiting, but without devastating memory corruption bugs.
I think there might end up being some problems which will be very challenging to solve with those resource constraints - namely memory. You will probably have to be pretty clever with your solutions.
I remember one of my naive brute force solutions from last year ended up allocating gigabtyes of memory. There were obviously more efficient solutions, but some of the inputs are pretty large and so hefty allocations might be difficult to avoid.
This year is a tiny bit weird, I was just getting ramped up organizing the event at a new job; because I think it's very useful for devs to learn some real problem solving, as opposed to stitching frameworks.
And then I had to leave because my new boss turned out to be someone I couldn't imagine working with.
dont you find all the string parsing and manipulation to be quite painful in Swift? I tried to do AoC in Swift before and that put me off a lot. I liked doing little functional one liners but a week from now the parsing burden will be too high.
I program everyday in Swift. I attempted AoC for the first time in Swift last year and gave up after about a week or so for this exact reason and switched to python for the remainder. I don't want to struggle with the awkward string API to do things other languages can do in a line.
Are you writing the solutions / compiling / running all with Emacs? I wanted to try Swift this year as well but feels sort of silly spinning up XCode for this.
You can use VSCode with a swift project created with the SwiftPackageManager (SPM). I find the experience to be good, with a good LSP support. I just have to sometimes trigger the build task for it to find newly defined objects.
Those are the problems I loathe the most, where the real problem is figuring out how to parse the input into something more workable. Once its parsed its ezpz.
Are you solving all puzzles? I find usually that the parsing isn't my problem, but some of the puzzles puzzle me (ha, couldn't resist), because they expect some kind of graph knowledge or some mathematical trick or so. Last year got stuck at day 17 for example. Usually some learning in it then, but parsing, while possibly annoying day after day, wasn't usually what stopped me from completing puzzles.
the input parsers don't get increasingly complex over the days. The problems themselves do. Even on the most difficult days around 22 or 23, the inputs are all just lines of space separate ints or some grid of points or something, just like the trivial problems on days 1-3
From last year: hot springs, the pipes problem, gears, pulses, range math.. half the problem is turning the text input into the correct data structures to solve it.
Aiming to get all the stars this year to round it out with 500 total - all the years, all the problems.
As of last week there were something around 1024 people who had all 450 stars.
Only started on like day 6 of 2022, but became hooked and had some time early in 2023 to go through the previous years. Once you have a few algorithms canned, it's not too difficult and some themes repeat across years.
It's fun to brush up on stuff you don't touch all the time - actual algorithms and stuff.
Hats off to the volunteers and Eric - I aim to donate every year now - it's a great event.
Woohoo, one of the highlights of this time of year. I had to do mine from an eastbound flight over the pacific. This has become a fun tradition not just for me personally but for many friends, colleagues, and fellow HNers. Big props once again to wastl and his helper elves for making this!
I encourage anyone who gets value from this to donate to support it if they can. It is a passion project but nonetheless comes with real costs.
> I encourage anyone who gets value from this to donate to support it if they can. It is a passion project but nonetheless comes with real costs.
With the sheer amount of sponsors and AoC++ users I do believe that this is not quite a small 'passion project' struggling to pay the monthly subscription to a VPS.
That being said, adventofcode is absolutely great and people should support it if they can. But I do think the author is doing quite well with the amount of support he is currently receiving.
I'm continuing my tradition of doing AoC in Whitespace[0]. The first year I did it, it was motivation to build out a standard library so things wouldn't be so tedious. Now, I find myself wishing I had finished better tooling. I debug with wsjq[1], a CLI debugger like gdb written in jq, but it's slow.
I've done last two AoCs in F# (well, only the first few days too). For a person without prior functional programming experience, it was fun! Unfortunately I won't have time to participate this year, but if I did, I'd probably chose F# again.
Nice. I've started picking up F# too and am trying AoC with it this year. I'm still early in my functional journey, but I think AoC has been helpful thus far.
Last year I got stuck on Day 12 for a full week, and thinking about how to solve it consumed my every waking moment. I think this year, I'm going to be kind to myself and not participate so I can really enjoy the winter break from work.
I'm doing this year in K2 (after a long hiatus from K). Is there a K4/5 binary? ATW gave me a K2 binary, but I miss some of the K4 and later functionality):
It ate my life for a few years in a row, I even managed to finish on Christmas eve twice. Now I don't even look, it turns from fun to stress rather quickly.
I re-read the intro and the fact it mentions leetcode and the like was enough for me to decide that it's an ultimately pointless endeavour for me.
I have no interest at all in competitive programming or maths; I spend 40+ hours a week doing programming for work, I want games and challenges that pull me away from that so I continue to have a life outside of my job.
Sounds sensible. It's important to set boundaries, and enjoy time off.
For me Advent of Code is a slippery slope. The difficulty ramps up so at first it's easy, then it's rewardingly difficult. But then before I know it, it takes wayyyyy too much time. The danger is being emotionally invested by then.
I usually make it Monday 18 or 19 and then I loose the will as the time taken is excessive, and obsessing about it is not good. I've finished a 5 years, but all after the fact. Some I am not sure I'll ever finish....
Oh man, this is my best memory of last year's AoC. After uselessly noodling for a while, I used Graphviz to draw the graph to an SVG file. It drew two messy balls of yarn neatly connected by three edges.
My script still says "TODO: find a real solution". Good times.
This was the day 25 problem: given a graph of ~1600 nodes and ~3500 edges, find the 3 edges that if deleted divide the graph into 2 components. I looked over some of the solutions and it surprised me how few used the simplest method: for each edge with endpoints u, v in the graph, delete it and then find another path P1 between u and v. Then, for each edge e1 in P1, delete it and then find another path P2 between u and v. Then, for each edge e2 in P2, delete it and then try to find another path between u and v. If there is no path, (u, v), e1, e2 is your cut-set. Otherwise, add e2 back and try the next edge in P2. When you've exhausted P2, add e1 back and try the next edge in P1. When you've exhausted P1, add (u, v) back and try the next edge in the graph. It's 3-6 loops deep depending on how you count, but it works. My python implementation completes in under 2 minutes, but it varies because it appears the standard python data structures have some nondeterminism, and I may have had a lucky draw with my puzzle input.
I have a self-imposed goal of not using third-party libraries for any of the solve logic. It feels more satisfying to do it myself, even if it takes longer.
Like Minecraft, everybody should play it however they want, it's just a game.
Which one was the "graph-cut puzzle" ? I've had a few where I couldn't do them on the day, either I was busy or I found them harder than usual or sometimes both.
It looks like in 2023 I took until almost New Year's Eve to finish, but until like the 21st of December I was fine, I got thrown off by travel and other commitments in the last few days as they got more difficult.
What solver are you referring to? I've used z3 and OR-tools, but I find it so difficult to model problems in either one that I seldom get good usage of either one.
This is my experience. After the first week I develop an intense hatred of all things Elf and start swearing at my laptop. At which point I give up to stop my mental health deteriorating any further.
One reason I didn't enjoy it was that I felt the days don't build on each other well. So you get little code reuse. It was continually changing requirements, so it was especially like work.
In 2019 he built up about 12 challenges using a VM, for Intcode, you had to construct. It was poorly received because without a working version (developed over the first few Intcode challenges), you couldn't solve the rest of them. He hasn't done anything like that since, though I thought it was probably the more interesting series of challenges.
The problem with continuity across days is that the later days can be blocked by the earlier ones, as they were in 2019. That partly defeats the purpose (or structure) of the challenge, where you can mostly pick any day and try it without regard to earlier days or prior years.
There's a lot of potential code reuse between years; whether that's good or bad is up to you, I think. (I would personally prefer if my Chinese remainder theorem solving function got less use, but it seems to be called for every year or two.)
We run a private board for Advent of Code for the Carolina Code Conference. Eligibility for prizes starts after earning only 10 of 50 possible stars precisely for this reason.
Oh cool. I live in WNC and had just missed your last conference in August. Is it possible to join multiple private boards? I usually do one with my coworkers as well
That's awesome. We do the exact same thing for prize eligibility on my work leaderboard. The whole point is for it to be fun and challenging. No need to grind to the end unless you want to.
Likewise. I did it one year in college and it became a life-consuming thing almost immediately. Not AoC's fault - part of it was depression, part of it was the Minnesota winter. Now that I have a full-time job and a wife, I'm trying to be more careful with those things that I know will suck me in.
The year I did it I got lucky and solved them all within a reasonable amount of time until there was one that suddenly involved a lot of nontrivial linear algebra and I immediately spotted that this wouldn't be fun and noped out. Noticed the number of people solving dropped off a cliff on that day.
I think as nerds we need to be quite careful not to get too drawn into this kind of thing. Sometimes it's like a superpower, but other times it just pointlessly consumes your life. Kinda makes me think of gambling addiction: "when the fun stops, you stop".
You can also set a time rule. For me it's 45min, if it takes longer to solve it, I an allowed to quit.
It's totally worth it, though, especially for the first week, when you look up how other people solved the thing you just solved. I always learned (or re-learned) something from that. IMHO there's not that much value in looking up solutions before you solved it yourself, though.
I just have them lingering in the back of my brain the whole year. I solved the last one from last year a month ago. This is much nicer than sudokus or whatever: I sometimes dream about them and I keep finding better (in my mind) solutions for ones from years ago. It's lovely when you sit at another dumb crap meeting/standup so you have something to do in your head.
Ah yeah I've been there! Having done it a few years now, I've found that the approach that works for me is: if it starts looking like I'll be stuck on one for more than a few hours, I'll skip it and move on. Otherwise I'll accumulate an insurmountable backlog that becomes more of a depressing chore to think about, than a fun little christmas tradition. I'd rather have a mostly-complete set of problems by the end of the year that I can come back and clean up when I feel like it.
That said, if you'd have a better holiday season by just stepping back from the computer and relaxing then that sounds great too. Either way - enjoy!
My main complaint the last time I did this (2022) was the havoc it wreaked on my sleep schedule. Advent of Code is not kind to East Coast participants.
Every year except for one has been kind of the same pattern for me:
Day 1: this year, I'm just going to solve the problems. No futzing around.
Day 3: but it would be kind of neat to turn the solutions into a reusable AoC library. Just something minimal.
Day 5: and I should really add a CLI harness for retrieving the problems and parsing the input files.
Day 6: and testing of course.
Day 7: maybe I'll skip today's problem (just for today) and keep improving the framework.
Hahaha...I love this comment. I have just been stuck for a week doing edge puzzles and backstepping recursion, keeping myself awake aye night because it bothered me I couldn't "just" solve it.
This time I'm trying to do them in Rust and Golang in an effort to either learn to like/tolerate Golang (because we use it at work) or prove my hypothesis that it sucks and never use it unless I have to.
I can't compare with Rust though because I've never used it. From a very superficial point of view though, it feels less pragmatic. But since AoC doesn't need memory safety or whatever criteria you have for production software, pragmatism and performance for later challenges are more important than safety.
My day 1 rust solution:
Day 1 clojure solution: Code here: https://github.com/whalesalad/aocI try every year to optimize for speed in zig: https://github.com/ManDeJan/advent-of-code
https://discord.gg/wYmyYsf
I have the opposite dilemma to you, I want to learn to like Rust.
Rust to me is what a modern take on a systems language would be. I think it’s substantially better than go.
Deleted Comment
I tried doing Rust, but I'm too dumb to figure out if each day should be a module or if I should use lib (I guess?) files for each day and link everything to a main entry point.
Can you share your repo (if public)?
Each day is a new module, this way I don't have to think of new names for part1() and part2(). I can still import code from the rest of the crate if I want with `use crate::`.
If you like this style of structuring the project, you may be interested in the generator I use for it - http://github.com/nindalf/aocgen. `aocgen --day 2` will create these files and save you a bit of time. It will even download your problem input if you give it your adventofcode.com cookie.
Also check out https://codspeed.io/advent/day/1 for other Rust solutions that are aimed at being fast. They all use the same project structure. I wouldn't read the top 20 solutions though, they sacrifice readability and idiomaticity for speed.
Dead Comment
I tried doing it in Assembly two years ago, ended up spending hours and hours writing an Assembly standard library, then gave up and switched to Rust...
This year the Amiga has an 060 upgrade with an MMU, so perhaps I can figure out how to use that and have another go.
What was the issue with lack of memory protection? If you're used to programming in C is there actually that much difference to running on a modern PC or embedded system?
https://git.sr.ht/~q3cpma/aoc2024/tree/master/item/01
If you could post a repo link so I can look at some of the progress, I'd be grateful.
- you can implement a hash table in C in about 125 LOC and reuse it.
- hash tables are not the only way to solve problems. hammer/nail
Last year I solved all the problems in C without external libraries [1] and I enjoyed it a lot. It forced me implement some low-level stuff that I had forgotten how to do (e.g. a heap) and to write some numerical routines myself (easier than you'd think!).
[1] https://github.com/sebastianotronto/aoc/tree/master/2023
I remember one of my naive brute force solutions from last year ended up allocating gigabtyes of memory. There were obviously more efficient solutions, but some of the inputs are pretty large and so hefty allocations might be difficult to avoid.
I do allow myself a 5Gb disk to which I can page out memory.
I think I'll follow in your footsteps. STM32F7 with 320k but with bare metal Rust :)
It's not half bad at this kind of twiddling for being a statically typed mainstream language.
https://github.com/codr7/aoc24/tree/main/swift/Sources/aoc
This year is a tiny bit weird, I was just getting ramped up organizing the event at a new job; because I think it's very useful for devs to learn some real problem solving, as opposed to stitching frameworks.
And then I had to leave because my new boss turned out to be someone I couldn't imagine working with.
Guess it'll be just me and Emacs as usual.
It’s Foundation so hopefully also on Linux/Windows, but if not there’s also one on GitHub called SwiftScanner.
1: https://developer.apple.com/documentation/foundation/scanner
The language has been moving pretty fast though, I have a feeling a lot of features I find useful are relatively new.
That is if you have nothing against using VSCode.
Deleted Comment
Sure, but then what's the point?
As of last week there were something around 1024 people who had all 450 stars.
Only started on like day 6 of 2022, but became hooked and had some time early in 2023 to go through the previous years. Once you have a few algorithms canned, it's not too difficult and some themes repeat across years.
It's fun to brush up on stuff you don't touch all the time - actual algorithms and stuff.
Hats off to the volunteers and Eric - I aim to donate every year now - it's a great event.
I encourage anyone who gets value from this to donate to support it if they can. It is a passion project but nonetheless comes with real costs.
With the sheer amount of sponsors and AoC++ users I do believe that this is not quite a small 'passion project' struggling to pay the monthly subscription to a VPS.
That being said, adventofcode is absolutely great and people should support it if they can. But I do think the author is doing quite well with the amount of support he is currently receiving.
For the pythonists around here, give F# a try: it can feels very close to scripting and it has a wonderful REPL too :)
[0]: https://github.com/thaliaarchi/ws-challenges
[1]: https://github.com/thaliaarchi/wsjq
For AoC I don't use a real project setup, just a `dayX.fsx` file and I run it like a script with `dotnet fsi dayX.fsx`, et voilà :)
https://github.com/jnordwick/aok2024
I have no interest at all in competitive programming or maths; I spend 40+ hours a week doing programming for work, I want games and challenges that pull me away from that so I continue to have a life outside of my job.
I’m not seeing my name on a leaderboard any time soon.
For me Advent of Code is a slippery slope. The difficulty ramps up so at first it's easy, then it's rewardingly difficult. But then before I know it, it takes wayyyyy too much time. The danger is being emotionally invested by then.
So it's not linear, and also based on your own knowledge. So perfectly fine to skip some days and still it's possible to solve some of the next ones!
https://eli.li/december-adventure
After I solved it I looked at other people's solutions and they used Meta's proposition solver in about 10 lines. Seemed like a massive cheat to me.
My script still says "TODO: find a real solution". Good times.
Which one was the "graph-cut puzzle" ? I've had a few where I couldn't do them on the day, either I was busy or I found them harder than usual or sometimes both.
It looks like in 2023 I took until almost New Year's Eve to finish, but until like the 21st of December I was fine, I got thrown off by travel and other commitments in the last few days as they got more difficult.
The problem with continuity across days is that the later days can be blocked by the earlier ones, as they were in 2019. That partly defeats the purpose (or structure) of the challenge, where you can mostly pick any day and try it without regard to earlier days or prior years.
I think as nerds we need to be quite careful not to get too drawn into this kind of thing. Sometimes it's like a superpower, but other times it just pointlessly consumes your life. Kinda makes me think of gambling addiction: "when the fun stops, you stop".
It's totally worth it, though, especially for the first week, when you look up how other people solved the thing you just solved. I always learned (or re-learned) something from that. IMHO there's not that much value in looking up solutions before you solved it yourself, though.
That said, if you'd have a better holiday season by just stepping back from the computer and relaxing then that sounds great too. Either way - enjoy!
Every year except for one has been kind of the same pattern for me:
Day 1: this year, I'm just going to solve the problems. No futzing around.
Day 3: but it would be kind of neat to turn the solutions into a reusable AoC library. Just something minimal.
Day 5: and I should really add a CLI harness for retrieving the problems and parsing the input files.
Day 6: and testing of course.
Day 7: maybe I'll skip today's problem (just for today) and keep improving the framework.
Day 358: oh neat, Advent of Code is coming up.
What line of work are you in that you can take a winter break, and furthermore, that you can actually not work during that break? I'm envious...
I've always wanted to do AoC but on top of work it is too much.
PRevious years I've managed basically the entire month of December.
I always have holiday days left over at the end of the year to take.