use aoc_runner_derive::{aoc as aoc_run, aoc_generator}; type Stax = Vec>; type Inst = (usize, usize, usize); #[aoc_generator(day5)] fn parse_input_day1(input: &str) -> (Stax, Vec) { let mut out = Vec::new(); let mut inst = Vec::new(); let mut parsing_crates = true; for _ in 0..9 { out.push(Vec::new()); } let re = regex::Regex::new(r"^move (\d+) from (\d+) to (\d+)$").unwrap(); for line in input.lines() { if parsing_crates { if line.trim().starts_with('1') { continue; } if line.trim().is_empty() { parsing_crates = false; } for (i, cell) in line.as_bytes().chunks(4).enumerate() { let cell = std::str::from_utf8(cell).unwrap().trim(); if !cell.is_empty() { let cell = cell.strip_prefix('[').unwrap().strip_suffix(']').unwrap(); out[i].push(cell.chars().next().unwrap()); } } } else { let ins = re.captures(line).unwrap(); inst.push(( ins[1].parse().unwrap(), ins[2].parse::().unwrap() - 1, ins[3].parse::().unwrap() - 1, )); } } for stack in out.iter_mut() { stack.reverse(); } (out, inst) } #[aoc_run(day5, part1)] fn part1((stax, inst): &(Stax, Vec)) -> String { let mut stax = stax.to_owned(); for ins in inst.iter() { let (amt, from, to) = ins; let from = &mut stax[*from]; let mut tmp = Vec::with_capacity(*amt); for _ in 0..*amt { let t = from.pop().unwrap(); tmp.push(t); } stax[*to].append(&mut tmp); } let mut s = String::with_capacity(9); for stack in stax { s.push(stack.last().copied().unwrap()); } s } #[aoc_run(day5, part2)] fn p2((stax, inst): &(Stax, Vec)) -> String { let mut stax = stax.to_owned(); for ins in inst.iter() { let (amt, from, to) = ins; let from = &mut stax[*from]; let mut tmp = Vec::with_capacity(*amt); for _ in 0..*amt { let c = from.pop().unwrap(); tmp.push(c); } tmp.reverse(); stax[*to].append(&mut tmp); } let mut s = String::with_capacity(9); for stack in stax { s.push(stack.last().copied().unwrap()); } s }