Rust Day 1 Part 2

This commit is contained in:
Tobias Berger 2023-12-01 14:48:01 +01:00
parent 0dffb33f3b
commit de2e672007
Signed by: toby
GPG key ID: 2D05EFAB764D6A88
6 changed files with 64 additions and 14 deletions

2
rust/Cargo.lock generated
View file

@ -4,4 +4,4 @@ version = 3
[[package]] [[package]]
name = "advent-of-code" name = "advent-of-code"
version = "23.1.1" version = "23.1.2"

View file

@ -1,6 +1,6 @@
[package] [package]
name = "advent-of-code" name = "advent-of-code"
version = "23.1.1" version = "23.1.2"
[profile.release] [profile.release]
strip = "symbols" strip = "symbols"

View file

@ -15,7 +15,7 @@ pub(crate) fn part_1(input: &'static str) -> u64 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
const SAMPLE_INPUT: &str = include_str!("sample_input.txt"); const SAMPLE_INPUT: &str = include_str!("sample_input_part_1.txt");
#[test] #[test]
fn test_with_sample_solution() { fn test_with_sample_solution() {

View file

@ -1,24 +1,67 @@
pub(crate) fn part_2(_input: &'static str) -> u64 { const DIGIT_PATTERNS: [&str; 10] = [
todo!("Part 2") "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::<Vec<_>>();
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::<u64>()
.expect("digits are guaranteed to create a valid number")
})
.sum()
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
const SAMPLE_INPUT: &str = include_str!("sample_input.txt"); const SAMPLE_INPUT: &str = include_str!("sample_input_part_2.txt");
#[test] #[test]
fn test_with_sample_solution() { fn test_with_sample_solution() {
assert_eq!( assert_eq!(super::part_2(SAMPLE_INPUT), 281);
super::part_2(SAMPLE_INPUT),
todo!("Add result from example part 2")
);
} }
#[test] #[test]
fn test_with_solution() { fn test_with_solution() {
assert_eq!( assert_eq!(super::part_2(crate::INPUT), 55614);
super::part_2(crate::INPUT),
todo!("Add result for solved part 2")
);
} }
} }

View file

@ -0,0 +1,7 @@
two1nine
eightwothree
abcone2threexyz
xtwone3four
4nineeightseven2
zoneight234
7pqrstsixteen