advent-of-code 2025.5.0

Solutions to Advent of Code
Documentation
pub struct IdAssigner<const MAX_SIZE: usize, H: Ord + Eq + Copy + Clone> {
    id_map: [H; MAX_SIZE],
    ids: [u16; MAX_SIZE],
    assigned_count: u16,
}

impl<const MAX_SIZE: usize, H: Ord + Eq + Copy + Clone> IdAssigner<MAX_SIZE, H> {
    pub const fn new(default: H) -> Self {
        Self {
            id_map: [default; MAX_SIZE],
            ids: [0; MAX_SIZE],
            assigned_count: 0,
        }
    }

    pub fn id_of(&mut self, name: H) -> Result<u16, String> {
        Ok(
            match self.id_map[0..(self.assigned_count as usize)].binary_search(&name) {
                Ok(idx) => self.ids[idx],
                Err(idx) => {
                    if usize::from(self.assigned_count) == MAX_SIZE {
                        return Err("Too many elements".to_string());
                    }
                    self.id_map
                        .copy_within(idx..self.assigned_count as usize, idx + 1);
                    self.ids
                        .copy_within(idx..self.assigned_count as usize, idx + 1);
                    let new_id = self.assigned_count;
                    self.assigned_count += 1;
                    self.id_map[idx] = name;
                    self.ids[idx] = new_id;
                    new_id
                }
            },
        )
    }

    pub const fn len(&self) -> usize {
        self.assigned_count as usize
    }
}

#[allow(clippy::unwrap_used)]
#[test]
fn test() {
    let mut id_assigner = IdAssigner::<3, u16>::new(1);
    assert_eq!(id_assigner.id_of(1).unwrap(), 0);
    assert_eq!(id_assigner.id_of(1).unwrap(), 0);
    assert_eq!(id_assigner.id_of(2).unwrap(), 1);
    assert_eq!(id_assigner.id_of(2).unwrap(), 1);
    assert_eq!(id_assigner.id_of(1).unwrap(), 0);
    assert_eq!(id_assigner.id_of(2).unwrap(), 1);
    assert_eq!(id_assigner.id_of(30).unwrap(), 2);
    assert!(id_assigner.id_of(40).is_err());
}