From db47fe79471ed5b0bf70b94e1ee64065ad2068d5 Mon Sep 17 00:00:00 2001 From: Tyler Hallada Date: Tue, 2 Dec 2025 00:48:11 -0500 Subject: [PATCH] Initial commit: day01 solved --- .gitignore | 4 + Cargo.lock | 381 ++++++++++++++++++++++++++++++++++++++ Cargo.toml | 17 ++ README.md | 15 ++ src/day01/input/test1.txt | 10 + src/day01/mod.rs | 142 ++++++++++++++ src/main.rs | 29 +++ 7 files changed, 598 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 README.md create mode 100644 src/day01/input/test1.txt create mode 100644 src/day01/mod.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b64ffa2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/target + +# Don't commit my personal input.txt files +input.txt diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..42399b0 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,381 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "advent-of-code-2025" +version = "0.1.0" +dependencies = [ + "color-eyre", + "test-log", + "tracing", + "tracing-error", + "tracing-subscriber", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "color-eyre" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5920befb47832a6d61ee3a3a846565cfa39b331331e68a3b1d1116630f2f26d" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8b88ea9df13354b55bc7234ebcce36e6ef896aca2e42a15de9e10edce01b427" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + +[[package]] +name = "indenter" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.177" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "owo-colors" +version = "4.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "proc-macro2" +version = "1.0.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "syn" +version = "2.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "test-log" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d53ac171c92a39e4769491c4b4dde7022c60042254b5fc044ae409d34a24d4" +dependencies = [ + "test-log-macros", + "tracing-subscriber", +] + +[[package]] +name = "test-log-macros" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be35209fd0781c5401458ab66e4f98accf63553e8fae7425503e92fdd319783b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tracing" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..321aef1 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "advent-of-code-2025" +version = "0.1.0" +edition = "2024" + +[dependencies] +color-eyre = "0.6" +tracing = "0.1" +tracing-error = "0.2" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } + +[dev-dependencies] +test-log = {version = "0.2", default-features = false, features = ["trace"]} + +# Improve perf on debug builds: https://docs.rs/color-eyre/latest/color_eyre/#improving-perf-on-debug-builds +[profile.dev.package.backtrace] +opt-level = 3 diff --git a/README.md b/README.md new file mode 100644 index 0000000..27b4230 --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# Advent of Code 2025 + +Rusty edition. + +## Running + +By request of AoC creator, I haven't included the input files (e.g. src/input/day01.txt). Log into the Advent of Code site and save the inputs there to the src/input/ folder. + +Then to run: `cargo run`. + +To run in super-fast prod mode: `cargo run --release`. + +To run with debug logs enabled: `RUST_LOG=debug cargo run`. + +To run the tests against included test input files: `RUST_LOG=debug cargo test -- --no-capture`. diff --git a/src/day01/input/test1.txt b/src/day01/input/test1.txt new file mode 100644 index 0000000..53287c7 --- /dev/null +++ b/src/day01/input/test1.txt @@ -0,0 +1,10 @@ +L68 +L30 +R48 +L5 +R60 +L55 +L1 +L99 +R14 +L82 diff --git a/src/day01/mod.rs b/src/day01/mod.rs new file mode 100644 index 0000000..25db8c2 --- /dev/null +++ b/src/day01/mod.rs @@ -0,0 +1,142 @@ +use std::str::FromStr; + +use color_eyre::{ + Result, + eyre::{Error, eyre}, +}; +use tracing::{debug, info, instrument}; + +const INPUT: &str = include_str!("input/input.txt"); + +const LOCK_SIZE: i32 = 100; +const LOCK_STARTING_POSITION: i32 = 50; + +#[derive(Debug)] +enum Direction { + Left, + Right, +} + +impl FromStr for Direction { + type Err = Error; + + fn from_str(s: &str) -> Result { + match s { + "L" => Ok(Direction::Left), + "R" => Ok(Direction::Right), + _ => Err(eyre!("Invalid direction")), + } + } +} + +#[instrument(skip(input))] +fn part1(input: &str) -> Result { + let mut dial = LOCK_STARTING_POSITION; + let mut visited_zero_count = 0; + for line in input.trim().split('\n') { + let dir: &Direction = &line[0..1].parse()?; + let clicks: i32 = line[1..].parse()?; + match dir { + Direction::Left => { + debug!("Turn left {} clicks", clicks); + dial = (dial - clicks).rem_euclid(LOCK_SIZE); + debug!("Dial is now {}", dial); + } + Direction::Right => { + debug!("Turn right {} clicks", clicks); + dial = (dial + clicks).rem_euclid(LOCK_SIZE); + debug!("Dial is now {}", dial); + } + } + if dial == 0 { + visited_zero_count += 1; + debug!("Visited zero, count is now {}", visited_zero_count); + } + } + Ok(visited_zero_count) +} + +#[instrument(skip(input))] +fn part2(input: &str) -> Result { + let mut dial = LOCK_STARTING_POSITION; + let mut visited_zero_count = 0; + for line in input.trim().split('\n') { + let dir: &Direction = &line[0..1].parse()?; + let clicks: i32 = line[1..].parse()?; + match dir { + Direction::Left => { + debug!("Turn left {} clicks", clicks); + let end = dial - clicks; + let passing_zero_count = + (dial - 1).div_euclid(LOCK_SIZE) - (end - 1).div_euclid(LOCK_SIZE); + if passing_zero_count > 0 { + visited_zero_count += passing_zero_count; + debug!( + "Passed zero {} times, count is now {}", + passing_zero_count, visited_zero_count + ); + } + dial = end.rem_euclid(LOCK_SIZE); + debug!("Dial is now {}", dial); + } + Direction::Right => { + debug!("Turn right {} clicks", clicks); + let end = dial + clicks; + let passing_zero_count = end.div_euclid(LOCK_SIZE); + if passing_zero_count > 0 { + visited_zero_count += passing_zero_count; + debug!( + "Passed zero {} times, count is now {}", + passing_zero_count, visited_zero_count + ); + } + dial = end.rem_euclid(LOCK_SIZE); + debug!("Dial is now {}", dial); + } + } + } + Ok(visited_zero_count) +} + +pub fn solve() -> Result<()> { + info!("Day 1"); + { + let _span = tracing::info_span!("day01").entered(); + let p1 = part1(INPUT)?; + info!("Part 1: {}", p1); + let p2 = part2(INPUT)?; + info!("Part 2: {}", p2); + } + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + use test_log::test; + + const TEST_INPUT1: &str = include_str!("input/test1.txt"); + + #[test] + fn test_parse_direction() { + let result = "L".parse::(); + assert!(matches!(result.unwrap(), Direction::Left)); + } + + #[test] + fn test_invalid_direction() { + let result = "U".parse::(); + let err = result.unwrap_err(); + assert!(err.to_string().contains("Invalid direction")); + } + + #[test] + fn test_part1() { + assert_eq!(part1(TEST_INPUT1).unwrap(), 3); + } + + #[test] + fn test_part2() { + assert_eq!(part2(TEST_INPUT1).unwrap(), 6); + } +} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..03aad64 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,29 @@ +pub mod day01; + +use color_eyre::Result; +use tracing::info; +use tracing_error::ErrorLayer; +use tracing_subscriber::EnvFilter; +use tracing_subscriber::fmt::format::FmtSpan; +use tracing_subscriber::prelude::*; + +fn main() -> Result<()> { + color_eyre::install()?; + + tracing_subscriber::registry() + .with(EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into())) + .with(ErrorLayer::default()) + .with( + tracing_subscriber::fmt::layer() + .with_line_number(true) + .with_span_events(FmtSpan::CLOSE), + ) + .init(); + + info!("Advent of Code 2025"); + { + let _span = tracing::info_span!("aoc").entered(); + day01::solve()?; + } + Ok(()) +}