From 9faaad81d3e4bcc467b6f9a18559048686813280 Mon Sep 17 00:00:00 2001 From: Greg Burri Date: Mon, 5 Dec 2022 12:09:19 +0100 Subject: [PATCH] Day 5 --- src/day05.rs | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 10 +++++ 2 files changed, 121 insertions(+) create mode 100644 src/day05.rs diff --git a/src/day05.rs b/src/day05.rs new file mode 100644 index 0000000..3a0f1bc --- /dev/null +++ b/src/day05.rs @@ -0,0 +1,111 @@ +use std::collections::VecDeque; + +use regex::Regex; + +type Stacks = Vec>; + +pub struct Move { + n: usize, + from: usize, + to: usize, +} + +pub fn parse(s: &str) -> (Stacks, Vec) { + let mut stacks = Vec::new(); + let mut lines = s.lines(); + while let Some(line) = lines.next() { + let chars: Vec = line.trim_end().chars().collect(); + if chars[1] == '1' { + break; + } + let n = (chars.len() + 1) / 4; + for _ in stacks.len()..n { + stacks.push(VecDeque::new()); + } + + for i in 0..n { + let pos_char = i * 4 + 1; + if chars[pos_char] != ' ' { + stacks[i].push_front(chars[pos_char]); + } + } + } + + lines.next(); // Drop the empty line. + + let r = Regex::new(r"move (\d+) from (\d+) to (\d+)").unwrap(); + let mut moves = Vec::new(); + while let Some(line) = lines.next() { + let cap = r.captures(line).unwrap(); + moves.push(Move { n: cap[1].parse().unwrap(), from: cap[2].parse::().unwrap() - 1, to: cap[3].parse::().unwrap() - 1 }); + } + + (stacks, moves) +} + +pub fn apply_moves_by_crate_mover_9000(stacks: &mut Stacks, moves: &[Move]) { + for m in moves { + for _ in 0..m.n { + if let Some(c) = stacks[m.from].pop_back() { + stacks[m.to].push_back(c); + } else { + break; + } + } + } +} + +pub fn apply_moves_by_crate_mover_9001(stacks: &mut Stacks, moves: &[Move]) { + for m in moves { + let from = stacks.get_mut(m.from).unwrap(); + let mut to_move = from.split_off(from.len() - m.n); + stacks[m.to].append(&mut to_move); + } +} + +pub fn get_top_as_string(stacks: &Stacks) -> String { + let mut result = String::new(); + for stack in stacks { + if let Some(c) = stack.back() { + result.push(*c); + } + } + result +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn part1() { + let stacks_and_moves =" [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"; + let (mut stacks, moves) = parse(stacks_and_moves); + apply_moves_by_crate_mover_9000(&mut stacks, &moves); + assert_eq!(get_top_as_string(&stacks), "CMZ"); + } + + #[test] + fn part2() { + let stacks_and_moves =" [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"; + let (mut stacks, moves) = parse(stacks_and_moves); + apply_moves_by_crate_mover_9001(&mut stacks, &moves); + assert_eq!(get_top_as_string(&stacks), "MCD"); + } +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 014c31d..8fbe072 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ mod day01; mod day02; mod day03; mod day04; +mod day05; fn day01() -> String { let f = fs::File::open("data/day01.input").unwrap(); @@ -30,6 +31,14 @@ fn day04() -> String { format!("part1: {}, part2: {}", day04::number_fully_contain(&pairs), day04::number_overlaps(&pairs)) } +fn day05() -> String { + let (mut stacks, moves) = day05::parse(&fs::read_to_string("data/day05.input").unwrap()); + let mut stacks2 = stacks.clone(); + day05::apply_moves_by_crate_mover_9000(&mut stacks, &moves); + day05::apply_moves_by_crate_mover_9001(&mut stacks2, &moves); + format!("part1: {}, part2: {}", day05::get_top_as_string(&stacks), day05::get_top_as_string(&stacks2)) +} + fn format_micros(t: u128) -> String { if t < 10_000 { format!("{} μs", t) @@ -53,6 +62,7 @@ fn main() { day02, day03, day04, + day05, ); let args: Vec = env::args().skip(1).collect(); -- 2.45.2