diff --git a/2024/09a/Cargo.toml b/2024/09a/Cargo.toml new file mode 100644 index 0000000..befa761 --- /dev/null +++ b/2024/09a/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "advent-of-code-2024-09a" +version = "0.1.0" +edition.workspace = true +rust-version.workspace = true +description = "Solution to Advent of Code 2024, problem 09a" +authors.workspace = true +repository.workspace = true +license.workspace = true +publish.workspace = true + +[dependencies] +adventutil = { path = "../../adventutil" } + +[lints] +workspace = true diff --git a/2024/09a/src/main.rs b/2024/09a/src/main.rs new file mode 100644 index 0000000..6713f48 --- /dev/null +++ b/2024/09a/src/main.rs @@ -0,0 +1,54 @@ +use adventutil::Input; +use std::collections::VecDeque; + +fn solve(input: Input) -> u64 { + // List of Option values + let mut blocks = VecDeque::new(); + let s = input.read(); + let mut is_file = true; + let mut i = 0u64; + for d in s.trim().chars() { + let size = usize::try_from(d.to_digit(10).unwrap()).unwrap(); + if is_file { + blocks.extend(std::iter::repeat_n(Some(i), size)); + } else { + blocks.extend(std::iter::repeat_n(None, size)); + i += 1; + } + is_file = !is_file; + } + let mut checksum = 0; + let mut pos = 0u64; + 'outer: while let Some(blk) = blocks.pop_front() { + if let Some(fid) = blk { + checksum += pos * fid; + } else { + let fid = loop { + let Some(blk) = blocks.pop_back() else { + break 'outer; + }; + if let Some(fid) = blk { + break fid; + } + }; + checksum += pos * fid; + } + pos += 1; + } + checksum +} + +fn main() { + println!("{}", solve(Input::from_env())); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_example() { + let input = Input::from("2333133121414131402"); + assert_eq!(solve(input), 1928); + } +} diff --git a/2024/09b/Cargo.toml b/2024/09b/Cargo.toml new file mode 100644 index 0000000..553f930 --- /dev/null +++ b/2024/09b/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "advent-of-code-2024-09b" +version = "0.1.0" +edition.workspace = true +rust-version.workspace = true +description = "Solution to Advent of Code 2024, problem 09a" +authors.workspace = true +repository.workspace = true +license.workspace = true +publish.workspace = true + +[dependencies] +adventutil = { path = "../../adventutil" } + +[lints] +workspace = true diff --git a/2024/09b/src/main.rs b/2024/09b/src/main.rs new file mode 100644 index 0000000..0a23d12 --- /dev/null +++ b/2024/09b/src/main.rs @@ -0,0 +1,104 @@ +use adventutil::Input; +use std::collections::VecDeque; + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +struct File { + position: u64, + id: u64, + size: u64, +} + +impl File { + fn with_position(mut self, pos: u64) -> File { + self.position = pos; + self + } + + fn checksum(&self) -> u64 { + (self.position..) + .map(|p| p * self.id) + .take(usize::try_from(self.size).unwrap()) + .sum() + } +} + +#[derive(Clone, Copy, Debug, Eq, PartialEq)] +struct Free { + position: u64, + size: u64, +} + +impl Free { + fn reduce(&mut self, size: u64) { + self.position += size; + self.size -= size; + } +} + +fn solve(input: Input) -> u64 { + let mut files = VecDeque::new(); + let mut free_space = Vec::new(); + let s = input.read(); + let mut is_file = true; + let mut file_id = 0u64; + let mut position = 0u64; + for d in s.trim().chars() { + let size = u64::from(d.to_digit(10).unwrap()); + if is_file { + files.push_back(File { + position, + id: file_id, + size, + }); + } else { + free_space.push(Free { position, size }); + file_id += 1; + } + is_file = !is_file; + position += size; + } + let mut checksum = 0; + if let Some(f) = files.pop_front() { + checksum += f.checksum(); + } + while let Some(f) = files.pop_back() { + let mut moved = false; + let mut del_index = None; + for (j, free) in free_space.iter_mut().enumerate() { + if free.position >= f.position { + break; + } + if free.size >= f.size { + checksum += f.with_position(free.position).checksum(); + free.reduce(f.size); + if free.size == 0 { + del_index = Some(j); + } + moved = true; + break; + } + } + if !moved { + checksum += f.checksum(); + } + if let Some(j) = del_index { + free_space.remove(j); + } + } + checksum +} + +fn main() { + println!("{}", solve(Input::from_env())); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_example() { + let input = Input::from("2333133121414131402"); + assert_eq!(solve(input), 2858); + } +} diff --git a/2024/answers.csv b/2024/answers.csv index 4b3ee50..63e371b 100644 Binary files a/2024/answers.csv and b/2024/answers.csv differ diff --git a/2024/inputs/09.txt b/2024/inputs/09.txt new file mode 100644 index 0000000..c098d16 Binary files /dev/null and b/2024/inputs/09.txt differ diff --git a/Cargo.lock b/Cargo.lock index 9eeb1aa..c3415fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2136,6 +2136,20 @@ dependencies = [ "adventutil", ] +[[package]] +name = "advent-of-code-2024-09a" +version = "0.1.0" +dependencies = [ + "adventutil", +] + +[[package]] +name = "advent-of-code-2024-09b" +version = "0.1.0" +dependencies = [ + "adventutil", +] + [[package]] name = "adventutil" version = "0.1.0"