Library / SDK
maneatingape/advent-of-code-rust avatar
maneatingape/advent-of-code-rust

advent-of-code-rust: eleven years of puzzles in one Rust crate

Blazing fast Rust solutions for every Advent of Code puzzle from 2015 to 2025, solving 524 stars in less than 1 second.

545 stars34 forksRustMIT

At a glance

What is it?
This repository holds optimised Rust solutions for every Advent of Code puzzle from 2015 to 2025, with the whole set solved in 461 milliseconds, a criterion for every solution, and no dependency outside the standard library. It is less a project than a benchmark suite for idiomatic Rust, with cargo bench built into the workflow and a lint configuration that reads like a style guide.
Who is it for?
Adopt this repository as a reading list if you want to see how an experienced Rust programmer writes dense, fast, allocation-conscious code for small well-specified problems, since every solution is a single file with rustdoc and a benchmark. Do not adopt it as production code or as a learning resource, because each solution assumes the puzzle's structure and a specific input format rather than a general problem domain.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Rust, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One crate, 524 stars, standard library only

The repository is a single Rust crate containing solutions for every Advent of Code puzzle from 2015 to 2025. The README's claim is that it takes 461 milliseconds to solve all 524 stars, and the repository description phrases the same thing as solving 524 stars in less than one second.

Those two statements are not identical, and the gap between them is a useful reminder that headline numbers in this project come from one specific machine. The benchmarks are measured with the built-in cargo bench tool on an Apple M2 Max, and the README adds that performance is reasonable even on older hardware, giving the example of a 2011 MacBook Pro with an Intel i7-2720QM which takes 3.5 seconds to run the same 262 solutions.

Three features are claimed and each maps to a concrete property of the code.

Minimal means the crate depends only on the standard library. That is a real constraint for a repository of this size, because the usual shortcuts in a puzzle solution, a regex crate, a parsing library, a heap helper, are all off the table, so every solution has to build what it needs.

High quality means the code is formatted with rustfmt, linted by clippy and continuously tested through GitHub Actions, and that there is no unsafe code. The last point is confirmed by the manifest, where unsafe_code is set to warn, and by the fact that the crate has no dependencies that could smuggle unsafe code in on its behalf.

Well documented means every solution is comprehensively commented, with rustdoc generated documentation published online. That matters more than it might seem, because a commented solution is a tutorial artifact, and a tutorial artifact that also has to be fast is a much harder constraint than either alone.

So the honest description of this project is a benchmark suite disguised as a puzzle collection. The puzzles are the test data, and the thing being optimised is the quality and speed of idiomatic Rust code.

Inputs, selectors and the shape of the run commands

The workflow is a Cargo project, and the README's quickstart section is a compact reference for it.

Inputs go in a predictable layout: input files in input/yearYYYY/dayDD.txt including leading zeroes, with input/year2015/day23.txt and input/year2023/day02.txt given as the examples. The zero padding is worth noting, because the day selector uses the same zero-padded form, so a file named day2.txt will not be found.

Running is done through cargo run with optional selectors, and the selector syntax is the elegant part of the design. Everything is cargo run, a specific year is cargo run year2023, and a specific day is cargo run year2023::day01. The year and day are not flags but arguments, which means the same selector syntax works for every subcommand.

The build profile and target features are part of the same line of options. The release profile is faster, and the SIMD feature is enabled with cargo run --features simd. The fastest option is the one that compiles for the CPU you are on, RUSTFLAGS="-C target-cpu=native" cargo run --release.

That last one deserves a warning from an engineering perspective, because it is the standard Rust caveat rather than a quirk of this repository. A binary compiled with target-cpu=native is tuned for the machine that built it and is not portable, so it belongs in a benchmark loop on your own machine and not in anything you ship.

The same selector grammar is used for tests, cargo test, cargo test year2023 and cargo test year2023::day01, with cargo test -- --nocapture to see the standard output while debugging. And for benchmarks, cargo bench, cargo bench year2023 and cargo bench year2023::day01.

So the entire interface is four verbs and a year::day path, and you learn it once.

Benchmarks as a design constraint, not a report card

Most solutions repositories treat the benchmark table as a footnote. Here it is the organising idea, and the per-year numbers in the README show why that matters.

The year totals are 1 millisecond for 2025, 4 for 2024, 4 for 2023, 5 for 2022, 8 for 2021, 220 for 2020, 10 for 2019, 33 for 2018, 56 for 2017, 107 for 2016 and 13 for 2015. One year out of eleven accounts for more than half of the total, and the README says something sharper about the distribution: 86 percent of the total time is spent on just 9 solutions.

That distribution is the point. The interesting engineering question is not how fast the easy days are, it is where the time actually goes, and nine solutions out of 524 are where it goes. A repository that optimised uniformly would be wasting effort, and the per-day tables make that visible at the day level, with figures ranging from 1 microsecond for the 2025 Gift Shop puzzle and 2 microseconds for the 2024 Chronospatial Computer to 688 microseconds for the 2024 Monkey Market puzzle and 441 microseconds for the 2025 Playground puzzle.

The Cargo.toml explains one of the reasons this is practical rather than a chore. The bench profile sets incremental = true, with a comment saying it speeds up benchmarking by not recompiling everything when only a single file changes. With 524 solutions and a per-file benchmark harness, that single line is the difference between a benchmark loop you can run and one you avoid.

For a reader, the tables are also a map. The day names are the puzzle titles, the 2025 set runs Secret Entrance, Gift Shop, Lobby, Printing Department, Cafeteria, Trash Compactor, Laboratories, Playground, Movie Theater, Factory, Reactor and Christmas Tree Farm, and each links to the puzzle and to the source file. The per-puzzle source link means you can go straight from a slow day to the code and see what the author did about it.

Feature flags: simd, and a joke called frivolity

The manifest declares exactly two feature flags.

One is simd, which is the one with engineering content. Enabling it with cargo run --features simd switches on a hand-written SIMD path in the solutions that can use one. Combined with the release profile, and with target-cpu=native on top, that is a three-level performance ladder: the debug build for correctness, the release build for speed, and the release build with the SIMD code path and CPU specific tuning on top.

In a standard library only crate, any SIMD has to come from the compiler's own vector types rather than from a crate like portable SIMD or wide, so the work per solution is not a flag flip but writing the vectorised variant by hand. The presence of the flag at all tells you the author considered that worth doing for the few puzzles where it pays.

The other is frivolity, which is declared as an empty feature list and, judging by the name, exists to be turned on for amusement. It is a small human touch in a manifest that is otherwise a machine for correctness, and it is a reminder that this repository is also a personal project with a sense of humour, not only a benchmark.

Neither flag changes the answers, only how fast they arrive. That separation is worth holding on to when you read the code, because it means the algorithmic content of a solution and its vectorised variant are two readable things rather than one opaque thing, and you can diff them to see what the SIMD path actually buys.

The lint configuration is the real style guide

The manifest's lint section is long, and it is the most transferable thing in the repository.

There are two blocks. The rust lints enable a large set of warnings by default, including elided_lifetimes_in_paths, explicit_outlives_requirements, unused_qualifications, unused_lifetimes, redundant_lifetimes, trivial_casts, trivial_numeric_casts, non_ascii_idents, unreachable_pub, unsafe_code, unstable_features, unused_crate_dependencies, unused_extern_crates and unused_import_braces, among others. A few are explicitly allowed, such as missing_copy_implementations, missing_debug_implementations, missing_docs, unused_results and variant_size_differences.

The allowances are as informative as the warnings. missing_docs is allowed, which tells you the rustdoc documentation is written for the solutions rather than enforced crate-wide by the compiler, and unused_results is allowed, which is a deliberate choice in a codebase where the point is often to call a function and look at what it returns.

The clippy block is even longer and more opinionated, and it has the same shape: absolute_paths is warned, alloc_instead_of_core is warned, as_pointer_underscore and as_underscore are warned, and a group of arithmetic and casting lints are allowed, among them arithmetic_side_effects, as_conversions and big_endian_bytes. For puzzle code that does index arithmetic and casts between integer widths, allowing those is a practical concession, and the repository is honest about it by listing them rather than silencing the whole group.

The rustdoc block allows private_intra_doc_links, which is what lets the generated documentation link between private items.

The rest of the toolchain follows the same pattern. A rustfmt.toml at the root sets the formatting rules, a justfile holds the two commands you actually need, cargo fmt over the found .rs files followed by cargo clippy over all targets and all features, and a docs target that builds the documentation with private items included and opens it. The README gives the same two commands in long form for people who do not use just.

A repository that lints this aggressively and documents why each exception exists is a better teaching artifact than one that merely passes clippy.

Licence, cadence and the two ways to read this

The licence is MIT, with the file named LICENSE.md at the root of the repository, so the code can be reused, adapted and shipped without copyleft obligations.

The maintenance picture is clean. The last push to the repository was on 2026-10-19, the repository is not archived, and the topics list every year from 2015 to 2025, which is how the project stays discoverable for each year's puzzle release. The package version in the manifest is 2025.12.25, a date rather than a semantic version, which fits a repository whose contents are organised by calendar. There are no GitHub releases, so the crate version and the commit history are the change record, and the CONTRIBUTING.md file is where a contribution is expected to start.

There are two distinct audiences here, and they want different things.

The first is a Rust learner who wants to see idiomatic code for small, well-specified problems. The rustdoc output is built for that, with private items included, so you can read the internal helpers as well as the solution, and every file is a single readable unit rather than a module in a large application.

The second is a systems programmer who wants to see what careful optimisation looks like in a language without a garbage collector pressing on you. The per-solution benchmark, the SIMD flag, the incremental bench profile and the lint list are all addressed to that reader, and the README's framing that each solution is carefully optimized for performance while ensuring the code remains concise, readable, and idiomatic states the tension the repository is deliberately working in.

The thing this repository is not is a general purpose project. There is no library to depend on, the crate is named aoc, and each solution assumes the puzzle's exact input format and the specific structure of that puzzle. Reading it is the use case; running it against your own data is not.

Editorial conclusion

Adopt this repository as a reading list if you want to see how an experienced Rust programmer writes dense, fast, allocation-conscious code for small well-specified problems, since every solution is a single file with rustdoc and a benchmark. Do not adopt it as production code or as a learning resource, because each solution assumes the puzzle's structure and a specific input format rather than a general problem domain. Verify first that your Rust toolchain is new enough, since the manifest asks for edition 2024 and rust-version 1.99, that you place the puzzle inputs where the crate expects them, in input/yearYYYY/dayDD.txt with leading zeroes, and that the timing claims are the ones you care about, because the 461 millisecond figure is for the whole set on an Apple M2 Max while the per-year table shows 2020 alone at 220 milliseconds.

Frequently asked questions

What is maneatingape/advent-of-code-rust?

It is a Rust crate with solutions for every Advent of Code puzzle from 2015 to 2025, described as taking 461 milliseconds to solve all 524 stars. It depends only on the standard library, contains no unsafe code, and every solution is commented and covered by rustdoc.

How do I run the Advent of Code Rust solutions?

Place the puzzle inputs in input/yearYYYY/dayDD.txt with leading zeroes, then run cargo run for everything, cargo run year2023 for one year, or cargo run year2023::day01 for a single day. Add --release for the faster profile, --features simd for the SIMD path, and RUSTFLAGS="-C target-cpu=native" for a binary tuned to your own processor.

How are the benchmarks run in advent-of-code-rust?

With the built-in cargo bench tool, with the same year and day selectors, on an Apple M2 Max according to the README. The per-year table shows 2020 alone at 220 milliseconds against 1 millisecond for 2025, and the README notes that 86 percent of the total time is spent on just 9 solutions.

What lint rules does the advent-of-code-rust crate enable?

The manifest enables a long list of rust lints, including elided_lifetimes_in_paths, explicit_outlives_requirements, unsafe_code, unstable_features, unused_dependencies and trivial_casts, with a set of exceptions such as missing_docs, unused_results and arithmetic_side_effects. The clippy block is configured separately and justfile holds the format and lint commands.

What licence applies to the advent-of-code-rust solutions?

MIT, with the licence text in the LICENSE.md file at the root of the repository. The crate is published under the package name aoc at version 2025.12.25, requires Rust 1.99 and edition 2024, and the repository publishes no GitHub releases.

Official sources

  1. Issues
  2. License: MIT
  3. maneatingape/advent-of-code-rust on GitHub
  4. Project website
  5. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/maneatingape-advent-of-code-rust.svg)](https://hysenlabs.com/projects/maneatingape-advent-of-code-rust)

Was this useful?