2019: day04: part 2
This commit is contained in:
parent
69000f9254
commit
f0f872c199
|
@ -5,6 +5,7 @@ const INPUT: &str = include_str!("../input/day04.txt");
|
||||||
|
|
||||||
pub fn run() -> Result<()> {
|
pub fn run() -> Result<()> {
|
||||||
println!("part 1: {}", part1(INPUT)?);
|
println!("part 1: {}", part1(INPUT)?);
|
||||||
|
println!("part 2: {}", part2(INPUT)?);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -29,6 +30,26 @@ fn part1(input: &str) -> Result<usize> {
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn part2(input: &str) -> Result<usize> {
|
||||||
|
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::<Vec<_>>())
|
||||||
|
.filter(|digits| GroupIter::new(digits).any(|group| group.len() == 2))
|
||||||
|
.filter(|digits| digits.windows(2).all(|window| window[0] <= window[1]))
|
||||||
|
.count();
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
struct DigitsIter {
|
struct DigitsIter {
|
||||||
n: usize,
|
n: usize,
|
||||||
div: usize,
|
div: usize,
|
||||||
|
@ -61,6 +82,37 @@ impl Iterator for DigitsIter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct GroupIter<'a> {
|
||||||
|
digits: &'a [usize],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> GroupIter<'a> {
|
||||||
|
fn new(digits: &'a [usize]) -> Self {
|
||||||
|
GroupIter { digits }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for GroupIter<'a> {
|
||||||
|
type Item = &'a [usize];
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
if self.digits.len() == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let digit = self.digits[0];
|
||||||
|
let mut num = 1;
|
||||||
|
while num < self.digits.len() && self.digits[num] == digit {
|
||||||
|
num += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = &self.digits[..num];
|
||||||
|
self.digits = &self.digits[num..];
|
||||||
|
|
||||||
|
Some(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -76,4 +128,16 @@ mod tests {
|
||||||
fn part1_real() {
|
fn part1_real() {
|
||||||
assert_eq!(part1(INPUT).unwrap(), 1729);
|
assert_eq!(part1(INPUT).unwrap(), 1729);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_provided() {
|
||||||
|
assert_eq!(part2("112233-112233").unwrap(), 1);
|
||||||
|
assert_eq!(part2("123444-123444").unwrap(), 0);
|
||||||
|
assert_eq!(part2("111122-111122").unwrap(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_real() {
|
||||||
|
assert_eq!(part2(INPUT).unwrap(), 1172);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue