50 lines
1.4 KiB
Rust
50 lines
1.4 KiB
Rust
const ALLOW_SEPARATION: bool = false;
|
|
|
|
pub fn day9() {
|
|
let mut regions: Vec<(Option<usize>, usize)> = crate::input(9)
|
|
.chars()
|
|
.filter_map(|c| c.to_string().parse::<usize>().ok())
|
|
.enumerate()
|
|
.flat_map(|(i, size)| {
|
|
let file_id = (i % 2 == 0).then_some(i / 2);
|
|
if ALLOW_SEPARATION {
|
|
vec![(file_id, 1); size]
|
|
} else {
|
|
vec![(file_id, size)]
|
|
}
|
|
})
|
|
.collect();
|
|
|
|
for i in (0..regions.len()).rev() {
|
|
let (Some(_), file_size) = regions[i] else {
|
|
continue;
|
|
};
|
|
let Some(slot_index) = regions[..i]
|
|
.iter()
|
|
.position(|&(slot, slot_size)| slot.is_none() && slot_size >= file_size)
|
|
else {
|
|
continue;
|
|
};
|
|
let slot_size = regions[slot_index].1;
|
|
|
|
regions[slot_index] = regions[i];
|
|
regions[i] = (None, file_size);
|
|
if slot_size > file_size {
|
|
regions.insert(slot_index + 1, (None, slot_size - file_size));
|
|
}
|
|
}
|
|
|
|
let disk: Vec<Option<usize>> = regions
|
|
.into_iter()
|
|
.flat_map(|(file_id, size)| vec![file_id; size])
|
|
.collect();
|
|
|
|
let checksum: usize = disk
|
|
.into_iter()
|
|
.enumerate()
|
|
.filter_map(|(i, f)| Some(i * f? as usize))
|
|
.sum();
|
|
|
|
println!("Checksum: {}", checksum);
|
|
}
|