diff --git a/src/day05.rs b/src/day05.rs new file mode 100644 index 0000000..84b49da --- /dev/null +++ b/src/day05.rs @@ -0,0 +1,116 @@ +use std::str::FromStr; + +use aoc_runner_derive::{aoc, aoc_generator}; + +#[derive(Debug, Clone)] +pub struct Stacks { + stacks: Vec>, +} + +impl Stacks { + pub fn apply_instruction(&mut self, ins: &Instruction) { + for _ in 0..(ins.count) { + let crte = self.stacks[ins.from - 1].pop().unwrap(); + self.stacks[ins.to - 1].push(crte); + } + } + + pub fn apply_instruction_in_order(&mut self, ins: &Instruction) { + let from_stack = &mut self.stacks[ins.from - 1]; + let crates = from_stack.split_off(from_stack.len() - ins.count); + dbg!(&crates); + self.stacks[ins.to - 1].extend_from_slice(&crates); + } + + pub fn top_crates(&self) -> String { + self.stacks + .iter() + .map(|stack| stack.last().unwrap()) + .collect() + } +} + +#[derive(Debug, Copy, Clone)] +pub struct InvalidStacks; + +impl FromStr for Stacks { + type Err = InvalidStacks; + + fn from_str(s: &str) -> Result { + let lines = s + .lines() + .take_while(|s| &s[1..2] != "1") + .map(|s| s.chars().skip(1).step_by(4).collect()) + .collect::>>(); + let mut stacks = Vec::new(); + stacks.resize(lines[0].len(), Vec::new()); + for line in &lines { + for (i, crte) in line.iter().enumerate() { + if crte == &' ' { + continue; + } + stacks[i].push(*crte); + } + } + for stack in &mut stacks { + stack.reverse(); + } + Ok(Self { stacks }) + } +} + +#[derive(Debug, Clone)] +pub struct Instruction { + count: usize, + from: usize, + to: usize, +} + +#[derive(Debug, Copy, Clone)] +pub struct InvalidInstruction; + +impl FromStr for Instruction { + type Err = InvalidInstruction; + + fn from_str(s: &str) -> Result { + let s = s.split(' ').collect::>(); + if s.len() != 6 { + return Err(InvalidInstruction); + } + Ok(Self { + count: s[1].parse().map_err(|_| InvalidInstruction)?, + from: s[3].parse().map_err(|_| InvalidInstruction)?, + to: s[5].parse().map_err(|_| InvalidInstruction)?, + }) + } +} + +#[aoc_generator(day5)] +pub fn input_generator(input: &str) -> (Stacks, Vec) { + let (start, instructions) = input.split_once(&"\n\n").unwrap(); + ( + start.parse().unwrap(), + instructions + .lines() + .map(|ins| ins.parse().unwrap()) + .collect(), + ) +} + +#[aoc(day5, part1)] +pub fn solve_part1(input: &(Stacks, Vec)) -> String { + let mut stacks = input.0.clone(); + for ins in &input.1 { + stacks.apply_instruction(ins); + } + stacks.top_crates() +} + +#[aoc(day5, part2)] +pub fn solve_part2(input: &(Stacks, Vec)) -> String { + let mut stacks = input.0.clone(); + for ins in &input.1 { + stacks.apply_instruction_in_order(ins); + } + stacks.top_crates() +} diff --git a/src/lib.rs b/src/lib.rs index 010163f..2fe9df9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,9 @@ use aoc_runner_derive::aoc_lib; -pub mod day01; -pub mod day02; -pub mod day03; -pub mod day04; +mod day01; +mod day02; +mod day03; +mod day04; +mod day05; aoc_lib! { year = 2022 }