2024: day 9: part 1 and 2: rust
This commit is contained in:
parent
7901645c55
commit
2ad18dce23
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "day09"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
|
@ -0,0 +1,116 @@
|
||||||
|
fn descriptor_to_disk(descriptor: String) -> Vec<i64> {
|
||||||
|
let mut file_index: i64 = 0;
|
||||||
|
let mut disk: Vec<i64> = Vec::new();
|
||||||
|
for (i, item) in descriptor.chars().enumerate() {
|
||||||
|
let item = item.to_digit(10);
|
||||||
|
if let Some(item) = item {
|
||||||
|
// If we are on a file
|
||||||
|
if i % 2 == 0 {
|
||||||
|
for _ in 0..item {
|
||||||
|
disk.push(file_index);
|
||||||
|
}
|
||||||
|
file_index += 1;
|
||||||
|
} else {
|
||||||
|
for _ in 0..item {
|
||||||
|
disk.push(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
disk
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fragment(disk: &Vec<i64>) -> Vec<i64> {
|
||||||
|
let mut disk = disk.clone();
|
||||||
|
let mut i: usize = 0;
|
||||||
|
let mut j: usize = disk.len() - 1;
|
||||||
|
while i < j {
|
||||||
|
// If there is an empty slot
|
||||||
|
if disk[i] == -1 {
|
||||||
|
if disk[j] == -1 {
|
||||||
|
j -= 1;
|
||||||
|
} else {
|
||||||
|
// Swap an empty slot with an occupied slot
|
||||||
|
let tmp = disk[i];
|
||||||
|
disk[i] = disk[j];
|
||||||
|
disk[j] = tmp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
disk
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn move_file(disk: &mut Vec<i64>, file_index: i64, file_length: usize, previous_start: usize, next_start: usize) {
|
||||||
|
for i in 0..file_length {
|
||||||
|
disk[previous_start + i] = -1;
|
||||||
|
}
|
||||||
|
for i in 0..file_length {
|
||||||
|
disk[next_start + i] = file_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn contiguous_empty(disk: &Vec<i64>, start_index: usize, file_length: usize) -> bool {
|
||||||
|
for i in start_index..(start_index + file_length) {
|
||||||
|
if i > disk.len() || disk[i] != -1 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_position(disk: &Vec<i64>, start_index: usize, file_length: usize) -> Option<usize> {
|
||||||
|
for i in 0..start_index {
|
||||||
|
if disk[i] == -1 && contiguous_empty(disk, i, file_length) {
|
||||||
|
return Some(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn defragment(disk: &Vec<i64>) -> Vec<i64> {
|
||||||
|
let mut disk = disk.clone();
|
||||||
|
let max_file_index = disk.iter().cloned().fold(0, i64::max);
|
||||||
|
let mut file_index = max_file_index;
|
||||||
|
while file_index >= 0 {
|
||||||
|
let mut start_index: usize = 0;
|
||||||
|
while disk[start_index] != file_index {
|
||||||
|
start_index += 1;
|
||||||
|
}
|
||||||
|
let mut file_length: usize = 0;
|
||||||
|
while start_index + file_length < disk.len() && disk[start_index + file_length] == file_index {
|
||||||
|
file_length += 1;
|
||||||
|
}
|
||||||
|
if let Some(next_index) = find_position(&disk, start_index, file_length) {
|
||||||
|
move_file(&mut disk, file_index, file_length, start_index, next_index);
|
||||||
|
}
|
||||||
|
file_index -= 1;
|
||||||
|
}
|
||||||
|
disk
|
||||||
|
}
|
||||||
|
|
||||||
|
fn checksum(disk: &Vec<i64>) -> i64 {
|
||||||
|
let mut sum = 0;
|
||||||
|
for (i, item) in disk.iter().enumerate() {
|
||||||
|
if *item != -1 {
|
||||||
|
sum += i as i64 * (*item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sum
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> std::io::Result<()> {
|
||||||
|
let disk_descriptor: String = std::io::read_to_string(std::io::stdin())?;
|
||||||
|
let disk = descriptor_to_disk(disk_descriptor);
|
||||||
|
// Part 1.
|
||||||
|
let disk1 = fragment(&disk);
|
||||||
|
let check1 = checksum(&disk1);
|
||||||
|
println!("{}", check1);
|
||||||
|
// Part 2
|
||||||
|
let disk2 = defragment(&disk);
|
||||||
|
let check2 = checksum(&disk2);
|
||||||
|
println!("{}", check2);
|
||||||
|
Ok(())
|
||||||
|
}
|
Loading…
Reference in New Issue