summaryrefslogtreecommitdiffstats
path: root/src/day_01.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/day_01.rs')
-rw-r--r--src/day_01.rs103
1 files changed, 103 insertions, 0 deletions
diff --git a/src/day_01.rs b/src/day_01.rs
new file mode 100644
index 0000000..9c0310e
--- /dev/null
+++ b/src/day_01.rs
@@ -0,0 +1,103 @@
+use anyhow::Context;
+
+use crate::{Problem, Solution};
+
+pub struct Day01;
+
+impl Problem for Day01 {
+ const DAY: u8 = 1;
+
+ const INPUT: &'static str = include_str!("../input/day_01.txt");
+}
+
+impl Solution for Day01 {
+ type Answer1 = usize;
+
+ type Answer2 = usize;
+
+ fn part_1(input: &str) -> anyhow::Result<Self::Answer1> {
+ input.trim().split('\n').try_fold(0, |acc, line| {
+ let first = line
+ .chars()
+ .find_map(|c| c.to_digit(10).map(|n| n as usize))
+ .context("Failed to find first number")?;
+
+ let last = line
+ .chars()
+ .rev()
+ .find_map(|c| c.to_digit(10).map(|n| n as usize))
+ .unwrap_or(first);
+
+ Ok(acc + first * 10 + last)
+ })
+ }
+
+ fn part_2(input: &str) -> anyhow::Result<Self::Answer2> {
+ let words = [
+ "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
+ ];
+
+ input.trim().split('\n').try_fold(0, |acc, line| {
+ let mut buf = String::new();
+ let first = line
+ .chars()
+ .find_map(|c| {
+ buf.push(c);
+ words
+ .iter()
+ .enumerate()
+ .find_map(|(n, w)| buf.contains(w).then_some(n))
+ .or_else(|| c.to_digit(10).map(|n| n as usize))
+ })
+ .context("Failed to find first number")?;
+
+ buf.clear();
+ let last = line
+ .chars()
+ .rev()
+ .find_map(|c| {
+ buf.insert(0, c);
+ words
+ .iter()
+ .enumerate()
+ .find_map(|(n, w)| buf.contains(w).then_some(n))
+ .or_else(|| c.to_digit(10).map(|n| n as usize))
+ })
+ .unwrap_or(first);
+
+ Ok(acc + first * 10 + last)
+ })
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_part_1() -> anyhow::Result<()> {
+ let input = indoc::indoc! {"
+ 1abc2
+ pqr3stu8vwx
+ a1b2c3d4e5f
+ treb7uchet
+ "};
+
+ Ok(assert_eq!(142, Day01::part_1(input)?))
+ }
+
+ #[test]
+ fn test_part_2() -> anyhow::Result<()> {
+ let input = indoc::indoc! {"
+ two1nine
+ eightwothree
+ abcone2threexyz
+ xtwone3four
+ 4nineeightseven2
+ zoneight234
+ 7pqrstsixteen
+ "};
+
+ Ok(assert_eq!(281, Day01::part_2(input)?))
+ }
+}