diff options
Diffstat (limited to 'src/bin/day9.rs')
| -rw-r--r-- | src/bin/day9.rs | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/bin/day9.rs b/src/bin/day9.rs new file mode 100644 index 0000000..f6a116d --- /dev/null +++ b/src/bin/day9.rs @@ -0,0 +1,59 @@ +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::<Vec<_>>(); + + 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); + } +} |
