Skip to content

Commit

Permalink
day 9
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesPatrickGill committed Dec 9, 2024
1 parent 88593b3 commit 3ce4645
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
| [Day 6](./src/bin/06.rs) | `358.0µs` | `31.5ms` |
| [Day 7](./src/bin/07.rs) | `487.3µs` | `862.0µs` |
| [Day 8](./src/bin/08.rs) | `36.5µs` | `116.8µs` |
| [Day 9](./src/bin/09.rs) | `78.7µs` | `-` |

**Total: 35.37ms**
**Total: 35.45ms**
<!--- benchmarking table --->
1 change: 1 addition & 0 deletions data/examples/09.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2333133121414131402
110 changes: 110 additions & 0 deletions src/bin/09.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
use std::collections::VecDeque;

advent_of_code::solution!(9);

#[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)]
enum Block {
File(u32),
Free(u32),
}

pub fn part_one(input: &str) -> Option<u64> {
let mut queue: VecDeque<Block> =
VecDeque::from_iter(input.chars().enumerate().filter_map(|(idx, ch)| {
if let Some(value) = ch.to_digit(10) {
if idx % 2 == 0 {
Some(Block::File(value))
} else {
Some(Block::Free(value))
}
} else {
None
}
}));
let mut curr_lower_file_id: u64 = 0;
let mut curr_upper_file_id: u64 = (queue.len() - 2).div_ceil(2) as u64;
let mut curr_idx = 0;

let mut result: u64 = 0;
while !queue.is_empty() {
let Some(front_candidate) = queue.pop_front() else {
break;
};
match front_candidate {
Block::File(size) => {
for offset in 0..size {
result += curr_lower_file_id * (curr_idx + offset) as u64;
}
curr_idx += size;
curr_lower_file_id += 1;
}
Block::Free(size) => {
let r_size = if let Some(r) = queue.pop_back() {
match r {
Block::File(r_size) => r_size,
Block::Free(_) => {
if let Some(r2) = queue.pop_back() {
match r2 {
Block::File(r2_size) => r2_size,
Block::Free(_) => panic!("Double free lol"),
}
} else {
break;
}
}
}
} else {
break;
};

match size.cmp(&r_size) {
std::cmp::Ordering::Less => {
for offset in 0..size {
result += curr_upper_file_id * (curr_idx + offset) as u64;
}
queue.push_back(Block::File(r_size - size));
curr_idx += size;
}
std::cmp::Ordering::Equal => {
for offset in 0..size {
result += curr_upper_file_id * (curr_idx + offset) as u64;
}
curr_upper_file_id -= 1;
curr_idx += size;
}
std::cmp::Ordering::Greater => {
for offset in 0..r_size {
result += curr_upper_file_id * (curr_idx + offset) as u64;
}
queue.push_front(Block::Free(size - r_size));
curr_upper_file_id -= 1;
curr_idx += r_size;
}
}
}
}
}

Some(result)
}

pub fn part_two(input: &str) -> Option<u32> {
None
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(1928));
}

#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, None);
}
}

0 comments on commit 3ce4645

Please sign in to comment.