2023 day1/rust: add solution
This commit is contained in:
parent
609762cf0b
commit
eb9e0e3ed4
4 changed files with 82 additions and 0 deletions
9
2023/day1/rust/Cargo.toml
Normal file
9
2023/day1/rust/Cargo.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "rust_2023_01"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
aoc = { path = "../../../common/rust" }
|
65
2023/day1/rust/src/main.rs
Normal file
65
2023/day1/rust/src/main.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
#![warn(clippy::pedantic)]
|
||||
|
||||
use std::io::stdin;
|
||||
|
||||
const DIGIT_WORDS: [&str; 9] = [
|
||||
"one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
|
||||
];
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum Direction {
|
||||
Forward,
|
||||
Backward,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum DigitMode {
|
||||
NumeralsOnly,
|
||||
NumeralsAndWords,
|
||||
}
|
||||
|
||||
fn locate_digit(s: &str, direction: Direction, mode: DigitMode) -> usize {
|
||||
let locate_digit = |n: usize, word| {
|
||||
let locate = match direction {
|
||||
Direction::Forward => str::find,
|
||||
Direction::Backward => str::rfind,
|
||||
};
|
||||
let numeral = n.to_string();
|
||||
let numeral_pos = locate(s, numeral.as_str());
|
||||
let word_pos = if mode == DigitMode::NumeralsAndWords {
|
||||
locate(s, word)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
[numeral_pos, word_pos].into_iter().flatten()
|
||||
};
|
||||
|
||||
let positions = DIGIT_WORDS.into_iter().enumerate().flat_map(|(n, word)| {
|
||||
let n = n + 1;
|
||||
locate_digit(n, word).map(move |pos| (pos, n))
|
||||
});
|
||||
|
||||
match direction {
|
||||
Direction::Forward => positions.min_by_key(|(pos, _)| *pos),
|
||||
Direction::Backward => positions.max_by_key(|(pos, _)| *pos),
|
||||
}
|
||||
.unwrap()
|
||||
.1
|
||||
}
|
||||
|
||||
fn get_number(s: &str, mode: DigitMode) -> usize {
|
||||
let first = locate_digit(s, Direction::Forward, mode);
|
||||
let last = locate_digit(s, Direction::Backward, mode);
|
||||
first * 10 + last
|
||||
}
|
||||
|
||||
fn get_sum(lines: &[String], mode: DigitMode) -> usize {
|
||||
lines.iter().map(|l| get_number(l, mode)).sum()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let lines: Vec<_> = stdin().lines().map(Result::unwrap).collect();
|
||||
|
||||
println!("{}", get_sum(&lines, DigitMode::NumeralsOnly));
|
||||
println!("{}", get_sum(&lines, DigitMode::NumeralsAndWords));
|
||||
}
|
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -628,6 +628,13 @@ dependencies = [
|
|||
"strum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust_2023_01"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"aoc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.11"
|
||||
|
|
|
@ -27,4 +27,5 @@ members = [
|
|||
"2022/day14/rust",
|
||||
"2022/day15/rust",
|
||||
"2022/day18/rust",
|
||||
"2023/day1/rust",
|
||||
]
|
||||
|
|
Loading…
Reference in a new issue