solved day 9 and deduplicated some code
Dieser Commit ist enthalten in:
Ursprung
9d807bbc75
Commit
1ff9286276
3 geänderte Dateien mit 169 neuen und 26 gelöschten Zeilen
1
examples/2024/09.txt
Normale Datei
1
examples/2024/09.txt
Normale Datei
|
@ -0,0 +1 @@
|
||||||
|
2333133121414131402
|
149
src/bin/2024/09.rs
Normale Datei
149
src/bin/2024/09.rs
Normale Datei
|
@ -0,0 +1,149 @@
|
||||||
|
use advent_of_code::strings::char_to_num;
|
||||||
|
#[allow(unused_imports)]
|
||||||
|
use advent_of_code_macros::{include_data, include_example};
|
||||||
|
|
||||||
|
include_data!(DATA 2024 09);
|
||||||
|
|
||||||
|
type Disk = Vec<Option<u64>>;
|
||||||
|
|
||||||
|
fn print_disk(disk: Disk, columns: bool) {
|
||||||
|
if columns {
|
||||||
|
for i in 1..=disk.len() {
|
||||||
|
print!("{:02}", i);
|
||||||
|
}
|
||||||
|
println!()
|
||||||
|
}
|
||||||
|
for block in disk {
|
||||||
|
match block {
|
||||||
|
None => print!(" "),
|
||||||
|
Some(x) => print!("{} ", x),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println!(";")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn layout_to_disk(layout: Vec<u64>) -> Disk {
|
||||||
|
let mut disk = Vec::new();
|
||||||
|
let mut space = false;
|
||||||
|
let mut block;
|
||||||
|
let mut blockid = 0;
|
||||||
|
for blocksize in layout {
|
||||||
|
block = if space {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
blockid += 1;
|
||||||
|
Some(blockid - 1)
|
||||||
|
};
|
||||||
|
for _ in 0..blocksize {
|
||||||
|
disk.push(block);
|
||||||
|
}
|
||||||
|
space = !space;
|
||||||
|
}
|
||||||
|
disk
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_checksum(disk: Disk) -> u64 {
|
||||||
|
let iter = disk.iter();
|
||||||
|
let mut checksum = 0;
|
||||||
|
let mut position = 0;
|
||||||
|
for block in iter {
|
||||||
|
if block.is_some() {
|
||||||
|
checksum += block.unwrap() * position;
|
||||||
|
}
|
||||||
|
position += 1;
|
||||||
|
}
|
||||||
|
checksum
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compact_blocks(disk: &mut Disk) {
|
||||||
|
let mut lastblock = disk.len() - 1;
|
||||||
|
let mut block = 0;
|
||||||
|
loop {
|
||||||
|
if disk[block].is_none() {
|
||||||
|
if disk[lastblock].is_some() {
|
||||||
|
disk[block] = disk[lastblock];
|
||||||
|
disk[lastblock] = None;
|
||||||
|
block += 1;
|
||||||
|
}
|
||||||
|
lastblock -= 1;
|
||||||
|
} else {
|
||||||
|
block += 1
|
||||||
|
}
|
||||||
|
if lastblock <= block {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn move_blocks(disk: &mut Disk, file_start: usize, length: usize, new_start: usize) {
|
||||||
|
for i in 0..=length {
|
||||||
|
disk[new_start + i] = disk[file_start - length + i];
|
||||||
|
disk[file_start - length + i] = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compact_files(disk: &mut Disk) {
|
||||||
|
let mut length;
|
||||||
|
let mut fileid;
|
||||||
|
let mut spaceblock;
|
||||||
|
let mut block;
|
||||||
|
let mut endblock = disk.len();
|
||||||
|
//print_disk(disk.clone(), true);
|
||||||
|
loop {
|
||||||
|
endblock -= 1;
|
||||||
|
if endblock == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if disk[endblock].is_some() {
|
||||||
|
fileid = disk[endblock];
|
||||||
|
length = 0;
|
||||||
|
while disk[endblock - length] == fileid {
|
||||||
|
if endblock - length - 1 == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
length += 1;
|
||||||
|
}
|
||||||
|
if length == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
length -= 1;
|
||||||
|
block = 0;
|
||||||
|
loop {
|
||||||
|
if block + length >= disk.len() || block + length >= endblock {
|
||||||
|
endblock -= length;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
spaceblock = disk.get(block..=block + length).unwrap();
|
||||||
|
if spaceblock.iter().all(Option::is_none) {
|
||||||
|
move_blocks(disk, endblock, length, block);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
block += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//print_disk(disk.clone(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut layout = Vec::with_capacity(DATA.len());
|
||||||
|
for char in DATA.chars() {
|
||||||
|
layout.push(char_to_num(char));
|
||||||
|
}
|
||||||
|
let raw_disk = layout_to_disk(layout);
|
||||||
|
println!("Layout parsed");
|
||||||
|
let mut block_disk = raw_disk.clone();
|
||||||
|
let mut file_disk = raw_disk.clone();
|
||||||
|
compact_blocks(&mut block_disk);
|
||||||
|
let mut cksum = calculate_checksum(block_disk);
|
||||||
|
println!(
|
||||||
|
"Checksum for the blockcompacted disk is: {}",
|
||||||
|
cksum
|
||||||
|
);
|
||||||
|
compact_files(&mut file_disk);
|
||||||
|
cksum = calculate_checksum(file_disk);
|
||||||
|
println!(
|
||||||
|
"Checksum for the filecompacted disk is: {}",
|
||||||
|
cksum,
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,15 +1,9 @@
|
||||||
use num::{pow::Pow, Integer};
|
use num::{pow::Pow, Integer};
|
||||||
use std::ops::AddAssign;
|
use std::ops::AddAssign;
|
||||||
|
|
||||||
pub fn parsenumber<T: Integer + From<u32> + Pow<u32, Output = T> + AddAssign + Copy>(
|
#[inline]
|
||||||
input: &str,
|
pub fn char_to_num<T: Integer + From<u32>>(c: char) -> T {
|
||||||
) -> T {
|
match c {
|
||||||
const MAX_POWER: u32 = 32;
|
|
||||||
let base = T::from(10);
|
|
||||||
let mut output: T = T::from(0);
|
|
||||||
let mut mul: u32 = 0;
|
|
||||||
for c in input.chars().rev() {
|
|
||||||
let i: T = match c {
|
|
||||||
'1' => T::from(1),
|
'1' => T::from(1),
|
||||||
'2' => T::from(2),
|
'2' => T::from(2),
|
||||||
'3' => T::from(3),
|
'3' => T::from(3),
|
||||||
|
@ -21,7 +15,18 @@ pub fn parsenumber<T: Integer + From<u32> + Pow<u32, Output = T> + AddAssign + C
|
||||||
'9' => T::from(9),
|
'9' => T::from(9),
|
||||||
'0' => T::from(0),
|
'0' => T::from(0),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parsenumber<T: Integer + From<u32> + Pow<u32, Output = T> + AddAssign + Copy>(
|
||||||
|
input: &str,
|
||||||
|
) -> T {
|
||||||
|
const MAX_POWER: u32 = 32;
|
||||||
|
let base = T::from(10);
|
||||||
|
let mut output: T = T::from(0);
|
||||||
|
let mut mul: u32 = 0;
|
||||||
|
for c in input.chars().rev() {
|
||||||
|
let i: T = char_to_num(c);
|
||||||
if mul > MAX_POWER {
|
if mul > MAX_POWER {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
@ -34,19 +39,7 @@ pub fn parsenumber<T: Integer + From<u32> + Pow<u32, Output = T> + AddAssign + C
|
||||||
pub fn get_numbers<T: Integer + From<u32>>(input: &str) -> Vec<T> {
|
pub fn get_numbers<T: Integer + From<u32>>(input: &str) -> Vec<T> {
|
||||||
let mut numbers = Vec::new();
|
let mut numbers = Vec::new();
|
||||||
for char in input.chars() {
|
for char in input.chars() {
|
||||||
match char {
|
numbers.push(char_to_num(char));
|
||||||
'1' => numbers.push(T::from(1)),
|
|
||||||
'2' => numbers.push(T::from(2)),
|
|
||||||
'3' => numbers.push(T::from(3)),
|
|
||||||
'4' => numbers.push(T::from(4)),
|
|
||||||
'5' => numbers.push(T::from(5)),
|
|
||||||
'6' => numbers.push(T::from(6)),
|
|
||||||
'7' => numbers.push(T::from(7)),
|
|
||||||
'8' => numbers.push(T::from(8)),
|
|
||||||
'9' => numbers.push(T::from(9)),
|
|
||||||
'0' => numbers.push(T::from(0)),
|
|
||||||
_ => unimplemented!(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
numbers
|
numbers
|
||||||
}
|
}
|
||||||
|
|
Laden …
Tabelle hinzufügen
In neuem Issue referenzieren