From 381ecb2f85152c3054c0a3b2edc97262291bf6bf Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Tue, 6 Dec 2022 00:30:08 +0100 Subject: [PATCH] 2022 - Day 5 --- 2022/Cargo.toml | 2 + 2022/input/5/input | 512 +++++++++++++++++++++++++++++++++++++++++++ 2022/input/5/test-1 | 9 + 2022/src/bin/day5.rs | 189 ++++++++++++++++ 4 files changed, 712 insertions(+) create mode 100644 2022/input/5/input create mode 100644 2022/input/5/test-1 create mode 100644 2022/src/bin/day5.rs diff --git a/2022/Cargo.toml b/2022/Cargo.toml index d56d162..ea67c1c 100644 --- a/2022/Cargo.toml +++ b/2022/Cargo.toml @@ -7,3 +7,5 @@ edition = "2021" [dependencies] anyhow = "1.0" +regex = "1" +lazy_static = "1.4.0" diff --git a/2022/input/5/input b/2022/input/5/input new file mode 100644 index 0000000..7227e79 --- /dev/null +++ b/2022/input/5/input @@ -0,0 +1,512 @@ +[S] [T] [Q] +[L] [B] [M] [P] [T] +[F] [S] [Z] [N] [S] [R] +[Z] [R] [N] [R] [D] [F] [V] +[D] [Z] [H] [J] [W] [G] [W] [G] +[B] [M] [C] [F] [H] [Z] [N] [R] [L] +[R] [B] [L] [C] [G] [J] [L] [Z] [C] +[H] [T] [Z] [S] [P] [V] [G] [M] [M] + 1 2 3 4 5 6 7 8 9 + +move 6 from 1 to 7 +move 2 from 2 to 4 +move 2 from 7 to 4 +move 6 from 4 to 3 +move 1 from 5 to 1 +move 3 from 8 to 3 +move 15 from 3 to 4 +move 6 from 5 to 9 +move 14 from 4 to 2 +move 3 from 2 to 7 +move 1 from 2 to 7 +move 9 from 9 to 1 +move 3 from 2 to 1 +move 7 from 6 to 7 +move 1 from 6 to 8 +move 2 from 9 to 1 +move 9 from 2 to 3 +move 8 from 3 to 9 +move 1 from 1 to 4 +move 1 from 8 to 6 +move 1 from 6 to 2 +move 5 from 9 to 8 +move 2 from 9 to 1 +move 1 from 4 to 2 +move 17 from 1 to 9 +move 1 from 3 to 1 +move 3 from 2 to 3 +move 2 from 4 to 5 +move 12 from 7 to 3 +move 16 from 9 to 2 +move 5 from 7 to 5 +move 2 from 1 to 2 +move 1 from 3 to 6 +move 1 from 4 to 6 +move 1 from 7 to 3 +move 1 from 6 to 3 +move 7 from 3 to 4 +move 5 from 8 to 3 +move 1 from 6 to 7 +move 7 from 3 to 4 +move 6 from 3 to 1 +move 2 from 4 to 8 +move 1 from 5 to 2 +move 10 from 4 to 5 +move 3 from 5 to 2 +move 2 from 8 to 9 +move 5 from 2 to 8 +move 1 from 3 to 5 +move 2 from 5 to 8 +move 12 from 5 to 7 +move 1 from 4 to 2 +move 5 from 9 to 4 +move 1 from 2 to 5 +move 6 from 1 to 3 +move 6 from 3 to 5 +move 10 from 7 to 4 +move 2 from 7 to 3 +move 4 from 7 to 6 +move 1 from 9 to 5 +move 12 from 2 to 1 +move 1 from 8 to 7 +move 3 from 7 to 4 +move 4 from 4 to 8 +move 7 from 5 to 3 +move 1 from 2 to 4 +move 10 from 1 to 5 +move 2 from 1 to 2 +move 4 from 6 to 7 +move 8 from 8 to 3 +move 5 from 4 to 9 +move 12 from 3 to 8 +move 4 from 3 to 8 +move 2 from 9 to 2 +move 3 from 5 to 4 +move 1 from 3 to 5 +move 1 from 7 to 6 +move 14 from 4 to 6 +move 6 from 5 to 9 +move 8 from 2 to 8 +move 3 from 5 to 7 +move 21 from 8 to 4 +move 16 from 4 to 9 +move 8 from 6 to 2 +move 4 from 6 to 1 +move 1 from 4 to 6 +move 2 from 4 to 8 +move 3 from 1 to 8 +move 2 from 4 to 6 +move 1 from 6 to 2 +move 3 from 8 to 4 +move 2 from 2 to 5 +move 2 from 5 to 7 +move 1 from 8 to 9 +move 1 from 4 to 9 +move 1 from 1 to 6 +move 3 from 6 to 3 +move 3 from 2 to 3 +move 1 from 4 to 6 +move 3 from 6 to 7 +move 10 from 9 to 7 +move 1 from 4 to 7 +move 6 from 8 to 3 +move 1 from 6 to 8 +move 2 from 2 to 5 +move 1 from 2 to 1 +move 1 from 8 to 9 +move 1 from 2 to 8 +move 1 from 1 to 9 +move 7 from 9 to 1 +move 1 from 8 to 5 +move 7 from 1 to 7 +move 3 from 5 to 8 +move 3 from 7 to 2 +move 1 from 8 to 4 +move 1 from 2 to 4 +move 2 from 4 to 6 +move 5 from 3 to 1 +move 9 from 7 to 2 +move 6 from 3 to 8 +move 8 from 2 to 7 +move 2 from 6 to 4 +move 2 from 1 to 7 +move 2 from 1 to 4 +move 24 from 7 to 4 +move 4 from 8 to 9 +move 2 from 7 to 5 +move 1 from 5 to 2 +move 1 from 3 to 8 +move 4 from 2 to 8 +move 13 from 9 to 2 +move 2 from 8 to 6 +move 3 from 9 to 6 +move 26 from 4 to 2 +move 1 from 5 to 7 +move 2 from 6 to 2 +move 2 from 4 to 1 +move 7 from 2 to 1 +move 15 from 2 to 6 +move 8 from 2 to 8 +move 4 from 6 to 8 +move 9 from 2 to 9 +move 13 from 6 to 7 +move 6 from 1 to 9 +move 2 from 2 to 4 +move 4 from 1 to 6 +move 3 from 8 to 3 +move 1 from 4 to 9 +move 2 from 6 to 7 +move 1 from 4 to 3 +move 3 from 3 to 2 +move 14 from 7 to 4 +move 5 from 9 to 5 +move 9 from 8 to 5 +move 7 from 9 to 6 +move 2 from 5 to 6 +move 2 from 9 to 2 +move 10 from 5 to 1 +move 1 from 3 to 1 +move 2 from 8 to 1 +move 1 from 9 to 2 +move 1 from 7 to 5 +move 4 from 2 to 1 +move 1 from 9 to 8 +move 3 from 4 to 1 +move 1 from 8 to 6 +move 12 from 1 to 5 +move 1 from 1 to 6 +move 1 from 7 to 5 +move 4 from 6 to 9 +move 2 from 2 to 4 +move 1 from 9 to 6 +move 1 from 1 to 5 +move 2 from 9 to 7 +move 10 from 6 to 5 +move 1 from 6 to 7 +move 20 from 5 to 1 +move 1 from 7 to 9 +move 2 from 9 to 1 +move 3 from 5 to 1 +move 2 from 8 to 4 +move 2 from 8 to 7 +move 1 from 5 to 9 +move 1 from 8 to 4 +move 22 from 1 to 7 +move 5 from 4 to 8 +move 1 from 5 to 9 +move 19 from 7 to 4 +move 2 from 9 to 1 +move 1 from 5 to 9 +move 10 from 1 to 8 +move 1 from 9 to 1 +move 1 from 8 to 3 +move 8 from 4 to 7 +move 1 from 5 to 6 +move 3 from 4 to 5 +move 1 from 5 to 9 +move 11 from 7 to 4 +move 4 from 4 to 9 +move 1 from 6 to 2 +move 1 from 3 to 9 +move 5 from 9 to 4 +move 5 from 7 to 9 +move 23 from 4 to 2 +move 17 from 2 to 7 +move 2 from 2 to 8 +move 4 from 4 to 7 +move 1 from 4 to 5 +move 2 from 5 to 2 +move 5 from 8 to 9 +move 5 from 2 to 7 +move 9 from 7 to 5 +move 11 from 9 to 2 +move 1 from 4 to 3 +move 5 from 8 to 7 +move 3 from 8 to 5 +move 2 from 1 to 3 +move 2 from 3 to 9 +move 1 from 5 to 8 +move 5 from 7 to 5 +move 15 from 5 to 4 +move 2 from 8 to 1 +move 2 from 5 to 1 +move 4 from 4 to 1 +move 1 from 8 to 7 +move 8 from 2 to 1 +move 4 from 2 to 8 +move 2 from 7 to 4 +move 5 from 8 to 6 +move 5 from 7 to 9 +move 4 from 6 to 5 +move 7 from 4 to 8 +move 1 from 6 to 1 +move 1 from 3 to 1 +move 2 from 5 to 1 +move 7 from 1 to 5 +move 5 from 1 to 3 +move 4 from 7 to 9 +move 4 from 3 to 9 +move 2 from 9 to 7 +move 6 from 9 to 2 +move 1 from 4 to 1 +move 1 from 3 to 5 +move 1 from 2 to 5 +move 5 from 9 to 4 +move 4 from 4 to 6 +move 1 from 8 to 9 +move 8 from 4 to 3 +move 7 from 7 to 3 +move 5 from 1 to 3 +move 11 from 5 to 9 +move 1 from 7 to 6 +move 2 from 3 to 5 +move 1 from 3 to 1 +move 3 from 6 to 2 +move 2 from 5 to 1 +move 2 from 1 to 2 +move 3 from 1 to 5 +move 5 from 9 to 2 +move 2 from 6 to 8 +move 2 from 3 to 8 +move 4 from 9 to 7 +move 3 from 5 to 2 +move 2 from 1 to 8 +move 1 from 9 to 8 +move 1 from 9 to 2 +move 4 from 7 to 9 +move 11 from 8 to 7 +move 1 from 8 to 2 +move 6 from 9 to 7 +move 3 from 7 to 1 +move 13 from 2 to 7 +move 24 from 7 to 1 +move 2 from 2 to 6 +move 1 from 8 to 3 +move 1 from 9 to 3 +move 5 from 2 to 4 +move 1 from 2 to 5 +move 1 from 6 to 2 +move 1 from 6 to 3 +move 1 from 2 to 4 +move 3 from 7 to 3 +move 2 from 1 to 7 +move 2 from 3 to 8 +move 2 from 7 to 8 +move 9 from 3 to 2 +move 3 from 4 to 8 +move 1 from 5 to 1 +move 9 from 2 to 1 +move 3 from 4 to 9 +move 1 from 7 to 8 +move 6 from 3 to 9 +move 2 from 1 to 5 +move 15 from 1 to 3 +move 13 from 3 to 9 +move 11 from 1 to 4 +move 5 from 4 to 1 +move 6 from 3 to 6 +move 4 from 4 to 8 +move 6 from 1 to 4 +move 1 from 5 to 2 +move 1 from 2 to 1 +move 3 from 4 to 2 +move 2 from 8 to 5 +move 2 from 4 to 2 +move 9 from 9 to 3 +move 9 from 3 to 5 +move 2 from 9 to 4 +move 5 from 2 to 6 +move 1 from 1 to 8 +move 1 from 4 to 1 +move 10 from 9 to 2 +move 9 from 2 to 4 +move 10 from 4 to 1 +move 3 from 1 to 3 +move 4 from 1 to 2 +move 5 from 2 to 4 +move 2 from 5 to 2 +move 4 from 1 to 7 +move 10 from 5 to 4 +move 2 from 2 to 4 +move 1 from 9 to 2 +move 2 from 3 to 5 +move 1 from 3 to 5 +move 3 from 6 to 7 +move 8 from 4 to 9 +move 6 from 6 to 1 +move 4 from 9 to 5 +move 2 from 9 to 1 +move 1 from 2 to 6 +move 6 from 5 to 2 +move 3 from 7 to 9 +move 4 from 8 to 2 +move 1 from 7 to 9 +move 1 from 5 to 3 +move 2 from 7 to 4 +move 1 from 7 to 1 +move 14 from 1 to 9 +move 1 from 1 to 9 +move 1 from 3 to 8 +move 3 from 2 to 5 +move 2 from 4 to 2 +move 6 from 8 to 1 +move 1 from 2 to 1 +move 5 from 1 to 9 +move 1 from 1 to 7 +move 2 from 8 to 5 +move 1 from 5 to 4 +move 1 from 6 to 1 +move 8 from 2 to 7 +move 2 from 6 to 1 +move 9 from 9 to 5 +move 11 from 4 to 8 +move 4 from 7 to 4 +move 6 from 4 to 6 +move 1 from 7 to 4 +move 6 from 6 to 7 +move 1 from 5 to 9 +move 6 from 8 to 9 +move 8 from 9 to 5 +move 1 from 4 to 5 +move 15 from 9 to 3 +move 3 from 1 to 4 +move 6 from 7 to 2 +move 3 from 4 to 9 +move 2 from 7 to 3 +move 1 from 7 to 3 +move 1 from 7 to 2 +move 2 from 8 to 1 +move 3 from 8 to 5 +move 2 from 1 to 7 +move 8 from 3 to 6 +move 3 from 6 to 5 +move 1 from 6 to 1 +move 10 from 5 to 7 +move 6 from 5 to 4 +move 4 from 2 to 4 +move 6 from 5 to 1 +move 6 from 1 to 8 +move 2 from 9 to 2 +move 2 from 9 to 7 +move 6 from 3 to 7 +move 1 from 3 to 5 +move 1 from 1 to 9 +move 2 from 8 to 1 +move 2 from 5 to 4 +move 3 from 3 to 7 +move 10 from 4 to 6 +move 1 from 9 to 7 +move 12 from 7 to 3 +move 12 from 3 to 8 +move 2 from 1 to 5 +move 1 from 1 to 3 +move 13 from 8 to 1 +move 7 from 7 to 1 +move 13 from 6 to 9 +move 1 from 7 to 4 +move 6 from 5 to 3 +move 3 from 4 to 3 +move 6 from 3 to 1 +move 10 from 9 to 4 +move 2 from 7 to 6 +move 8 from 1 to 9 +move 3 from 2 to 9 +move 1 from 3 to 5 +move 1 from 3 to 5 +move 1 from 1 to 4 +move 6 from 9 to 3 +move 2 from 6 to 7 +move 4 from 9 to 5 +move 4 from 1 to 6 +move 1 from 2 to 4 +move 6 from 1 to 4 +move 3 from 9 to 3 +move 3 from 6 to 8 +move 3 from 8 to 7 +move 5 from 5 to 1 +move 1 from 3 to 9 +move 1 from 9 to 5 +move 1 from 3 to 2 +move 2 from 5 to 1 +move 1 from 6 to 9 +move 1 from 6 to 3 +move 2 from 9 to 7 +move 2 from 8 to 1 +move 1 from 3 to 2 +move 1 from 2 to 5 +move 1 from 7 to 1 +move 7 from 7 to 9 +move 12 from 1 to 9 +move 1 from 5 to 2 +move 1 from 7 to 1 +move 13 from 4 to 7 +move 1 from 9 to 4 +move 5 from 7 to 3 +move 4 from 9 to 1 +move 8 from 7 to 9 +move 3 from 2 to 3 +move 4 from 3 to 7 +move 5 from 4 to 6 +move 3 from 9 to 4 +move 10 from 1 to 5 +move 3 from 4 to 7 +move 16 from 9 to 2 +move 3 from 9 to 2 +move 6 from 5 to 3 +move 4 from 6 to 2 +move 1 from 4 to 6 +move 2 from 6 to 8 +move 1 from 5 to 2 +move 1 from 5 to 8 +move 7 from 7 to 2 +move 16 from 2 to 1 +move 1 from 5 to 1 +move 10 from 2 to 8 +move 14 from 8 to 5 +move 2 from 2 to 6 +move 1 from 2 to 5 +move 2 from 2 to 1 +move 8 from 1 to 7 +move 4 from 1 to 7 +move 2 from 1 to 7 +move 5 from 3 to 2 +move 1 from 1 to 6 +move 2 from 2 to 5 +move 4 from 1 to 7 +move 1 from 2 to 8 +move 1 from 2 to 8 +move 3 from 6 to 7 +move 10 from 7 to 5 +move 1 from 2 to 8 +move 27 from 5 to 9 +move 1 from 5 to 6 +move 1 from 6 to 4 +move 1 from 4 to 3 +move 3 from 3 to 7 +move 4 from 3 to 6 +move 2 from 6 to 4 +move 3 from 8 to 1 +move 2 from 6 to 1 +move 12 from 7 to 8 +move 2 from 3 to 9 +move 1 from 9 to 2 +move 1 from 2 to 8 +move 2 from 1 to 2 +move 6 from 3 to 8 +move 1 from 7 to 4 +move 15 from 9 to 5 +move 7 from 9 to 4 +move 1 from 2 to 1 +move 16 from 8 to 2 +move 8 from 5 to 2 +move 24 from 2 to 9 +move 3 from 1 to 2 +move 24 from 9 to 1 +move 5 from 5 to 9 +move 3 from 4 to 1 +move 1 from 7 to 6 +move 1 from 6 to 3 +move 1 from 3 to 2 +move 3 from 2 to 3 +move 1 from 5 to 6 +move 1 from 2 to 7 diff --git a/2022/input/5/test-1 b/2022/input/5/test-1 new file mode 100644 index 0000000..84933bb --- /dev/null +++ b/2022/input/5/test-1 @@ -0,0 +1,9 @@ + [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 diff --git a/2022/src/bin/day5.rs b/2022/src/bin/day5.rs new file mode 100644 index 0000000..7377c50 --- /dev/null +++ b/2022/src/bin/day5.rs @@ -0,0 +1,189 @@ +use core::fmt; +use std::collections::HashMap; +use lazy_static::lazy_static; + +use regex::Regex; +use anyhow::Result; +use aoc::{Solver, Output}; + +// -- Runners -- +fn main() -> Result<()> { + Day::solve() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn part1_test1() -> Result<()> { + Day::test(aoc::Part::ONE, "test-1", Output::String("CMZ".to_string())) + } + #[test] + fn part2_test1() -> Result<()> { + Day::test(aoc::Part::TWO, "test-1", Output::String("MCD".to_string())) + } + #[test] + fn part1_solution() -> Result<()> { + Day::test(aoc::Part::ONE, "input", Output::String("RNZLFZSJH".to_string())) + } + #[test] + fn part2_solution() -> Result<()> { + Day::test(aoc::Part::TWO, "input", Output::String("CNSFCGJSM".to_string())) + } +} + +// -- Implementation -- +#[derive(Debug)] +struct Crate{ + letter: char, +} + +#[derive(Debug)] +struct Boat{ + stacks: HashMap>, +} + +impl fmt::Display for Boat { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + for i in 0..self.stacks.len() { + match self.top(i+1) { + Some(cr) => write!(f, "{}", cr.letter)?, + None => panic!("No crate in stack") + } + } + + Ok(()) + } +} + +impl Boat { + fn new(lines: &Vec<&str>) -> Boat { + lazy_static! { + static ref RE: Regex = Regex::new(r"\[[A-Z]\]").unwrap(); + } + + let mut boat = Boat{stacks: HashMap::new()}; + for line in lines { + for mat in RE.find_iter(line) { + let index = mat.start() / 4 + 1; + // based on the pattern [.] we get the second char + let letter = mat.as_str().chars().nth(1).unwrap(); + + boat.push(index, Crate{letter}); + } + } + + // Because of how we load the data, each stack is upside down + boat.reverse(); + + return boat; + } + + fn push(&mut self, index: usize, cr: Crate) { + let stack = self.stacks.entry(index).or_insert(vec![]); + stack.push(cr); + } + + fn pop(&mut self, index: usize) -> Option { + let stack = match self.stacks.get_mut(&index) { + Some(s) => s, + None => return None, + }; + + stack.pop() + } + + fn top(&self, index: usize) -> Option<&Crate> { + let stack = match self.stacks.get(&index) { + Some(s) => s, + None => return None, + }; + + stack.last() + } + + fn reverse(&mut self) { + for stack in self.stacks.iter_mut() { + stack.1.reverse() + } + } +} + +// -- Helpers -- + +fn parse_instruction(s: &str) -> (usize, usize, usize) { + lazy_static! { + static ref RE: Regex = Regex::new(r"move (?P[0-9]+) from (?P[0-9]) to (?P[0-9])").unwrap(); + } + + let capture = RE.captures(s).unwrap(); + + let parse_number = |name| capture.name(name).unwrap().as_str().parse::().unwrap(); + let amount: usize = parse_number("amount"); + let from: usize = parse_number("from"); + let to: usize = parse_number("to"); + + (amount, from, to) +} + +// -- Solution -- +pub struct Day; +impl aoc::Solver for Day { + fn day() -> u8 { + 5 + } + + fn part1(input: &str) -> Output { + // The current layout description ends with an empty line + let mut boat = Boat::new(&input + .lines() + .take_while(|line| !line.is_empty()) + .collect()); + + // Each instruction starts with an 'm' + input + .lines() + .skip_while(|line| !line.starts_with('m')) + .map(parse_instruction) + .for_each(|(amount, from, to)| { + for _ in 0..amount { + let cr = boat.pop(from).unwrap(); + boat.push(to, cr); + } + }); + + Output::String(boat.to_string()) + } + + fn part2(input: &str) -> Output { + // The current layout description ends with an empty line + let mut boat = Boat::new(&input + .lines() + .take_while(|line| !line.is_empty()) + .collect()); + + // Each instruction starts with an 'm' + input + .lines() + .skip_while(|line| !line.starts_with('m')) + .map(parse_instruction) + .for_each(|(amount, from, to)| { + // @TODO Is there a nicer way to do this? + let mut temp = vec![]; + + for _ in 0..amount { + let cr = boat.pop(from).unwrap(); + temp.push(cr); + } + + temp.reverse(); + + for cr in temp { + boat.push(to, cr); + } + }); + + Output::String(boat.to_string()) + } +}