Skip to content

Commit

Permalink
day 9 pt 2
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesPatrickGill committed Dec 10, 2024
1 parent 46f2e3e commit 95c9441
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 6 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,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` | `-` |
| [Day 9](./src/bin/09.rs) | `80.1µs` | `258.4ms` |

**Total: 35.45ms**
**Total: 293.85ms**
<!--- benchmarking table --->
97 changes: 93 additions & 4 deletions src/bin/09.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::VecDeque;
use std::{collections::VecDeque, ops::Div};

advent_of_code::solution!(9);

Expand Down Expand Up @@ -88,8 +88,97 @@ pub fn part_one(input: &str) -> Option<u64> {
Some(result)
}

pub fn part_two(input: &str) -> Option<u32> {
None
#[derive(Debug, Eq, Hash, PartialEq, Clone, Copy)]
enum Block2 {
File(u32, u32),
Free(u32),
}

pub fn part_two(input: &str) -> Option<u64> {
let mut queue: VecDeque<Block2> =
VecDeque::from_iter(input.chars().enumerate().filter_map(|(idx, ch)| {
if let Some(value) = ch.to_digit(10) {
if idx % 2 == 0 {
Some(Block2::File(value, (idx as u32).div(2)))
} else {
Some(Block2::Free(value))
}
} else {
None
}
}));
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 {
Block2::File(size, id) => {
for offset in 0..size {
result += id as u64 * (curr_idx + offset) as u64;
}
curr_idx += size;
}
Block2::Free(size) => {
// First get next right side candidate that fits
let mut to_readd_to_queue = VecDeque::new();
let mut r_candidate = None;
loop {
if queue.is_empty() {
queue.extend(to_readd_to_queue);
break;
}

if let Some(r) = queue.pop_back() {
match r {
Block2::File(r_size, id) => match size.cmp(&r_size) {
std::cmp::Ordering::Greater | std::cmp::Ordering::Equal => {
r_candidate = Some((r_size, id));
to_readd_to_queue.push_front(Block2::Free(r_size));
queue.extend(to_readd_to_queue);
break;
}
std::cmp::Ordering::Less => {
to_readd_to_queue.push_front(Block2::File(r_size, id));
}
},
Block2::Free(_) => {
to_readd_to_queue.push_front(r);
}
}
} else {
queue.extend(to_readd_to_queue);
break;
};
}

// Now fit it if it can
if let Some(r_can) = r_candidate {
match size.cmp(&r_can.0) {
std::cmp::Ordering::Less => panic!("Should not be possible"),
std::cmp::Ordering::Equal => {
for offset in 0..r_can.0 {
result += r_can.1 as u64 * (curr_idx + offset) as u64;
}
curr_idx += r_can.0;
}
std::cmp::Ordering::Greater => {
for offset in 0..r_can.0 {
result += r_can.1 as u64 * (curr_idx + offset) as u64;
}
curr_idx += r_can.0;
queue.push_front(Block2::Free(size - r_can.0));
}
}
} else {
curr_idx += size;
}
}
}
}
Some(result)
}

#[cfg(test)]
Expand All @@ -105,6 +194,6 @@ mod tests {
#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, None);
assert_eq!(result, Some(2858));
}
}

0 comments on commit 95c9441

Please sign in to comment.