#![feature(iter_next_chunk)] use std::collections::VecDeque; const OFFSET: usize = 4; enum MachineType { Type9000, Type9001, } fn main() { let f = std::fs::read_to_string("/dev/stdin").unwrap(); let (crates, instructions) = f.split_once("\n\n").unwrap(); let (crates, instructions) = (crates.lines(), instructions.lines()); let mut stacks: Vec> = vec![VecDeque::new(); (f.lines().next().unwrap().len() / 4) + 1]; for crate_str in crates { for i in (1..crate_str.len()).step_by(OFFSET) { if let Some(crate_label) = crate_str.get(i..i + 1) { if !crate_label.chars().next().unwrap().is_alphabetic() { continue; } let vee = stacks.get_mut(i / 4).unwrap(); vee.push_front(crate_label); } } } let (mut reset_stacks, reset_instructions) = (stacks.clone(), instructions.clone()); solve(instructions, &mut stacks, MachineType::Type9000); solve(reset_instructions, &mut reset_stacks, MachineType::Type9001); } fn solve(instructions: core::str::Lines, stacks: &mut [VecDeque<&str>], machine_type: MachineType) { for instruction in instructions { if let Ok([amount, source, dest]) = instruction .split_whitespace() .filter_map(|n| n.parse::().ok()) .next_chunk() { let mut temp = VecDeque::new(); let source_stack = stacks.get_mut(source - 1).unwrap(); for _ in 0..amount { temp.push_front(source_stack.pop_back().unwrap()); } let dest_stack = stacks.get_mut(dest - 1).unwrap(); match machine_type { MachineType::Type9000 => { for _ in 0..amount { dest_stack.push_back(temp.pop_back().unwrap()); } } MachineType::Type9001 => { if amount == 1 { dest_stack.push_back(temp.pop_back().unwrap()); } else { dest_stack.append(&mut temp); } } } } } if matches!(machine_type, MachineType::Type9000) { print!("P1: "); } else { print!("P2: "); } for stack in stacks.iter_mut() { print!("{}", stack.pop_back().unwrap()); } println!(); }