feat(day9): init
This commit is contained in:
parent
8f513f74cc
commit
e1ecbe536c
2 changed files with 116 additions and 0 deletions
114
src/solutions/day_09.rs
Normal file
114
src/solutions/day_09.rs
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
use crate::common::{Answer, Solution};
|
||||||
|
|
||||||
|
pub struct Day09;
|
||||||
|
|
||||||
|
impl Solution for Day09 {
|
||||||
|
fn name(&self) -> &'static str {
|
||||||
|
"Disk Fragmenter"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part_a(&self, input: &str) -> Answer {
|
||||||
|
let nums = input
|
||||||
|
.chars()
|
||||||
|
.map(|c| c.to_digit(10).unwrap())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut aligned_files = nums
|
||||||
|
.iter()
|
||||||
|
.step_by(2)
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(i, &n)| vec![i; n as usize])
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut final_disk = Vec::new();
|
||||||
|
|
||||||
|
for (i, n) in nums.iter().enumerate() {
|
||||||
|
if aligned_files.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let len = (*n as usize).min(aligned_files.len());
|
||||||
|
|
||||||
|
if i % 2 == 0 {
|
||||||
|
final_disk.extend(aligned_files.drain(0..len));
|
||||||
|
} else {
|
||||||
|
final_disk.extend(
|
||||||
|
aligned_files
|
||||||
|
.split_off(aligned_files.len() - len)
|
||||||
|
.iter()
|
||||||
|
.rev(),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
final_disk
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, n)| i * n)
|
||||||
|
.sum::<usize>()
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part_b(&self, input: &str) -> Answer {
|
||||||
|
let mut chunks = input
|
||||||
|
.chars()
|
||||||
|
.map(|c| c.to_digit(10).unwrap())
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, n)| ((i % 2 == 0).then_some(i >> 1), n))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let files = chunks
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(o, n)| o.map(|i| (i, *n)))
|
||||||
|
.rev()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
for (content, size) in files {
|
||||||
|
let free_idx = chunks
|
||||||
|
.iter()
|
||||||
|
.position(|(o, len)| o.is_none() && *len >= size);
|
||||||
|
|
||||||
|
// we need to recompute this because stuff moves in the vec and the element count is not constant
|
||||||
|
let orig_idx = chunks
|
||||||
|
.iter()
|
||||||
|
.position(|chunk| chunk == &(Some(content), size))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if let Some(free_idx) = free_idx {
|
||||||
|
if free_idx < orig_idx {
|
||||||
|
chunks.get_mut(orig_idx).unwrap().0 = None;
|
||||||
|
chunks.insert(free_idx, (Some(content), size));
|
||||||
|
chunks.get_mut(free_idx + 1).unwrap().1 -= size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chunks
|
||||||
|
.iter()
|
||||||
|
.flat_map(|(o, n)| vec![o.unwrap_or(0); *n as usize])
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, n)| i * n)
|
||||||
|
.sum::<usize>()
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::Day09;
|
||||||
|
use crate::common::Solution;
|
||||||
|
|
||||||
|
const INPUT: &str = "2333133121414131402";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part_a() {
|
||||||
|
assert_eq!(Day09.part_a(INPUT), 1928.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part_b() {
|
||||||
|
assert_eq!(Day09.part_b(INPUT), 2858.into());
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ mod day_05;
|
||||||
mod day_06;
|
mod day_06;
|
||||||
mod day_07;
|
mod day_07;
|
||||||
mod day_08;
|
mod day_08;
|
||||||
|
mod day_09;
|
||||||
|
|
||||||
pub const SOLUTIONS: &[&dyn Solution] = &[
|
pub const SOLUTIONS: &[&dyn Solution] = &[
|
||||||
&day_01::Day01,
|
&day_01::Day01,
|
||||||
|
@ -18,4 +19,5 @@ pub const SOLUTIONS: &[&dyn Solution] = &[
|
||||||
&day_06::Day06,
|
&day_06::Day06,
|
||||||
&day_07::Day07,
|
&day_07::Day07,
|
||||||
&day_08::Day08,
|
&day_08::Day08,
|
||||||
|
&day_09::Day09,
|
||||||
];
|
];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue