Remix.run Logo
fainpul 7 hours ago

Opinion poll:

Python is extremely suitable for these kind of problems. C++ is also often used, especially by competitive programmers.

Which "non-mainstream" or even obscure languages are also well suited for AoC? Please list your weapon of choice and a short statement why it's well suited (not why you like it, why it's good for AoC).

sunrunner 7 hours ago | parent | next [-]

My favourite "non-mainstream" languages are, depending on my mood at the time, either:

- Array languages such as K or Uiua. Why they're good for AoC: Great for showing off, no-one else can read your solution (including yourself a few days later), good for earlier days that might not feel as challenging

- Raw-dogging it by creating a Game Boy ROM in ASM (for the Game Boy's 'Z80-ish' Sharp LR35902). Why it's good for AoC: All of the above, you've got too much free time on your hands

Just kidding, I use Clojure or Python, and you can pry itertools from my cold, dead hands.

nemo1618 6 hours ago | parent | prev | next [-]

I made my own, with a Haskell+Bash flavor and a REPL that reloads with each keystroke: https://www.youtube.com/watch?v=r99-nzGDapg

This year I've been working on a bytecode compiler for it, which has been a nice challenge. :)

When I want to get on the leaderboard, though, I use Go. I definitely felt a bit handicapped by the extra typing and lack of 'import solution' (compared to Python), but with an ever-growing 'utils' package and Go's fast compile times, you can still be competitive. I am very proud of my 1st place finish on Day 19 2022, and I credit it to Go's execution speed, which made my brute-force-with-heuristics approach just fast enough to be viable.

taolson 4 hours ago | parent [-]

>I made my own, with a Haskell+Bash flavor and a REPL that reloads with each keystroke

That was impressive! Do you have a public repo with your language, anywhere?

WJW 7 hours ago | parent | prev | next [-]

I like to use Haskell, because parser combinators usually make the input parsing aspect of the puzzles extremely straightforward. In addition, the focus of the language on laziness and recursion can lead to some very concise yet idiomatic solutions.

Example: find the first example for when this "game of life" variant has more than 1000 cells in the "alive" state.

Solution: generate infinite list of all states and iterate over them until you find one with >= 1000 alive cells.

    let allStates = iterate nextState beginState # infinite list of consecutive solutions
    let solution = head $ dropWhile (\currentState -> numAliveCells currentState < 1000) allStates
taolson 5 hours ago | parent | next [-]

Yes, there are some cool solutions using laziness that aren't immediately obvious. For example, in 2015 and 2024 there were problems involving circuits of gates that were elegantly solved using the Löb function:

https://github.com/quchen/articles/blob/master/loeb-moeb.md

jvuygbbkuurx 5 hours ago | parent | prev | next [-]

Does this solution copy the state on each iteration?

WJW 4 hours ago | parent [-]

Haskell values are immutable, so it creates a new state on each iteration. Since most of these "game of life" type problems need to touch every cell in the simulation multiple times anyway, building a new value is not really that much more expensive than mutating in place. The Haskell GC is heavily optimized for quickly allocating and collecting short-lived objects anyway.

But yeah, if you're looking to solve the puzzle in under a microsecond you probably want something like Rust or C and keep all the data in L1 cache like some people do. If solving it in under a millisecond is still good enough, Haskell is fine.

sltkr 12 minutes ago | parent [-]

Fun fact about Game of Life is that the leading algorithm, HashLife[1], uses immutable data structures. It's quite well suited to functional languages, and was in fact originally implemented in Lisp by Bill Gosper.

1. https://en.wikipedia.org/wiki/Hashlife

lkuty 6 hours ago | parent | prev [-]

Do you plan to share your solutions on Github or something similar ?

WJW 6 hours ago | parent [-]

I actually plan on doing this year in Gleam, because I did the last 5 years in Haskell and want to learn a new language this year. My solutions for last year are on github at https://github.com/WJWH/aoc2024 though, if you're interested.

shakna 7 hours ago | parent | prev | next [-]

I've always done it in a Scheme. Generally to learn a new compiler and its quirks.

Scheme is fairly well suited to both general programming, and abstract math, which tends to be a good fit for AoC.

andriamanitra 4 hours ago | parent | prev | next [-]

I think Ruby is the ideal language for AoC:

* The expressive syntax helps keep the solutions short.

* It has extensive standard library with tons of handy methods for AoC style problems: Enumerable#each_cons, Enumerable#each_slice, Array#transpose, Array#permutation, ...

* The bundled "prime" gem (for generating primes, checking primality, and prime factorization) comes in handy for at least a few of problems each year.

* The tools for parsing inputs and string manipulation are a bit more ergonomic than what you get even in Python: first class regular expression syntax, String#scan, String#[], Regexp::union, ...

* You can easily build your solution step-by-step by chaining method calls. I would typically start with `p File.readlines("input.txt")` and keep executing the script after adding each new method call so I can inspect the intermediate results.

encomiast 7 hours ago | parent | prev | next [-]

It was mind-boggling to see SQL solutions last year: https://news.ycombinator.com/item?id=42577736

JokerDan 7 hours ago | parent [-]

This is what is great about it, the community posting hyper-creative (sometimes cursed) solutions for fun! I usually use AoC to try out a new language and that has been fun for me over the years.

AstroBen 4 hours ago | parent | prev | next [-]

This question is really confusing to me because the point of AoC is the fun and experience of it

So.. a language that you're interested in or like?

Reminds me of "gamers will optimize the fun out of a game"

I'm pretty clojure-curious so might mess around with doing it in that

matsemann 5 hours ago | parent | prev | next [-]

I use python at work but code these in kotlin. The stdlib for lists is very comprehensive, and the syntax is sweet. So easy to make a chain of map, filter and some reduction or nice util (foldr, zipwithnext, windowed etc). Flows very well with my thought process, where in python I feel list comprehensions are the wrong order, lambdas are weak etc.

I write most as pure functional/immutable code unless a problem calls for speed. And with extension functions I've made over the years and a small library (like 2d vectors or grid utils) it's quite nice to work with. Like, if I have a 2D list (List<List<E>>), and my 2d vec, like a = IntVec(5,3), I can do myList[a] and get the element due to an operator overload extension on list-lists.

and with my own utils and extension functions added over years of competitive programming (like it's very fluent

auxym 4 hours ago | parent | prev | next [-]

I've had a lot of fun using Nim for AOC for many years. Once you're familiar with the language and std lib, its almost as fast to write as python, but much faster (Nim compiles to C, which then gets compiled to your executable). This means that sometimes, if your solution isn't perfect in terms of algorithmic complexity, waiting a few minutes can still save you (waiting 5 mins for your slow Nim code is OK, waiting 5 hours for your slow Python isn't really, for me). Of course all problems have a solution that can run in seconds even in Python, but sometimes it's not the one I figure out first try.

Downsides: The debugging situation is pretty bad (hope you like printf debugging), smaller community means smaller package ecosystem and fewer reference solutions to look up if you're stuck or looking for interesting alternative ideas after solving a problem on your own, but there's still quality stuff out there.

Though personally I'm thinking of trying Go this year, just for fun and learning something new.

Edit: also a static type system can save you from a few stupid bugs that you then spend 15 minutes tracking down because you added a "15" to your list without converting it to an int first or something like that.

jlouis 7 hours ago | parent | prev | next [-]

Go is strong. You get something where writing a solution doesn't take too much time, you get a type system, you can brute-force problems, and the usual mind-numbing boring data-manipulation handling fits well into the standard tools.

OCaml is strong too. Stellar type system, fast execution and sane semantics unlike like 99% of all programming languages. If you want to create elegant solutions to problems, it's a good language.

For both, I recommend coming prepared. Set up a scaffold and create a toolbox which matches the typical problems you see in AoC. There's bound to be a 2d grid among the problems, and you need an implementation. If it can handle out-of-bounds access gracefully, things are often much easier, and so on. You don't want to hammer the head against the wall not solving the problem, but solving parsing problems. Having a combinator-parser library already in the project will help, for instance.

sunrunner 7 hours ago | parent [-]

> For both, I recommend coming prepared.

Any recommendations for Go? Traditionally I've gone for Python or Clojure with an 'only builtins or things I add myself' approach (e.g. no NetworkX), but I've been keen to try doing a year in Go however was a bit put off by the verbosity of the parsing and not wanting to get caught spending more time futzing with input lines and err.

Naturally later problems get more puzzle-heavy so the ratio of input-handling to puzzle-solving code changes, but it seemed a bit off putting for early days, and while I like a builtins-only approach it seems like the input handling would really benefit from a 'parse don't validate' type approach (goparsec?).

jlouis 6 hours ago | parent [-]

It's usually easy enough for Go you can just roll your own for the problems at hand. It won't be as elegant as having access to a combinator-parser, but all of the AoC problems aren't parsing problems.

Once you have something which can "load \n seperated numbers into array/slice" you are mostly set for the first few days. Go has verbosity. You can't really get around that.

The key thing in typed languages are to cook up the right data structures. In something without a type system, you can just wing things and work with a mess of dictionaries and lists. But trying to do the same in a typed language is just going to be uphill as you don't have the tools to manipulate the mess.

Historically, the problems has had some inter-linkage. If you built something day 3, then it's often used day 4-6 as well. Hence, you can win by spending a bit more time on elegance at day 3, and that makes the work at day 4-6 easier.

Mind you, if you just want to LLM your way through, then this doesn't matter since generating the same piece of code every day is easier. But obviously, this won't scale.

sunrunner 2 hours ago | parent [-]

> It won't be as elegant as having access to a combinator-parser, but all of the AoC problems aren't parsing problems.

Yeah, this is essentially it for me. While it might not be a 'type-safe and correct regarding error handling' approach with Python, part of the interest of the AoC puzzles is the ability to approach them as 'almost pure' programs - no files except for puzzle input and output, no awkward areas like date time handling (usually), absolutely zero frameworks required.

> you can just wing things and work with a mess of dictionaries and lists.

Checks previous years type-hinted solutions with map[tuple[int, int], list[int]]

Yeah...

> but all of the AoC problems aren't parsing problems.

I'd say for the first ten years at least the first ten-ish days are 90% parsing and 10% solving ;) But yes, I agree, and maybe I'm worrying over a few extra visible err's in the code that I shouldn't be.

> if you just want to LLM your way through

Totally fair point if I constrain LLM usage to input handling and the things that I already know that I know how to do but don't want to type, although I've always quite liked being able to treat each day as an independent problem with no bootstrapping of any code, no 'custom AoC library', and just the minimal program required to solve the problem.

marc_omorain 7 hours ago | parent | prev | next [-]

Clojure works really well for AOC.

A lot of the problems involve manipulating sets and maps, which Clojure makes really straightforward.

Barrin92 3 hours ago | parent [-]

I'll second Clojure not just for the data structures but also because of the high level functions the standard library ships with.

Things like `partition`, `cycle` or `repeat` have come in so handy when working with segments of lists or the Conway's Game-of-Life type puzzles.

bhollan 7 hours ago | parent | prev | next [-]

I used MATLAB last year while I was re-learning it for work. It did okay, but we didn't have a license for the Image Processing Toolbox, which has a boatload of tools for the grid based problems.

infamousclyde 7 hours ago | parent | prev | next [-]

I’ve always used AoC as my jump-off point for new languages. I was thinking about using Gleam this year! I wish I had more profound reasons, but the pipeline syntax is intriguing and I just want to give it a whirl.

ceautery 5 hours ago | parent [-]

That's a perfectly valid reason.

I tried AoC out one year with the Wolfram language, which sounds insane now, but back then it was just a "seemed like the thing to do at the time" and I'm glad I did it.

rootnod3 7 hours ago | parent | prev | next [-]

My personal choice is always Common Lisp. Absolute swiss army knife.

tmtvl 3 hours ago | parent [-]

With both AoC and Project Euler I like seeing how fast I can get my solution to run with SBCL. Finding all palindromic primes below a million in less than a second is pretty neat.

incognito124 5 hours ago | parent | prev | next [-]

If I remember correctly, one of the competitive programming experts from the global leaderboard made his own language, specifically tailored to help solve AoC problems:

https://github.com/betaveros/noulith

wging 4 hours ago | parent [-]

Yes (or so I thought too!), but apparently no: https://blog.vero.site/post/noulith

(post title: "Designing a Programming Language to Speedrun Advent of Code", but starts off "The title is clickbait. I did not design and implement a programming language for the sole or even primary purpose of leaderboarding on Advent of Code. It just turned out that the programming language I was working on fit the task remarkably well.")

taolson 5 hours ago | parent | prev | next [-]

AoC has been a highlight of the season for me since the beginning in 2015. I experimented with many languages over the years, zeroing in on Haskell, then Miranda as my language of choice. Finally, I decided to write my own language to do AoC, and created Admiran (based upon Miranda and other lazy, pure, functional languages) with its own self-hosted compiler and library of functional data structures that are useful in AoC puzzles:

https://github.com/taolson/Admiran https://github.com/taolson/advent-of-code

mrkaye97 5 hours ago | parent | prev | next [-]

I've been using Elixir, which has been wonderful, mostly because of how amazing the built in `Enum` library is for working on lists and maps (since the majority of AoC problems are list / map processing problems, at least for the first while)

cyberpunk 4 hours ago | parent [-]

Enum really does feel like a superpower sometimes. I’ll knock out some loop and then spend a few mins with h Enum.<tab> and realise it could’ve been one or two Enum functions.

tonyedgecombe 2 hours ago | parent | prev | next [-]

I think that whatever you know well is the best choice.

natrys 6 hours ago | parent | prev | next [-]

I am going to try and stick with Prolog as much as I can this year. Plenty of problems involve a lot of parsing and searching, both could be expressed declaratively in Prolog and it just works (though you do have to keep the execution model in mind).

andrelaszlo 3 hours ago | parent | prev | next [-]

I think Crystal, Nim, Julia and F# were my favorites from last year's AoC

I wrote a bit more about it here https://laszlo.nu/blog/advent-of-code-2024.html

AoC is a great opportunity for exploring languages!

fainpul 7 hours ago | parent | prev | next [-]

For some grid based problems, I think spreadsheets are very powerful and under-appreciated.

The spatial and functional problem solving makes it easy to reason about how a single cell is calculated. Then simply apply that logic to all cells to come up with the solution.

makerofthings 3 hours ago | parent | prev | next [-]

Another vote for Haskell. It’s fun and the parsing bit is easy. I do struggle with some of the 2d map style questions which are simpler in a mutable 2d array in c++. It’s sometimes hard to write throwaway code in Haskell!

sevenseacat 6 hours ago | parent | prev | next [-]

I've been using Elixir since day one, and it works pretty well :)

aloisdg 6 hours ago | parent [-]

I plan to do it in elixir too this year :)

keithlfrost 6 hours ago | parent | prev | next [-]

Elixir Livebook is my tool of choice for Advent of Code. The language is well-suited for the puzzles, I can write some Markdown if I need to record some algebra or my thought process, the notebook format serves as a REPL for instant code testing, and if the solution doesn't fit neatly into an executable form, I can write up my manual steps as well.

vharuck 5 hours ago | parent | prev | next [-]

I've done some of the problems in R. Vectorized-by-default can avoid a lot of boilerplate. And for problems that aren't in R's happy path, I learn how to optimize in the language. And then I try to make those optimizations non-hideous to read.

ashdnazg 4 hours ago | parent [-]

My wife did one of the years in Matlab. Some of the problems translate very nicely into vectors and matrices.

riffraff 7 hours ago | parent | prev | next [-]

I usually do it with ruby with is well suite just like python, but last year I did it with Elixir.

I think it lends itself very well to the problem set, the language is very expressive, the standard library is extensive, you can solve most things functionally with no state at all. Yet, you can use global state for things like memoization without having to rewrite all your functions so that's nice too.

Alex_L_Wood 4 hours ago | parent | prev | next [-]

Not sure if Kotlin is non-mainstream, but being able to use the vast Java libraries choice and a much nicer syntax are great boons.

4pkjai 7 hours ago | parent | prev | next [-]

Kotlin, because it’s a language I like

jpgvm 5 hours ago | parent [-]

IMO it's maybe the best suited language to AoC. You can write it even faster than Python, has a very terse syntax and great numerical performance for the few challenges where that matters.

christophilus 4 hours ago | parent | prev | next [-]

I’d say Clojure because it has great data manipulation utilities baked into the standard library.

azkalam 5 hours ago | parent | prev | next [-]

Terse languages with great collection functions in the standard libraries and tail call optimization. Haskell, OCaml, F# ...

yxhuvud 5 hours ago | parent | prev | next [-]

Crystal. Expressiveness and get-shit-done ability similar to the one of Ruby while being way faster in execution.

yoyohello13 5 hours ago | parent | prev | next [-]

Haskell is my favorite for advent of code. Finally give me an opportunity to think in a pure functional way.

6 hours ago | parent | prev | next [-]
[deleted]
f1shy 7 hours ago | parent | prev | next [-]

I’ve been doing them is JS and Common Lisp. I recommend the problems to help learning new languages.

StopDisinfo910 7 hours ago | parent [-]

I respect the effort going into making Advent of Code but with the very heavy emphasis on string parsing, I'm not convinced it's a good way to learn most languages.

Most problems are 80%-90% massaging the input with a little data modeling which you might have to rethink for the second part and algorithms used to play a significant role only in the last few days.

That heavily favours languages which make manipulating string effortless and have very permissive data structures like Python dict or JS objects.

f1shy 5 hours ago | parent | next [-]

You are right. The exercises are heavy in one area. Still, for starting in a new language can be helpful: you have to do in/out with files. Data structures, and you will be using all flow control. So you will not be an ace, but can help to get started.

I know people who make some arbitrary extra restriction, like “no library at all” which can help to learn the basics of a language.

The downside I see is that suddenly you are solving algorithmic problems, which some times are bot trivial, and at the same time struggling with a new language.

mhitza 5 hours ago | parent | prev [-]

That's a hard agree and a reason why anyone trying to learn Haskell, OCaml, or other language with minimal/"batteries depleted" stdlib will suffer.

Sure Haskell comes packaged with parser combinators, but a new user having to juggle immutability, IO and monads all at once at the same time will be almost certainly impossible.

PapstJL4U 3 hours ago | parent [-]

Maybe not learning a new language from the ground up, but I think it is good training to "just write" within the language. A daily or twice-daily interaction. Setting up projects, doing the basic stuff to get things running, and reading up on the standard library.

Having smaller problems makes it possible to find multiple solutions as well.

6 hours ago | parent | prev [-]
[deleted]