refactor(day01): more idiomatic, cleaner, optimal (because fun!)
This commit is contained in:
1 file changed
+23
-39
+23
-39
@@ -9,23 +9,18 @@ inventory::submit! {
|
||||
}
|
||||
|
||||
fn first_and_last_digit(s: &str) -> usize {
|
||||
// Find the first character in the string that is an ASCII digit
|
||||
let first = s
|
||||
.chars()
|
||||
.find(|c| c.is_ascii_digit()) // Use find to get an Option containing the first digit character
|
||||
.unwrap() // Unwrap the Option, panicking if no digit is found
|
||||
.to_digit(10) // Convert the character to a digit in base 10
|
||||
.unwrap() as usize; // Convert the digit to a usize
|
||||
// Find the first ASCII digit in the string
|
||||
let first = s.chars().filter_map(|c| c.to_digit(10)).next().unwrap() as usize; // Safe to use unwrap as a digit is always present
|
||||
|
||||
// Find the last character in the string that is an ASCII digit
|
||||
// Find the last ASCII digit in the string
|
||||
let last = s
|
||||
.chars()
|
||||
.rfind(|c| c.is_ascii_digit()) // Use rfind to get an Option containing the last digit character
|
||||
.unwrap() // Unwrap the Option, panicking if no digit is found
|
||||
.to_digit(10) // Convert the character to a digit in base 10
|
||||
.unwrap() as usize; // Convert the digit to a usize
|
||||
.rev() // Reverse the iteration for the last digit
|
||||
.filter_map(|c| c.to_digit(10))
|
||||
.next()
|
||||
.unwrap() as usize; // Safe to use unwrap here as well
|
||||
|
||||
// Return the result
|
||||
// Combine the first and last digits to form a new number
|
||||
first * 10 + last
|
||||
}
|
||||
|
||||
@@ -35,34 +30,23 @@ lazy_static! {
|
||||
}
|
||||
|
||||
fn first_and_last_digit_regex(s: &str) -> usize {
|
||||
// Initialize variables to keep track of the positions and values of the first and last digits.
|
||||
let mut first_start = usize::MAX;
|
||||
let mut last_end = 0;
|
||||
let mut first_digit = String::new();
|
||||
let mut last_digit = String::new();
|
||||
// Find the first digit in the string by testing against each sice from [0..] to [n-1..]
|
||||
let first_digit = s
|
||||
.char_indices()
|
||||
.find_map(|(index, _)| REGEX.find(&s[index..]).map(|mat| mat.as_str().to_string()))
|
||||
.unwrap(); // Safe to use unwrap because a digit is always expected
|
||||
|
||||
// Iterate over each character index in the string.
|
||||
for (index, _) in s.char_indices() {
|
||||
// Check if there is a digit at the current index or beyond.
|
||||
if let Some(mat) = REGEX.find(&s[index..]) {
|
||||
// Calculate the start and end positions of the matched digit.
|
||||
let match_start = index + mat.start();
|
||||
let match_end = index + mat.end();
|
||||
// Iterate from the end of the string, checking each slice for the last match
|
||||
let last_digit = s
|
||||
.char_indices()
|
||||
.rev()
|
||||
.find_map(|(index, _)| {
|
||||
// Check if the slice from this index to the end of the string matches the regex
|
||||
REGEX.find(&s[index..]).map(|mat| mat.as_str().to_string())
|
||||
})
|
||||
.unwrap(); // Safe to use unwrap as a digit is always expected
|
||||
|
||||
// If the current match starts before any previously found digit, it's the new first digit.
|
||||
if match_start < first_start {
|
||||
first_start = match_start;
|
||||
first_digit = mat.as_str().to_string();
|
||||
}
|
||||
// If the current match ends after any previously found digit, it's the new last digit.
|
||||
if match_end > last_end {
|
||||
last_end = match_end;
|
||||
last_digit = mat.as_str().to_string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert the first and last digit strings to their numeric values and return the result
|
||||
// Convert the found digits to numbers and calculate the result
|
||||
digit_value(&first_digit) * 10 + digit_value(&last_digit)
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user