A => .cargo/config.toml +3 -0
@@ 1,3 @@
+[target.x86_64-unknown-linux-gnu]
+linker = "clang"
+rustflags = ["-C", "link-arg=-fuse-ld=mold"]
A => .envrc +1 -0
A => .gitignore +4 -0
@@ 1,4 @@
+/.direnv/
+/input/
+/target/
+/.pre-commit-config.yaml
A => Cargo.lock +23 -0
@@ 1,23 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "common"
+version = "0.1.0"
+dependencies = [
+ "sc",
+]
+
+[[package]]
+name = "day1"
+version = "0.1.0"
+dependencies = [
+ "common",
+]
+
+[[package]]
+name = "sc"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "010e18bd3bfd1d45a7e666b236c78720df0d9a7698ebaa9c1c559961eb60a38b"
A => Cargo.toml +3 -0
@@ 1,3 @@
+[workspace]
+resolver = "3"
+members = ["crates/common", "crates/day1"]
A => crates/common/Cargo.toml +7 -0
@@ 1,7 @@
+[package]
+name = "common"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+sc = "0.2"
A => crates/common/src/lib.rs +68 -0
@@ 1,68 @@
+use core::fmt::{self, Write};
+
+use sc::syscall;
+
+const STDIN: i32 = 0;
+const STDOUT: i32 = 1;
+
+pub fn write(msg: &str) {
+ unsafe {
+ syscall!(WRITE, STDOUT, msg.as_ptr(), msg.len());
+ }
+}
+
+pub fn read(buf_ptr: *const u8, buf_len: usize) {
+ unsafe {
+ syscall!(READ, STDIN, buf_ptr, buf_len);
+ }
+}
+
+pub struct Format<'a> {
+ buf: &'a mut [u8],
+ len: usize,
+}
+
+impl<'a> Format<'a> {
+ pub fn new(buf: &'a mut [u8]) -> Self {
+ Self { buf, len: 0 }
+ }
+}
+
+impl<'a> fmt::Write for Format<'a> {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ if self.len > self.buf.len() {
+ write("1");
+ return Err(fmt::Error);
+ }
+ let remaining_buf = &mut self.buf[self.len..];
+ let bytes = s.as_bytes();
+ let write_num = core::cmp::min(bytes.len(), remaining_buf.len());
+ remaining_buf[..write_num].copy_from_slice(&bytes[..write_num]);
+ self.len += bytes.len();
+ if write_num < bytes.len() {
+ write("2");
+ return Err(fmt::Error);
+ }
+
+ Ok(())
+ }
+}
+
+pub fn format(buf: &mut [u8], args: fmt::Arguments<'_>) {
+ let mut f = Format::new(buf);
+ f.write_fmt(args).unwrap();
+}
+
+pub fn format_str<'a>(buf: &'a mut [u8], args: fmt::Arguments<'_>) -> &'a str {
+ let mut f = Format::new(buf);
+ f.write_fmt(args).unwrap();
+ str::from_utf8(buf).unwrap()
+}
+
+#[macro_export]
+macro_rules! print {
+ ($len:expr, $($args:tt)*) => {
+ let mut buf = [0u8; $len];
+ common::write(common::format_str(&mut buf, core::format_args!($($args)*)));
+ };
+}
A => crates/day1/Cargo.toml +7 -0
@@ 1,7 @@
+[package]
+name = "day1"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
+common = { path = "../common" }
A => crates/day1/src/main.rs +69 -0
@@ 1,69 @@
+#![no_std]
+
+use common::{print, read};
+
+fn main() {
+ let buf = [0u8; 65000];
+ read(buf.as_ptr(), buf.len());
+ let input = str::from_utf8(&buf).unwrap();
+ let result_one = one(input);
+ let result_two = two(input);
+ print!(32, "one: {}\ntwo: {}\n", result_one, result_two);
+}
+
+fn one(input: &str) -> u16 {
+ let mut zeros: u16 = 0;
+ let mut pos: i16 = 50;
+ for ins in input.split("\n") {
+ // Last entry is all unused bytes.
+ if ins.len() > 10 {
+ continue;
+ }
+
+ let (direction, amount_s) = ins.split_at(1);
+ let amount = amount_s.parse::<i16>().unwrap();
+
+ match direction {
+ "R" => {
+ pos += amount;
+ while pos > 99 {
+ pos -= 100;
+ }
+ }
+ "L" => {
+ pos -= amount;
+ while pos < 0 {
+ pos += 100;
+ }
+ }
+ _ => unreachable!(),
+ }
+
+ if pos == 0 {
+ zeros += 1;
+ }
+ }
+
+ zeros
+}
+
+#[cfg(test)]
+mod test {
+ use super::*;
+
+ const EXAMPLE_INPUT: &str = r#"L68
+L30
+R48
+L5
+R60
+L55
+L1
+L99
+R14
+L82"#;
+
+ #[test]
+ fn example() {
+ assert_eq!(one(EXAMPLE_INPUT), 3);
+ }
+}
A => flake.lock +170 -0
@@ 1,170 @@
+{
+ "nodes": {
+ "flake-compat": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1761588595,
+ "narHash": "sha256-XKUZz9zewJNUj46b4AJdiRZJAvSZ0Dqj2BNfXvFlJC4=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "f387cd2afec9419c8ee37694406ca490c3f34ee5",
+ "type": "github"
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-parts": {
+ "inputs": {
+ "nixpkgs-lib": "nixpkgs-lib"
+ },
+ "locked": {
+ "lastModified": 1763759067,
+ "narHash": "sha256-LlLt2Jo/gMNYAwOgdRQBrsRoOz7BPRkzvNaI/fzXi2Q=",
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "rev": "2cccadc7357c0ba201788ae99c4dfa90728ef5e0",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "flake-parts",
+ "type": "github"
+ }
+ },
+ "gitignore": {
+ "inputs": {
+ "nixpkgs": [
+ "pre-commit-hooks",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1709087332,
+ "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
+ "type": "github"
+ },
+ "original": {
+ "owner": "hercules-ci",
+ "repo": "gitignore.nix",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1764557259,
+ "narHash": "sha256-fhD/QUtJ0HKs3oLvfnD+/SrBV5Y7YEkCYnDjOVUjLys=",
+ "owner": "nixos",
+ "repo": "nixpkgs",
+ "rev": "0d70460758949966e91d9ecb823b821f963cefbb",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nixos",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs-lib": {
+ "locked": {
+ "lastModified": 1761765539,
+ "narHash": "sha256-b0yj6kfvO8ApcSE+QmA6mUfu8IYG6/uU28OFn4PaC8M=",
+ "owner": "nix-community",
+ "repo": "nixpkgs.lib",
+ "rev": "719359f4562934ae99f5443f20aa06c2ffff91fc",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-community",
+ "repo": "nixpkgs.lib",
+ "type": "github"
+ }
+ },
+ "nixpkgs_2": {
+ "locked": {
+ "lastModified": 1759417375,
+ "narHash": "sha256-O7eHcgkQXJNygY6AypkF9tFhsoDQjpNEojw3eFs73Ow=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "dc704e6102e76aad573f63b74c742cd96f8f1e6c",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "nixpkgs_3": {
+ "locked": {
+ "lastModified": 1744536153,
+ "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "pre-commit-hooks": {
+ "inputs": {
+ "flake-compat": "flake-compat",
+ "gitignore": "gitignore",
+ "nixpkgs": "nixpkgs_2"
+ },
+ "locked": {
+ "lastModified": 1763988335,
+ "narHash": "sha256-QlcnByMc8KBjpU37rbq5iP7Cp97HvjRP0ucfdh+M4Qc=",
+ "owner": "cachix",
+ "repo": "git-hooks.nix",
+ "rev": "50b9238891e388c9fdc6a5c49e49c42533a1b5ce",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cachix",
+ "repo": "git-hooks.nix",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "flake-parts": "flake-parts",
+ "nixpkgs": "nixpkgs",
+ "pre-commit-hooks": "pre-commit-hooks",
+ "rust-overlay": "rust-overlay"
+ }
+ },
+ "rust-overlay": {
+ "inputs": {
+ "nixpkgs": "nixpkgs_3"
+ },
+ "locked": {
+ "lastModified": 1764557621,
+ "narHash": "sha256-kX5PoY8hQZ80+amMQgOO9t8Tc1JZ70gYRnzaVD4AA+o=",
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "rev": "93316876c2229460a5d6f5f052766cc4cef538ce",
+ "type": "github"
+ },
+ "original": {
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
A => flake.nix +72 -0
@@ 1,72 @@
+{
+ inputs = {
+ nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
+ flake-parts.url = "github:hercules-ci/flake-parts";
+ pre-commit-hooks.url = "github:cachix/git-hooks.nix";
+ rust-overlay.url = "github:oxalica/rust-overlay";
+ };
+
+ outputs = inputs @ {self, ...}:
+ inputs.flake-parts.lib.mkFlake {inherit inputs;} {
+ systems = ["x86_64-linux"];
+ perSystem = {
+ pkgs,
+ system,
+ ...
+ }: let
+ toolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
+ in {
+ _module.args.pkgs = import inputs.nixpkgs {
+ inherit system;
+ overlays = [inputs.rust-overlay.overlays.default];
+ };
+
+ checks.pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
+ src = ./.;
+ hooks = {
+ # Nix formatting
+ alejandra.enable = true;
+
+ # Toml formatting
+ taplo.enable = true;
+
+ # Rust formatting and linting
+ rustfmt = {
+ enable = true;
+ packageOverrides = {
+ cargo = toolchain;
+ rustfmt = toolchain;
+ };
+ };
+ clippy = {
+ enable = true;
+ packageOverrides = {
+ cargo = toolchain;
+ clippy = toolchain;
+ };
+ settings = {
+ denyWarnings = true;
+ };
+ };
+ };
+ };
+
+ devShells.default = pkgs.mkShell {
+ buildInputs = with pkgs;
+ [
+ clang
+ mold
+
+ just
+ ]
+ ++ [
+ toolchain
+ self.checks.${system}.pre-commit-check.enabledPackages
+ ];
+ shellHook = ''
+ ${self.checks.${system}.pre-commit-check.shellHook}
+ '';
+ };
+ };
+ };
+}
A => justfile +8 -0
@@ 1,8 @@
+_default:
+ just --list
+
+init day:
+ cargo init crates/day{{day}}
+
+solve day:
+ cat input/day{{day}}.txt | cargo run day{{day}} --
A => rust-toolchain.toml +2 -0
@@ 1,2 @@
+[toolchain]
+channel = "1.91"