diff --git a/Cargo.lock b/Cargo.lock index e152003..faeb77e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,11 +6,72 @@ version = 3 name = "advent_of_code" version = "0.9.2" dependencies = [ + "itertools", "pico-args", + "regex", ] +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + [[package]] name = "pico-args" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" diff --git a/Cargo.toml b/Cargo.toml index ac5c09e..6f8b797 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,4 +14,6 @@ doctest = false test_lib = [] [dependencies] +itertools = "0.12.0" pico-args = "0.5.0" +regex = "1.10.2" diff --git a/src/bin/01.rs b/src/bin/01.rs new file mode 100644 index 0000000..1d72aef --- /dev/null +++ b/src/bin/01.rs @@ -0,0 +1,54 @@ +advent_of_code::solution!(1); + +use itertools::Itertools; + +pub fn part_one(input: &str) -> Option { + let result = input + .lines() + .map(|line| line.chars().filter(|&c| c.is_numeric()).collect::()) + .filter(|line| line.len() >= 1) + .map(|line| { + line.chars().nth(0).unwrap().to_digit(10).unwrap() * 10 + + line.chars().last().unwrap().to_digit(10).unwrap() + }) + .sum(); + Some(result) +} + +// list of written out numbers +const NUMBERS: [&str; 10] = [ + "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", +]; + +#[allow(unused_variables)] +pub fn part_two(input: &str) -> Option { + let res = input + .lines() + // recursively replace all written out numbers with their digits + .map(|line| { + let mut line = line.to_string(); + for (i, number) in NUMBERS.iter().enumerate() { + line = line.replace(number, format!("{}{}{}", number, i, number).as_str()); + } + line + }) + .join("\n"); + part_one(&res) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let result = part_one(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(142)); + } + + #[test] + fn test_part_two() { + let result = part_two(&advent_of_code::template::read_filepath("examples", "01-b")); + assert_eq!(result, Some(281)); + } +} diff --git a/src/template/mod.rs b/src/template/mod.rs index 4403b95..e04faa5 100644 --- a/src/template/mod.rs +++ b/src/template/mod.rs @@ -19,6 +19,16 @@ pub fn read_file(folder: &str, day: Day) -> String { f.expect("could not open input file") } +pub fn read_filepath(folder: &str, filename: &str) -> String { + let cwd = env::current_dir().unwrap(); + let filepath = cwd + .join("data") + .join(folder) + .join(format!("{filename}.txt")); + let f = fs::read_to_string(filepath); + f.expect("could not open input file") +} + /// Creates the constant `DAY` and sets up the input and runner for each part. #[macro_export] macro_rules! solution {