From d75c49e8c4ed4d8904a124ff06680bf7eb6da255 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Mon, 5 Dec 2022 06:39:20 +0100 Subject: [PATCH] 2022 day5/rust: add solution --- 2022/day5/rust/Cargo.toml | 10 ++++ 2022/day5/rust/src/main.rs | 109 +++++++++++++++++++++++++++++++++++++ Cargo.lock | 19 +++++++ Cargo.toml | 1 + 4 files changed, 139 insertions(+) create mode 100644 2022/day5/rust/Cargo.toml create mode 100644 2022/day5/rust/src/main.rs diff --git a/2022/day5/rust/Cargo.toml b/2022/day5/rust/Cargo.toml new file mode 100644 index 0000000..27430f5 --- /dev/null +++ b/2022/day5/rust/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "rust_2022_05" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +aoc = { path = "../../../common/rust" } +regex = "1.7.0" diff --git a/2022/day5/rust/src/main.rs b/2022/day5/rust/src/main.rs new file mode 100644 index 0000000..cf6a6cd --- /dev/null +++ b/2022/day5/rust/src/main.rs @@ -0,0 +1,109 @@ +#![warn(clippy::pedantic)] + +use std::io::{stdin, Read}; + +use regex::Regex; + +fn main() { + let mut data = String::new(); + stdin().read_to_string(&mut data).unwrap(); + + let mut lines = data.lines(); + + let mut stacks = Vec::new(); + + for line in &mut lines { + if !line.contains('[') { + lines.next(); + break; + } + + for (i, crate_) in line.as_bytes().chunks(4).enumerate() { + if stacks.len() <= i { + stacks.push(vec![]); + } + + if crate_.iter().all(|&c| c == b' ') { + // empty space + continue; + } + + let crate_ = crate_.strip_suffix(b" ").unwrap_or(crate_); + + let Some([crate_]) = crate_ + .strip_prefix(b"[") + .and_then(|crate_| crate_.strip_suffix(b"]")) + else { + panic!("invalid crate {:?} {}", crate_, std::str::from_utf8(crate_).unwrap()); + }; + + stacks[i].push(*crate_ as char); + } + } + + for stack in &mut stacks { + stack.reverse(); + } + + let stacks = stacks; + let mut stacks_9000 = stacks.clone(); + let mut stacks_9001 = stacks; + + let regex = Regex::new(r"move (\d+) from (\d+) to (\d+)").unwrap(); + for line in lines { + let matches = regex.captures(line).unwrap(); + + let amount: usize = matches[1].parse().unwrap(); + let source: usize = matches[2].parse().unwrap(); + let dest: usize = matches[3].parse().unwrap(); + + let source = source - 1; + let dest = dest - 1; + + { + let (p1, p2) = stacks_9000.split_at_mut(usize::max(source, dest)); + + let (source, dest) = if source < dest { + (&mut p1[source], &mut p2[0]) + } else { + (&mut p2[0], &mut p1[dest]) + }; + + let sourceidx = source.len() - amount; + + dest.extend(source[sourceidx..].iter().copied().rev()); + source.truncate(sourceidx); + } + + { + let (p1, p2) = stacks_9001.split_at_mut(usize::max(source, dest)); + + let (source, dest) = if source < dest { + (&mut p1[source], &mut p2[0]) + } else { + (&mut p2[0], &mut p1[dest]) + }; + + let sourceidx = source.len() - amount; + + dest.extend(source[sourceidx..].iter().copied()); + source.truncate(sourceidx); + } + } + + println!( + "{}", + stacks_9000 + .iter() + .map(|s| s.last().unwrap()) + .collect::() + ); + + println!( + "{}", + stacks_9001 + .iter() + .map(|s| s.last().unwrap()) + .collect::() + ); +} diff --git a/Cargo.lock b/Cargo.lock index dc9d942..276ab35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + [[package]] name = "aoc" version = "0.1.0" @@ -392,6 +401,8 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" dependencies = [ + "aho-corasick", + "memchr", "regex-syntax", ] @@ -484,6 +495,14 @@ dependencies = [ "aoc", ] +[[package]] +name = "rust_2022_05" +version = "0.1.0" +dependencies = [ + "aoc", + "regex", +] + [[package]] name = "ryu" version = "1.0.11" diff --git a/Cargo.toml b/Cargo.toml index 4daf70a..f0083d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,4 +14,5 @@ members = [ "2022/day2/rust", "2022/day3/rust", "2022/day4/rust", + "2022/day5/rust", ]