diff --git a/aoc2019/input/day04.txt b/aoc2019/input/day04.txt new file mode 100644 index 0000000..6c18726 --- /dev/null +++ b/aoc2019/input/day04.txt @@ -0,0 +1 @@ +153517-630395 diff --git a/aoc2019/src/day04.rs b/aoc2019/src/day04.rs new file mode 100644 index 0000000..0ecc99b --- /dev/null +++ b/aoc2019/src/day04.rs @@ -0,0 +1,79 @@ +use aoc::err; +use aoc::Result; + +const INPUT: &str = include_str!("../input/day04.txt"); + +pub fn run() -> Result<()> { + println!("part 1: {}", part1(INPUT)?); + + Ok(()) +} + +fn part1(input: &str) -> Result { + let mut range = input.trim_end().split('-'); + let begin: usize = range + .next() + .ok_or_else(|| err!("invalid input: {}", input))? + .parse()?; + let end: usize = range + .next() + .ok_or_else(|| err!("invalid input: {}", input))? + .parse()?; + + let res = (begin..=end) + .map(|n| DigitsIter::new(n).collect::>()) + .filter(|digits| digits.windows(2).any(|window| window[0] == window[1])) + .filter(|digits| digits.windows(2).all(|window| window[0] <= window[1])) + .count(); + + Ok(res) +} + +struct DigitsIter { + n: usize, + div: usize, +} + +impl DigitsIter { + fn new(n: usize) -> Self { + let mut div = 1; + while n >= div * 10 { + div *= 10; + } + + DigitsIter { n, div } + } +} + +impl Iterator for DigitsIter { + type Item = usize; + + fn next(&mut self) -> Option { + match self.div { + 0 => None, + _ => { + let res = self.n / self.div; + self.n %= self.div; + self.div /= 10; + Some(res) + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn part1_provided() { + assert_eq!(part1("111111-111111").unwrap(), 1); + assert_eq!(part1("223450-223450").unwrap(), 0); + assert_eq!(part1("123789-123789").unwrap(), 0); + } + + #[test] + fn part1_real() { + assert_eq!(part1(INPUT).unwrap(), 1729); + } +} diff --git a/aoc2019/src/lib.rs b/aoc2019/src/lib.rs index 89345b1..e051fbd 100644 --- a/aoc2019/src/lib.rs +++ b/aoc2019/src/lib.rs @@ -1,3 +1,4 @@ pub mod day01; pub mod day02; pub mod day03; +pub mod day04; diff --git a/aoc2019/src/main.rs b/aoc2019/src/main.rs index 3685bc6..4fa0ab4 100644 --- a/aoc2019/src/main.rs +++ b/aoc2019/src/main.rs @@ -3,9 +3,10 @@ use aoc::Result; use aoc2019::day01; use aoc2019::day02; use aoc2019::day03; +use aoc2019::day04; fn main() -> Result<()> { - let days: &[fn() -> Result<()>] = &[day01::run, day02::run, day03::run]; + let days: &[fn() -> Result<()>] = &[day01::run, day02::run, day03::run, day04::run]; aoc::run(days) }