summaryrefslogtreecommitdiff
path: root/2023/src/bin/day_1.rs
diff options
context:
space:
mode:
Diffstat (limited to '2023/src/bin/day_1.rs')
-rw-r--r--2023/src/bin/day_1.rs75
1 files changed, 74 insertions, 1 deletions
diff --git a/2023/src/bin/day_1.rs b/2023/src/bin/day_1.rs
index 227aada..fe3ef1e 100644
--- a/2023/src/bin/day_1.rs
+++ b/2023/src/bin/day_1.rs
@@ -1,8 +1,81 @@
+use nom::{
+ branch::alt,
+ bytes::complete::tag,
+ character::complete::{alpha1, anychar, line_ending, none_of, one_of},
+ combinator::{map, map_opt, map_res, opt, peek, value},
+ multi::{many1, separated_list1},
+ sequence::pair,
+ IResult,
+};
use std::fs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let input = fs::read_to_string("inputs/day_1.txt")?;
- dbg!(input);
+ let parsed = CalibrationInput::parser(&input).unwrap().1;
+ dbg!(parsed.calibration_sum());
Ok(())
}
+
+#[derive(Debug)]
+struct CalibrationInput(Vec<CalibrationValue>);
+
+#[derive(Debug)]
+struct CalibrationValue(u32);
+
+#[derive(Debug)]
+struct CalibrationDigit(u8);
+
+impl CalibrationInput {
+ fn calibration_sum(&self) -> u32 {
+ self.0.iter().map(|d| d.0).sum()
+ }
+
+ fn parser(input: &str) -> IResult<&str, Self> {
+ map(
+ separated_list1(line_ending, CalibrationValue::parser),
+ CalibrationInput,
+ )(input)
+ }
+}
+
+impl CalibrationValue {
+ fn parser(input: &str) -> IResult<&str, Self> {
+ map(
+ many1(pair(
+ opt(peek(CalibrationDigit::parser)), // peek is to not consume the 'one' in 'twone'
+ none_of("\n"), // this is just to advance the input
+ )),
+ |digits| {
+ let digits: Vec<u32> = digits
+ .into_iter()
+ .filter_map(|(d, _)| d.map(|d| d.0 as u32))
+ .collect();
+ CalibrationValue(digits[0] * 10 + digits[digits.len() - 1])
+ },
+ )(input)
+ }
+}
+
+impl CalibrationDigit {
+ fn parser(input: &str) -> IResult<&str, Self> {
+ map(
+ alt((
+ map(one_of("0123456789"), |c| {
+ c.to_string().parse::<u8>().unwrap()
+ }),
+ value(0, tag("zero")),
+ value(1, tag("one")),
+ value(2, tag("two")),
+ value(3, tag("three")),
+ value(4, tag("four")),
+ value(5, tag("five")),
+ value(6, tag("six")),
+ value(7, tag("seven")),
+ value(8, tag("eight")),
+ value(9, tag("nine")),
+ )),
+ CalibrationDigit,
+ )(input)
+ }
+}