use core::read_data; fn display_filesystem(from: &[u32]) { for (index, value) in from.iter().enumerate() { if index.is_multiple_of(16) { println!(); } if *value < u32::MAX { print!("{value}"); } else { print!("_"); } } println!(); } fn build_filesystem(from: String) -> Vec { let mut fs: Vec = vec![]; let mut file_entry = true; let mut last_file_entry_id = 0; for current_char in from.chars() { let as_digit = current_char.to_digit(10).unwrap_or(0); let (to_push, should_inc) = if file_entry { (last_file_entry_id, true) } else { (u32::MAX, false) }; if should_inc { last_file_entry_id += 1; } for i in 0..as_digit { fs.push(to_push) } file_entry = !file_entry; } fs } fn compact_filesystem(from: &[u32]) -> Vec { let mut fs = from.clone().to_vec(); let mut left = 0; let mut right = fs.len() - 1; let fs_len = fs.len(); while left < right { // find next empty slot from the left while left < fs_len && fs[left] != u32::MAX { left += 1; } // find next data slot from the right while right > 0 && fs[right] == u32::MAX { right -= 1; } if left >= right { break; } // move data left fs[left] = fs[right]; fs[right] = u32::MAX; } fs } fn calculate_checksum(from: &[u32]) -> u64 { let mut checksum: u64 = 0; for (index, &value) in from.iter().enumerate() { if value != u32::MAX { checksum += index as u64 * value as u64; } } checksum } fn main() { // let binding = "2333133121414131402".to_string(); let binding = read_data("2024_09_data.txt"); // build out the filesystem... let mut filesystem = build_filesystem(binding); println!("Filesystem built..."); // display_filesystem(&filesystem); // ...start to compact it... filesystem = compact_filesystem(&filesystem); // ...calculate the checksum // println!("filesystem post compact:"); // display_filesystem(&filesystem); println!("Filesystem compacted..."); println!("Calculated Checksum = {} / Expected 1928", calculate_checksum(&filesystem)); } // 6331212425418