advent-of-code 2025.5.0

Solutions to Advent of Code
Documentation
pub struct TripleWindowIterator<I, T>
where
    I: Iterator<Item = T>,
    T: Copy,
{
    iterator: I,
    first_item: Option<T>,
    second_item: Option<T>,
}

impl<I, T> Iterator for TripleWindowIterator<I, T>
where
    I: Iterator<Item = T>,
    T: Copy,
{
    type Item = (T, T, T);

    fn next(&mut self) -> Option<Self::Item> {
        loop {
            match self.first_item {
                Some(first_item) => match self.second_item {
                    Some(second_item) => {
                        let next_element = self.iterator.next()?;
                        self.first_item = Some(second_item);
                        self.second_item = Some(next_element);
                        return Some((first_item, second_item, next_element));
                    }
                    None => {
                        self.second_item = Some(self.iterator.next()?);
                    }
                },
                None => {
                    self.first_item = Some(self.iterator.next()?);
                }
            }
        }
    }
}

impl<I, T> ExactSizeIterator for TripleWindowIterator<I, T>
where
    I: ExactSizeIterator<Item = T>,
    T: Copy,
{
    fn len(&self) -> usize {
        let result = usize::from(self.first_item.is_some())
            + usize::from(self.second_item.is_some())
            + self.iterator.len();
        if result > 0 { result - 2 } else { result }
    }
}

pub trait TripleWindowIteratorExt: Iterator {
    fn triple_windows(self) -> TripleWindowIterator<Self, Self::Item>
    where
        Self::Item: Copy,
        Self: Sized,
    {
        TripleWindowIterator {
            iterator: self,
            first_item: None,
            second_item: None,
        }
    }
}

impl<I: Iterator> TripleWindowIteratorExt for I {}

#[test]
fn test() {
    let a = [1, 2, 3, 4, 5, 6];
    let mut it = a.into_iter().triple_windows();
    assert_eq!(it.len(), 4);
    assert_eq!(it.next(), Some((1, 2, 3)));
    assert_eq!(it.len(), 3);
    assert_eq!(it.next(), Some((2, 3, 4)));
    assert_eq!(it.len(), 2);
    assert_eq!(it.next(), Some((3, 4, 5)));
    assert_eq!(it.len(), 1);
    assert_eq!(it.next(), Some((4, 5, 6)));
    assert_eq!(it.len(), 0);
    assert_eq!(it.next(), None);
    assert_eq!(it.len(), 0);
}