use std::collections::VecDeque; static DAY: u8 = 9; fn main() { let input = advent::read_file(DAY); println!("{DAY}a: {}", fs_checksum(&input)); println!("{DAY}b: {}", 0); } fn fs_checksum(map: &str) -> usize { let counts = map.trim_end().chars().map(|x| x.to_digit(10).unwrap() as u8).collect::>(); let mut file_ids = VecDeque::new(); let mut block_sizes = VecDeque::new(); let mut holes = VecDeque::new(); for (id, c) in counts.chunks(2).enumerate() { let file = c[0]; for _ in 0 .. file { file_ids.push_back(id); } block_sizes.push_back(file); if c.len() == 2 { let free = c[1]; holes.push_back(free); } } let mut disk = Vec::new(); disk.reserve(map.len() * 10); while !holes.is_empty() && !file_ids.is_empty() { let blocks_front = block_sizes.pop_front().unwrap() as usize; for _ in 0 .. blocks_front.min(file_ids.len()) { let front = file_ids.pop_front().unwrap(); disk.push(front); } let holes_front = holes.pop_front().unwrap() as usize; for _ in 0 .. holes_front.min(file_ids.len()) { let back = file_ids.pop_back().unwrap(); disk.push(back); } } disk.iter() .enumerate() .map(|(i, block)| i * block) .sum() } #[cfg(test)] mod tests { use super::*; #[test] fn test() { let input = "2333133121414131402"; assert_eq!(fs_checksum(input), 1928); } }