DEVELOPMENT ENVIRONMENT

~liljamo/aoc2025

7e407c3dd7d76869cca56c095caad7d8207feb40 — Jonni Liljamo 3 days ago
feat: init with day1 part one
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
@@ 1,1 @@
use_flake

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"