aoc/2024/src/bin/2024_09a.rs

93 lines
2.3 KiB
Rust

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<u32> {
let mut fs: Vec<u32> = 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<u32> {
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