From de2e67200765f24d91be0aa8c2505ec92d9d3894 Mon Sep 17 00:00:00 2001 From: Tobias Berger Date: Fri, 1 Dec 2023 14:48:01 +0100 Subject: [PATCH] Rust Day 1 Part 2 --- rust/Cargo.lock | 2 +- rust/Cargo.toml | 2 +- rust/src/day01/part_1.rs | 2 +- rust/src/day01/part_2.rs | 65 +++++++++++++++---- ...mple_input.txt => sample_input_part_1.txt} | 0 rust/src/day01/sample_input_part_2.txt | 7 ++ 6 files changed, 64 insertions(+), 14 deletions(-) rename rust/src/day01/{sample_input.txt => sample_input_part_1.txt} (100%) create mode 100644 rust/src/day01/sample_input_part_2.txt diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 8efa4c2..8240683 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -4,4 +4,4 @@ version = 3 [[package]] name = "advent-of-code" -version = "23.1.1" +version = "23.1.2" diff --git a/rust/Cargo.toml b/rust/Cargo.toml index d8f3f1b..5f58971 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "advent-of-code" -version = "23.1.1" +version = "23.1.2" [profile.release] strip = "symbols" diff --git a/rust/src/day01/part_1.rs b/rust/src/day01/part_1.rs index 2be6d69..ded542d 100644 --- a/rust/src/day01/part_1.rs +++ b/rust/src/day01/part_1.rs @@ -15,7 +15,7 @@ pub(crate) fn part_1(input: &'static str) -> u64 { #[cfg(test)] mod tests { - const SAMPLE_INPUT: &str = include_str!("sample_input.txt"); + const SAMPLE_INPUT: &str = include_str!("sample_input_part_1.txt"); #[test] fn test_with_sample_solution() { diff --git a/rust/src/day01/part_2.rs b/rust/src/day01/part_2.rs index 928ee24..064eaae 100644 --- a/rust/src/day01/part_2.rs +++ b/rust/src/day01/part_2.rs @@ -1,24 +1,67 @@ -pub(crate) fn part_2(_input: &'static str) -> u64 { - todo!("Part 2") +const DIGIT_PATTERNS: [&str; 10] = [ + "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", +]; + +pub(crate) fn part_2(input: &'static str) -> u64 { + input + .lines() + .map(|line| { + let mut digit_indices = DIGIT_PATTERNS + .iter() + .enumerate() + .map(|(number, pattern)| { + let first_index_digit = line.find(&number.to_string()); + let first_index_str = line.find(pattern); + let first_index = match (first_index_str, first_index_digit) { + (Some(lhs), Some(rhs)) => Some(usize::min(lhs, rhs)), + (None, idx) => idx, + (idx, None) => idx, + }; + + let last_index_digit = line.rfind(&number.to_string()); + let last_index_str = line.rfind(pattern); + let last_index = match (last_index_str, last_index_digit) { + (Some(lhs), Some(rhs)) => Some(usize::max(lhs, rhs)), + (None, idx) => idx, + (idx, None) => idx, + }; + + (number, first_index, last_index) + }) + .collect::>(); + digit_indices.sort_unstable_by(|a, b| match (a.1, b.1) { + (Some(_), None) => std::cmp::Ordering::Less, + (None, Some(_)) => std::cmp::Ordering::Greater, + (None, None) => std::cmp::Ordering::Equal, + (Some(lhs), Some(rhs)) => lhs.cmp(&rhs), + }); + // SAFETY: Slice is guaranteed to be length 10 + let first_digit = unsafe { digit_indices.first().unwrap_unchecked() }.0; + digit_indices.sort_unstable_by(|a, b| match (a.2, b.2) { + (Some(_), None) => std::cmp::Ordering::Less, + (None, Some(_)) => std::cmp::Ordering::Greater, + (None, None) => std::cmp::Ordering::Equal, + (Some(lhs), Some(rhs)) => rhs.cmp(&lhs), + }); + let last_digit = unsafe { digit_indices.first().unwrap_unchecked() }.0; + format!("{first_digit}{last_digit}") + .parse::() + .expect("digits are guaranteed to create a valid number") + }) + .sum() } #[cfg(test)] mod tests { - const SAMPLE_INPUT: &str = include_str!("sample_input.txt"); + const SAMPLE_INPUT: &str = include_str!("sample_input_part_2.txt"); #[test] fn test_with_sample_solution() { - assert_eq!( - super::part_2(SAMPLE_INPUT), - todo!("Add result from example part 2") - ); + assert_eq!(super::part_2(SAMPLE_INPUT), 281); } #[test] fn test_with_solution() { - assert_eq!( - super::part_2(crate::INPUT), - todo!("Add result for solved part 2") - ); + assert_eq!(super::part_2(crate::INPUT), 55614); } } diff --git a/rust/src/day01/sample_input.txt b/rust/src/day01/sample_input_part_1.txt similarity index 100% rename from rust/src/day01/sample_input.txt rename to rust/src/day01/sample_input_part_1.txt diff --git a/rust/src/day01/sample_input_part_2.txt b/rust/src/day01/sample_input_part_2.txt new file mode 100644 index 0000000..41aa89c --- /dev/null +++ b/rust/src/day01/sample_input_part_2.txt @@ -0,0 +1,7 @@ +two1nine +eightwothree +abcone2threexyz +xtwone3four +4nineeightseven2 +zoneight234 +7pqrstsixteen