Adds day 9

This commit is contained in:
Dennis Brentjes 2025-02-22 22:43:39 +01:00
parent bc0aa70ac3
commit 8c116cb59a
4 changed files with 156 additions and 1 deletions

1
resources/input9.txt Normal file

File diff suppressed because one or more lines are too long

149
src/days/day9.rs Normal file
View File

@ -0,0 +1,149 @@
use core::fmt;
use std::path::Path;
use advent_derive::advent_day;
use crate::{error::AdventError, input::get_input};
use super::*;
#[derive(PartialEq, Copy, Clone)]
enum Sector {
Empty,
Chunk(u32)
}
impl fmt::Debug for Sector {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Empty => write!(f, "(.)"),
Self::Chunk(arg0) => write!(f, "({})", arg0),
}
}
}
struct Part1{
drive: Vec<Sector>
}
type Part2 = Part1;
impl Part1 {
fn new() -> Self {
Self {
drive: vec![]
}
}
}
fn read_input_part1(part1: &mut Part1, path: &Path) -> Result<(), AdventError> {
let line = get_input(path);
let mut reading_file = true;
let mut current_file_id = 0;
for c in line.chars() {
let i = c.to_digit(10).unwrap() as u8;
if reading_file {
for _ in 0..i {
part1.drive.push(Sector::Chunk(current_file_id))
}
current_file_id += 1;
} else {
for _ in 0..i {
part1.drive.push(Sector::Empty);
}
}
reading_file = !reading_file
}
Ok(())
}
fn checksum(drive: &Vec<Sector>) -> usize {
drive.iter().enumerate().map(|(i, sector)| {
match sector {
Sector::Empty => 0,
Sector::Chunk(f) => i * (*f as usize),
}
}).sum()
}
fn solve_part1(part1: &mut Part1) -> Result<String, AdventError> {
let mut empty_index = 0;
let mut rev_file_index = 0;
loop {
empty_index += part1.drive.iter().skip(empty_index).position(|s| { *s == Sector::Empty}).unwrap();
rev_file_index += part1.drive.iter().rev().skip(rev_file_index).position(|s| { *s != Sector::Empty}).unwrap();
let file_index = part1.drive.len() - 1 - rev_file_index;
if empty_index > file_index {
break;
}
part1.drive[empty_index] = part1.drive[file_index];
part1.drive[file_index] = Sector::Empty;
}
let checksum: usize = checksum(&part1.drive);
Ok(checksum.to_string())
}
fn read_input_part2(part2: &mut Part2, path: &Path) -> Result<(), AdventError> {
read_input_part1(part2, path)
}
fn highest_file_id(part2: &Part2) -> u32 {
match part2.drive.iter().rev().find(|s| **s != Sector::Empty).unwrap() {
Sector::Empty => panic!("Should not happen"),
Sector::Chunk(f) => *f,
}
}
fn find_pos_and_len(part2: &Part2, id: u32) -> (usize, usize) {
let pos = part2.drive.iter().position(|s| match s {
Sector::Empty => false,
Sector::Chunk(cid) => *cid == id,
}).unwrap();
for j in pos..part2.drive.len() {
if part2.drive[j] != Sector::Chunk(id){
return (pos, j - pos)
}
}
return (pos, part2.drive.len() - pos)
}
fn find_empty_slice(part2: &Part2, len: usize) -> usize {
let mut pos = 0;
loop {
pos += part2.drive.iter().skip(pos).position(|s| *s == Sector::Empty).unwrap();
if pos + len >= part2.drive.len() {
return part2.drive.len();
}
if part2.drive[pos..pos+len].iter().all(|s| *s == Sector::Empty) {
return pos;
}
pos += 1;
}
}
fn solve_part2(part2: &mut Part2) -> Result<String, AdventError> {
let highest_file_id = highest_file_id(part2);
for i in (1..highest_file_id + 1).rev() {
let (pos, len) = find_pos_and_len(part2, i);
let empty_pos = find_empty_slice(part2, len);
if empty_pos > pos {
continue;
}
for j in empty_pos..empty_pos+len {
part2.drive[j] = Sector::Chunk(i);
}
for j in pos..pos+len {
part2.drive[j] = Sector::Empty;
}
}
let checksum: usize = checksum(&part2.drive);
Ok(checksum.to_string())
}
#[advent_day(Part1, Part2)]
struct Day9;

View File

@ -23,13 +23,17 @@ pub mod day5;
pub mod day6;
pub mod day7;
pub mod day8;
pub mod day9;
pub mod day14;
/*
use std::path::Path;
use advent_derive::advent_day;
use crate::error::AdventError;
use super::*;
struct Part1{}

View File

@ -12,6 +12,7 @@ use day5::Day5;
use day6::Day6;
use day7::Day7;
use day8::Day8;
use day9::Day9;
use day14::Day14;
@ -49,7 +50,7 @@ fn main() -> Result<(), AdventError> {
Box::new(Day6::new()),
Box::new(Day7::new()),
Box::new(Day8::new()),
Box::new(DummyDay::new()),
Box::new(Day9::new()),
Box::new(DummyDay::new()),
Box::new(DummyDay::new()),
Box::new(DummyDay::new()),