diff --git a/Cargo.lock b/Cargo.lock index 6e8578a..08bc17f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7,7 +7,18 @@ name = "advent_of_code_2025" version = "0.1.0" dependencies = [ "grid", + "regex", "sanitise-file-name", + "scan_fmt", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", ] [[package]] @@ -16,8 +27,52 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9e2d4c0a8296178d8802098410ca05d86b17a10bb5ab559b3fb404c1f948220" +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[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 = "sanitise-file-name" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d36299972b96b8ae7e8f04ecbf75fb41a27bf3781af00abcf57609774cb911" + +[[package]] +name = "scan_fmt" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b53b0a5db882a8e2fdaae0a43f7b39e7e9082389e978398bdf223a55b581248" +dependencies = [ + "regex", +] diff --git a/Cargo.toml b/Cargo.toml index b379acd..fe0ad45 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,4 +5,6 @@ edition = "2024" [dependencies] grid = "1.0.0" +regex = "1.12.2" sanitise-file-name = "1.0.0" +scan_fmt = "0.2.6" diff --git a/src/lib.rs b/src/lib.rs index 93a4b1a..847a0e4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,5 @@ +#[macro_use] +extern crate scan_fmt; + mod common; pub mod solvers; diff --git a/src/main.rs b/src/main.rs index 4023c30..7495a26 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ use advent_of_code_2025::solvers; fn main() { println!("### Advent of Code 2025 ###\n"); - // SecretEntrance + solvers::run(solvers::secret_entrance::SecretEntrance {}); // GiftShop // Lobby solvers::run(solvers::printing_department::PrintingDepartment {}); @@ -11,4 +11,7 @@ fn main() { // Laboratories solvers::run(solvers::playground::Playground::new(None)); solvers::run(solvers::movie_theater::MovieTheater {}); + // Factory + // Reactor + // ChristmasTreeFarm } diff --git a/src/solvers.rs b/src/solvers.rs index df6d6db..0bf9c0a 100644 --- a/src/solvers.rs +++ b/src/solvers.rs @@ -9,6 +9,7 @@ pub mod cafeteria; pub mod movie_theater; pub mod playground; pub mod printing_department; +pub mod secret_entrance; pub mod trash_compactor; pub trait Solver { diff --git a/src/solvers/secret_entrance.rs b/src/solvers/secret_entrance.rs new file mode 100644 index 0000000..14ef7ad --- /dev/null +++ b/src/solvers/secret_entrance.rs @@ -0,0 +1,42 @@ +use crate::solvers::Solver; +use std::io::BufRead; + +pub struct SecretEntrance {} + +impl SecretEntrance { + const START_POSITION: i32 = 50; + const DIAL_SIZE: i32 = 100; + const COUNT_POSITION: i32 = 0; + const POSITIVE_SIGN_CHAR: char = 'R'; + const NEGATIVE_SIGN_CHAR: char = 'L'; +} + +impl Solver for SecretEntrance { + const PUZZLE_INDEX: u8 = 1; + const PUZZLE_NAME: &'static str = "Secret Entrance"; + + fn process_data(&self, reader: R) -> (u64, u64) { + let mut position = Self::START_POSITION; + let mut count = 0; + let format = format!( + "{{[{}{}]}}{{d}}", + Self::POSITIVE_SIGN_CHAR, + Self::NEGATIVE_SIGN_CHAR + ); + for line in reader.lines().map_while(Result::ok) { + if let Ok((sign, distance)) = scan_fmt!(&line, &format, char, i32) { + position = (position + + if sign == Self::POSITIVE_SIGN_CHAR { + distance + } else { + -distance + }) + .rem_euclid(Self::DIAL_SIZE); + } + if position == Self::COUNT_POSITION { + count = count + 1; + } + } + (count, 0) + } +} diff --git a/tests/examples.rs b/tests/examples.rs index 299a70e..983f370 100644 --- a/tests/examples.rs +++ b/tests/examples.rs @@ -8,6 +8,14 @@ const EXAMPLE_PATHS: &'static [&'static str] = &[ "../../../data/examples", ]; +#[test] +fn secret_entrance() { + assert_eq!( + Ok((3, 0)), + solvers::run_solver(solvers::secret_entrance::SecretEntrance {}, &EXAMPLE_PATHS) + ); +} + #[test] fn printing_department() { assert_eq!( diff --git a/tests/full_data.rs b/tests/full_data.rs index 7cee78b..b005056 100644 --- a/tests/full_data.rs +++ b/tests/full_data.rs @@ -1,5 +1,16 @@ use advent_of_code_2025::*; +#[test] +fn secret_entrance() { + assert_eq!( + Ok((1086, 0)), + solvers::run_solver( + solvers::secret_entrance::SecretEntrance {}, + &solvers::DATA_PATHS + ) + ); +} + #[test] fn printing_department() { assert_eq!(