--- title: "Advent of Code: Day Five" date: 2022-12-05T00:00:00 slug: advent-of-code-day-five tags: [advent-of-code-2022] --- **Spoilers for Advent of Code below** * [Day four](/post/advent-of-code-day-four) * [All Advent of Code posts](/blog/category/advent-of-code) * [Source](https://github.com/lewisdaleuk/advent-of-code-2022) Today was the first day that I can definitely say that I struggled to get the task done. ## Part one The brief _sounded_ fairly simple. Given a list of "stacks" of boxes (represented by a character), and a set of instructions (in the format `move n from x to y`), work out what the final configuration would look like. The input: ```bash [D] [N] [C] [Z] [M] [P] 1 2 3 move 1 from 2 to 1 move 3 from 1 to 3 move 2 from 2 to 1 move 1 from 1 to 2 ``` I was planning out my data structures, and this is where I made my first and silliest mistake: I used String for my stacks. "They're just lists of chars", I thought, this should be easy. Unfortunately, my logic was off and I kept forgetting to reverse my strings, leading to a lot of banging my head against the wall when I came up with this: ```rust #[derive(Debug, PartialEq, Eq)] struct Operation { quantity: usize, source: usize, target: usize } #[derive(Debug, PartialEq, Eq)] pub struct Crane { pub stacks: Vec, operations: VecDeque, } impl Crane { fn operate(&mut self) { let operation = self.operations.pop_front().unwrap(); let split: String = self.stacks[operation.source - 1].take(operation.quantity).unwrap(); self.stacks[operation.target - 1].insert_str(0, &split); } } ``` The `take` function was my first foray into using `Trait` to extend a core type: ```rust trait Take { fn take(&mut self, n: usize) -> Option; } impl Take for String { fn take(&mut self, n: usize) -> Option { if n <= self.len() { let split = String::from(&self[..n]); self.replace_range(..n, ""); return Some(split); } None } } ``` But this didn't work, because my take function took the _top_ off the string, and then replaced it in the original order, so instead of going from: ```bash P N Z C D B ``` to: ```bash N C P P Z Z D B ``` I was doing: ```bash N C Z P D B ``` A subtle difference, but very important for the final result. In the end, I updated `operate` to reverse the strings before prepending them to the stack: ```rust fn operate(&mut self) { let operation = self.operations.pop_front().unwrap(); let split: String = self.stacks[operation.source - 1] .take(operation.quantity) .unwrap() .chars() .rev() .collect(); self.stacks[operation.target - 1].insert_str(0, &split); } ``` ## Part two Interestingly... Part two's problem was the same, but I was to retain the original insertion order of the stack. Well, well, well, look how the tables have turned. My earlier cockup has become my superpower. All I had to do was revert my little change from earlier, returning `operate` back to it's original state, and that was it! Day 5 was a toughie for me, but mostly because I tried to be clever but really wasn't. Next time, I'll use an actual Stack - even if I need to write the operations for it myself.