From 3f133059513b1f3f8cda54ae47094a7d3a25a9f2 Mon Sep 17 00:00:00 2001 From: Lars Martens Date: Fri, 29 Nov 2024 20:28:54 +0100 Subject: [PATCH] Prepare AOC --- .gitignore | 5 + Cargo.lock | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 11 ++ README.md | 21 ++++ justfile | 29 +++++ src/lib.rs | 108 ++++++++++++++++++ template.rs | 18 +++ 7 files changed, 505 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 justfile create mode 100644 src/lib.rs create mode 100644 template.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a8d7222 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/target +output/ +.idea/ +.env +input/?? diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..d72c3eb --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,313 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "allocator-api2" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" + +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + +[[package]] +name = "aoc" +version = "0.0.0" +dependencies = [ + "anyhow", + "cached", + "glam", + "itertools", + "rayon", +] + +[[package]] +name = "cached" +version = "0.46.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c8c50262271cdf5abc979a5f76515c234e764fa025d1ba4862c0f0bcda0e95" +dependencies = [ + "ahash", + "cached_proc_macro", + "cached_proc_macro_types", + "hashbrown", + "instant", + "once_cell", + "thiserror", +] + +[[package]] +name = "cached_proc_macro" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c878c71c2821aa2058722038a59a67583a4240524687c6028571c9b395ded61f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cached_proc_macro_types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "glam" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..2c594d7 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "aoc" +version = "0.0.0" +edition = "2021" + +[dependencies] +anyhow = "1.0.75" +cached = "0.46.1" +glam = "0.29.2" +itertools = "0.12.0" +rayon = "1.8.0" diff --git a/README.md b/README.md new file mode 100644 index 0000000..d78a50b --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +# Advent Of Code 2024 + +My solutions for [Advent Of Code 2024](https://adventofcode.com/2024). + +## Usage + +This project uses [`just`](https://github.com/casey/just) . For some commands to work a session token needs to be provided in the `AOC_SESSION` environment variable. The easiest way to set it is to create the file `.env` with `AOC_SESSION=your token` inside in the root of this repository. The token can be received by reading the session cookie from the AOC website. + +Download the puzzle input, create a file for the current day and open it in your $EDITOR: + +```shell +just begin # Prepare the current day +just day=09 begin # Prepare day 9 +``` + +Run: + +```shell +just # Runs the current day +just day=09 # Runs day 9 +``` diff --git a/justfile b/justfile new file mode 100644 index 0000000..925b66b --- /dev/null +++ b/justfile @@ -0,0 +1,29 @@ +set dotenv-load + +day := `date +%d` +dayWithout0 := trim_start_match(day, "0") +year := "2024" +file := "src/bin/" + day + ".rs" + +# Format, lint, and run the program for today. +run: + rustfmt {{file}} + cargo clippy + # Hide warning here because we just ran clippy + RUSTFLAGS=-Awarnings cargo build --release --bin {{day}} + time ./target/release/{{day}} + +# Begin working on todays problem. +# Downloads input, creates template and opens the problem and code. +begin: _folders + cat template.rs | sed -e "s/DAY/{{day}}/g" >> src/bin/{{day}}.rs + rustfmt {{file}} + curl --silent "https://adventofcode.com/{{year}}/day/{{dayWithout0}}/input" -H "Cookie: session=$AOC_SESSION" > "input/{{day}}" + touch input/{{day}}-test + $EDITOR {{file}} + $EDITOR input/{{day}}-test + open "https://adventofcode.com/{{year}}/day/{{dayWithout0}}" + +# Makes sure that folders exist +_folders: + mkdir -p input src/bin diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..9d7408b --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,108 @@ +//! This library contains useful helper functions that may be useful in several problems. + +use std::{ + fmt::{Debug, Display}, + ops::{Div, Mul, Rem}, + str::FromStr, +}; + +/// Parse a whitespace separated list of things. +/// +/// This works with any type that implements [`FromStr`]. +/// +/// Panics on parse error to keep things simple. +/// +/// ```rust +/// # use aoc::parse_ws_separated; +/// let mut nums = parse_ws_separated("1 2 3"); +/// assert_eq!(nums.next(), Some(1)); +/// assert_eq!(nums.next(), Some(2)); +/// assert_eq!(nums.next(), Some(3)); +/// assert_eq!(nums.next(), None); +/// ``` +/// +/// ```rust +/// # use aoc::parse_ws_separated; +/// # use std::net::Ipv4Addr; +/// let mut ips = parse_ws_separated("127.0.0.1 10.0.0.1"); +/// assert_eq!(ips.next(), Some(Ipv4Addr::new(127, 0, 0, 1))); +/// assert_eq!(ips.next(), Some(Ipv4Addr::new(10, 0, 0, 1))); +/// assert_eq!(ips.next(), None); +/// ``` +pub fn parse_ws_separated(s: &str) -> impl DoubleEndedIterator + '_ +where + T: FromStr, + ::Err: Debug, +{ + s.split_ascii_whitespace().map(|s| s.parse().unwrap()) +} + +/// Concatenate two things. +/// +/// Panics if the concatenation is not be parseable to keep things simple. +/// +/// ```rust +/// # use aoc::concat; +/// assert_eq!(concat(123, 456), 123456); +/// ``` +pub fn concat(a: T, b: T) -> T +where + T: Display + FromStr, + ::Err: Debug, +{ + format!("{a}{b}").parse().unwrap() +} + +/// Return the greatest common divisor. +/// +/// +/// +/// ```rust +/// # use aoc::gcd; +/// assert_eq!(gcd(12, 8), 4); +/// # assert_eq!(gcd(105, 252), 21); +/// # assert_eq!(gcd(252, 105), 21); +/// ``` +pub fn gcd(mut a: T, mut b: T) -> T +where + T: PartialEq + Default + Rem + Copy, +{ + let zero = T::default(); + while b != zero { + (a, b) = (b, a % b); + } + + a +} + +/// Return the least common multiple. +/// +/// +/// +/// ```rust +/// # use aoc::lcm; +/// assert_eq!(lcm(4, 6), 12); +/// # assert_eq!(lcm(6, 4), 12); +/// ``` +pub fn lcm(a: T, b: T) -> T +where + T: PartialEq + Default + Rem + Div + Mul + Copy, +{ + let gcd = gcd(a, b); + a / gcd * b +} + +/// Given a function and a name of a file in the `input` directory, +/// assert that the function applied to the contents of the file returns the expected result. +#[macro_export] +macro_rules! assert_example { + ($solve:ident, $file:expr, $expected:expr) => { + assert_eq!( + $solve(include_str!(concat!("../../input/", $file))), + $expected, + "{}, {}", + stringify!($solve), + $file, + ) + }; +} diff --git a/template.rs b/template.rs new file mode 100644 index 0000000..6146c4c --- /dev/null +++ b/template.rs @@ -0,0 +1,18 @@ +use aoc::*; + +const INPUT: &str = include_str!("../../input/DAY"); + +fn main() { + assert_example!(part1, "DAY-test", 0); + println!("Part 1: {}", part1(INPUT)); + assert_example!(part2, "DAY-test", 0); + println!("Part 2: {}", part2(INPUT)); +} + +fn part1(input: &str) -> usize { + 0 +} + +fn part2(input: &str) -> usize { + 0 +}