use std::{default, collections::VecDeque}; use aoc_runner_derive::{aoc, aoc_generator}; use itertools::Itertools; #[derive(Debug)] pub struct Instruction { from: usize, to: usize, num: usize, } #[aoc_generator(day05)] pub fn input_generator(input: &str) -> (Vec>, Vec) { let mut instructions = vec![]; let mut rows = vec![]; for line in input.lines() { if line.trim().starts_with('[') { let mut row = vec![]; for chunk in &line.chars().chunks(4) { let boxes = chunk.filter(|c| c.is_ascii_uppercase()).collect::>(); row.push(boxes.first().copied()) } rows.push(row); } if line.starts_with("move") { let mut nums: Vec = vec![]; for w in line.split_ascii_whitespace() { if w.chars().all(|c| c.is_ascii_digit()) { nums.push(w.parse().unwrap()) } } instructions.push(Instruction { num: nums[0], from: nums[1]-1, to: nums[2]-1, }) } } let num_stacks = rows.iter().map(|v| v.len()).max().unwrap_or_default(); let mut stacks: Vec> = vec![]; stacks.resize(num_stacks, Default::default()); for row in rows.iter().rev() { for (stack,item) in row.iter().enumerate() { stacks[stack].extend(item); } } (stacks,instructions) } #[aoc(day05, part1)] pub fn solve_part1((stacks, instructions): &(Vec>, Vec)) -> String { let mut stacks = stacks.clone(); for inst in instructions { for _ in 0..inst.num { let item = stacks[inst.from].pop(); stacks[inst.to].extend(item); } } stacks.iter().filter_map(|s| s.last()).collect() } #[aoc(day05, part2)] pub fn solve_part2((stacks, instructions): &(Vec>, Vec)) -> String { let mut stacks = stacks.clone(); let mut buffer = Vec::with_capacity(1024); for inst in instructions { for _ in 0..inst.num { let item = stacks[inst.from].pop(); buffer.extend(item) } while let Some(item) = buffer.pop() { stacks[inst.to].push(item); } } stacks.iter().filter_map(|s| s.last()).collect() }