feat: day 9
This commit is contained in:
parent
1e9030960d
commit
a7bc0e746a
|
@ -4,7 +4,7 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
full = ["day1", "day2", "day3", "day4", "day5", "day6", "day7", "day8"]
|
full = ["day1", "day2", "day3", "day4", "day5", "day6", "day7", "day8", "day9"]
|
||||||
default = ["full"]
|
default = ["full"]
|
||||||
day1 = []
|
day1 = []
|
||||||
day2 = []
|
day2 = []
|
||||||
|
@ -14,6 +14,7 @@ day5 = []
|
||||||
day6 = []
|
day6 = []
|
||||||
day7 = []
|
day7 = []
|
||||||
day8 = []
|
day8 = []
|
||||||
|
day9 = []
|
||||||
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
1
inputs/day09/example.txt
Normal file
1
inputs/day09/example.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
2333133121414131402
|
|
@ -79,7 +79,7 @@ pub fn pt1(input: &str) -> usize {
|
||||||
debug!("new Map: \n{new_map}");
|
debug!("new Map: \n{new_map}");
|
||||||
antinode_positions.len()
|
antinode_positions.len()
|
||||||
}
|
}
|
||||||
// 225 is too high
|
|
||||||
pub fn pt2(input: &str) -> usize {
|
pub fn pt2(input: &str) -> usize {
|
||||||
let char_positions = input
|
let char_positions = input
|
||||||
.lines()
|
.lines()
|
||||||
|
|
154
src/day09.rs
Normal file
154
src/day09.rs
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
|
pub fn pt1(input: &str) -> usize {
|
||||||
|
let mut disk_layout = input
|
||||||
|
.chars()
|
||||||
|
.map(|c| c.to_digit(10).unwrap())
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(i, c)| {
|
||||||
|
(0..c)
|
||||||
|
.map(|_| if i % 2 == 0 { Some(i / 2) } else { None })
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let mut min_pos = usize::MAX;
|
||||||
|
let dl = disk_layout.clone();
|
||||||
|
debug!(
|
||||||
|
"disk layout: {}",
|
||||||
|
disk_layout
|
||||||
|
.iter()
|
||||||
|
.map(|v| match v {
|
||||||
|
Some(v) => v.to_string(),
|
||||||
|
None => ".".to_string(),
|
||||||
|
})
|
||||||
|
.collect::<String>()
|
||||||
|
);
|
||||||
|
for (pos, segment) in disk_layout.iter_mut().enumerate() {
|
||||||
|
if segment.is_none() && pos < min_pos {
|
||||||
|
let next_candidate = dl
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.rev()
|
||||||
|
.find(|(i, v)| v.is_some() && *i < min_pos);
|
||||||
|
match next_candidate {
|
||||||
|
Some((i, a)) => {
|
||||||
|
segment.replace(a.unwrap());
|
||||||
|
min_pos = i;
|
||||||
|
}
|
||||||
|
None => break,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug!(
|
||||||
|
"disk layout: {}",
|
||||||
|
disk_layout
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(i, _v)| *i < min_pos)
|
||||||
|
.map(|(_i, v)| match v {
|
||||||
|
Some(v) => v.to_string(),
|
||||||
|
None => ".".to_string(),
|
||||||
|
})
|
||||||
|
.collect::<String>()
|
||||||
|
);
|
||||||
|
disk_layout
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(i, v)| v.is_some() && *i < min_pos)
|
||||||
|
.map(|(i, v)| v.unwrap() * i)
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub(crate) enum Segment {
|
||||||
|
Empty(usize),
|
||||||
|
File(usize, usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pt2(input: &str) -> usize {
|
||||||
|
let mut final_disk: Vec<usize> = Vec::new();
|
||||||
|
let disk_layout = input
|
||||||
|
.chars()
|
||||||
|
.map(|c| c.to_digit(10).unwrap())
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, c)| {
|
||||||
|
if i % 2 == 0 {
|
||||||
|
Segment::File(c as usize, i / 2)
|
||||||
|
} else {
|
||||||
|
Segment::Empty(c as usize)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let mut moved_segments = HashSet::new();
|
||||||
|
for (outer_pos, segment) in disk_layout.iter().enumerate() {
|
||||||
|
let mut s = segment.clone();
|
||||||
|
if moved_segments.contains(&outer_pos) {
|
||||||
|
s = match s {
|
||||||
|
Segment::File(v, _i) => Segment::Empty(v),
|
||||||
|
Segment::Empty(v) => Segment::Empty(v),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
moved_segments.insert(outer_pos);
|
||||||
|
match s {
|
||||||
|
Segment::File(v, i) => {
|
||||||
|
final_disk.append(&mut vec![i; v]);
|
||||||
|
}
|
||||||
|
Segment::Empty(v) => {
|
||||||
|
let mut remaining_space = v;
|
||||||
|
while remaining_space > 0 {
|
||||||
|
if let Some((pos, v, i)) = disk_layout
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_pos, s)| match s {
|
||||||
|
Segment::Empty(_) => false,
|
||||||
|
Segment::File(_v, _i) => true,
|
||||||
|
})
|
||||||
|
.filter(|(pos, _s)| !moved_segments.contains(pos))
|
||||||
|
.map(|(pos, s)| match s {
|
||||||
|
Segment::Empty(_) => unreachable!(),
|
||||||
|
Segment::File(v, i) => (pos, *v, *i),
|
||||||
|
})
|
||||||
|
.rev()
|
||||||
|
.find(|(_pos, v, _i)| *v <= remaining_space)
|
||||||
|
{
|
||||||
|
final_disk.append(&mut vec![i; v]);
|
||||||
|
remaining_space -= v;
|
||||||
|
moved_segments.insert(pos);
|
||||||
|
} else {
|
||||||
|
final_disk.append(&mut vec![0; remaining_space]);
|
||||||
|
remaining_space = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug!("disk layout: {final_disk:?}");
|
||||||
|
final_disk.iter().enumerate().map(|(a, b)| a * *b).sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use tracing_test::traced_test;
|
||||||
|
|
||||||
|
use super::{pt1, pt2};
|
||||||
|
use std::fs::read_to_string;
|
||||||
|
|
||||||
|
#[traced_test]
|
||||||
|
#[test]
|
||||||
|
pub fn test_pt1() {
|
||||||
|
let input =
|
||||||
|
read_to_string("./inputs/day09/example.txt").expect("Missing example.txt for day09");
|
||||||
|
assert_eq!(pt1(&input), 1928)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[traced_test]
|
||||||
|
#[test]
|
||||||
|
pub fn test_pt2() {
|
||||||
|
let input =
|
||||||
|
read_to_string("./inputs/day09/example.txt").expect("Missing example.txt for day09");
|
||||||
|
|
||||||
|
assert_eq!(pt2(&input), 2858)
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,8 @@ mod day06;
|
||||||
mod day07;
|
mod day07;
|
||||||
#[cfg(feature = "day8")]
|
#[cfg(feature = "day8")]
|
||||||
mod day08;
|
mod day08;
|
||||||
|
#[cfg(feature = "day9")]
|
||||||
|
mod day09;
|
||||||
|
|
||||||
fn main() -> eyre::Result<()> {
|
fn main() -> eyre::Result<()> {
|
||||||
color_eyre::install()?;
|
color_eyre::install()?;
|
||||||
|
@ -41,6 +43,8 @@ fn main() -> eyre::Result<()> {
|
||||||
solve_day(7, day07::pt1, day07::pt2);
|
solve_day(7, day07::pt1, day07::pt2);
|
||||||
#[cfg(feature = "day8")]
|
#[cfg(feature = "day8")]
|
||||||
solve_day(8, day08::pt1, day08::pt2);
|
solve_day(8, day08::pt1, day08::pt2);
|
||||||
|
#[cfg(feature = "day9")]
|
||||||
|
solve_day(9, day09::pt1, day09::pt2);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue