use std::collections::LinkedList;
use std::io;
use std::io::Read;
fn main() {
// get input as lines
let mut buf: String = String::new();
io::stdin().read_to_string(&mut buf).unwrap();
let mut lines: Vec<&str> = buf.split('\n').collect();
lines.pop(); // newline at end of file
// get separator between initial setup <=> operations
let mut ind: usize = 0;
while lines[ind].len() > 0 { ind += 1; }
// init stacks
let mut stacks: Vec<LinkedList<char>> = vec![];
let ns = (lines[ind-1].len() + 1) / 4;
for _ in 0..ns { stacks.push(LinkedList::new()); }
// make initial state
for i in (0..ind - 1).rev() {
println!("{}", lines[i]);
let l: Vec<char> = lines[i].chars().collect();
for j in 0..ns {
if l[j*4 + 1] != ' ' {
stacks[j].push_back(l[j*4 + 1]);
}
}
}
// move stacks
for i in ind + 1..lines.len() {
let l: Vec<&str> = lines[i].split_ascii_whitespace().collect();
let (a, b, c): (usize, usize, usize) = ( // get the number parts. terrible code. whatever
l[1].parse::<>().unwrap(),
l[3].parse::<>().unwrap(),
l[5].parse::<>().unwrap()
);
move_crates_p2(&mut stacks, a, b-1, c-1); // switch to move_crates_p1 for part 1
}
// output
for s in stacks {
print!("{}", s.back().unwrap());
}
println!(); // not strictly necessary but my shell yells at me if i don't always output a newline at the end
}
fn move_crates_p2(crates: &mut Vec<LinkedList<char>>, num: usize, src: usize, dest: usize) { // part 2
let mut queue: LinkedList<char> = LinkedList::new(); // 2 stacks = queue
for _ in 0..num {
let ch = crates[src].pop_back().unwrap();
queue.push_back(ch);
}
while !queue.is_empty() {
crates[dest].push_back(queue.pop_back().unwrap());
}
}
fn move_crates_p1(crates: &mut Vec<LinkedList<char>>, num: usize, src: usize, dest: usize) { // part 1
for _ in 0..num {
let ch = crates[src].pop_back().unwrap();
crates[dest].push_back(ch);
}
}