master
Elias Almqvist 2 years ago
parent 0a60c515ff
commit f82b65472b
  1. 33
      2022/Cargo.lock
  2. 1
      2022/Cargo.toml
  3. 143
      2022/src/bin/05.rs
  4. 9
      2022/src/examples/05.txt
  5. 10
      2022/src/helpers.rs

33
2022/Cargo.lock generated

@ -7,10 +7,43 @@ name = "advent_of_code"
version = "0.8.0" version = "0.8.0"
dependencies = [ dependencies = [
"pico-args", "pico-args",
"regex",
] ]
[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]] [[package]]
name = "pico-args" name = "pico-args"
version = "0.5.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]]
name = "regex"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"

@ -9,3 +9,4 @@ publish = false
[dependencies] [dependencies]
pico-args = "0.5.0" pico-args = "0.5.0"
regex = "1.7.0"

@ -0,0 +1,143 @@
use advent_of_code::helpers::transpose;
use regex::Regex;
type Stack = Vec<char>;
fn split_input(input: &str) -> (&str, &str) {
let splitted: Vec<&str> = input.split("\n\n").collect();
(splitted[0], splitted[1])
}
fn build_stack(stack_str: &str) -> Stack {
let stack_regex_builder = Regex::new(r"[A-Z]").unwrap();
let matches: Vec<&str> = stack_regex_builder
.find_iter(stack_str)
.map(|m| m.as_str())
.collect();
let mut stack = Stack::new();
for cr in matches[0..].iter() {
stack.push(cr.chars().next().unwrap());
}
stack
}
fn create_stacks(stack_input: &str) -> Vec<Stack> {
let lines: Vec<Vec<char>> = stack_input
.lines()
.map(|txt| txt.chars().collect::<Vec<char>>())
.map(|line| format!("{:>10}", line.iter().collect::<String>()))
.map(|line| line.chars().collect::<Vec<char>>())
.collect();
let transpose_regex_filter = Regex::new(r"[A-Z]+\d+").unwrap();
let transposed_lines: Vec<String> = transpose(lines)
.iter()
.map(String::from_iter)
.filter(|s| transpose_regex_filter.is_match(s))
.map(|s| s.chars().rev().collect())
.collect();
let stacks: Vec<&str> = transposed_lines.iter().map(|s| s.trim()).collect();
let stacks: Vec<Stack> = stacks.iter().map(|s| build_stack(s)).collect();
stacks
}
fn parse_ins(ins: &str) -> (u32, u32, u32) {
let opcode_regex = Regex::new(r"\d+").unwrap();
let opcodes: Vec<u32> = opcode_regex
.find_iter(ins)
.map(|m| m.as_str())
.map(|s| s.parse::<u32>().unwrap())
.collect();
(opcodes[0], opcodes[1] - 1, opcodes[2] - 1)
}
fn perform_ins(stacks: &mut Vec<Stack>, ins: &str) {
let (amount, src, dest) = parse_ins(ins);
for _ in 0..amount {
let transfer_value = stacks[src as usize].pop().unwrap();
stacks[dest as usize].push(transfer_value);
}
}
pub fn part_one(input: &str) -> Option<String> {
let (stack_input, instructions_input) = split_input(input);
let mut stacks = create_stacks(stack_input);
for ins in instructions_input.lines() {
perform_ins(&mut stacks, ins);
}
let tops: Vec<char> = stacks
.iter()
.map(|stack| *stack.last().unwrap_or(&' '))
.collect();
let output: String = tops.iter().collect();
Some(output)
}
fn perform_ins_9001(stacks: &mut Vec<Stack>, ins: &str) {
let (amount, src, dest) = parse_ins(ins);
let mut cont_buffer: Vec<char> = Vec::new();
for _ in 0..amount {
let transfer_value = stacks[src as usize].pop().unwrap();
cont_buffer.push(transfer_value);
}
cont_buffer.reverse();
stacks[dest as usize].append(&mut cont_buffer);
}
pub fn part_two(input: &str) -> Option<String> {
let (stack_input, instructions_input) = split_input(input);
let mut stacks = create_stacks(stack_input);
for ins in instructions_input.lines() {
perform_ins_9001(&mut stacks, ins);
}
let tops: Vec<char> = stacks
.iter()
.map(|stack| *stack.last().unwrap_or(&' '))
.collect();
let output: String = tops.iter().collect();
Some(output)
}
fn main() {
let input = &advent_of_code::read_file("inputs", 5); // inputs
advent_of_code::solve!(1, part_one, input);
advent_of_code::solve!(2, part_two, input);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_part_one() {
let input = advent_of_code::read_file("examples", 5);
assert_eq!(part_one(&input), Some(String::from("CMZ")));
}
#[test]
fn test_part_two() {
let input = advent_of_code::read_file("examples", 5);
assert_eq!(part_two(&input), Some(String::from("MCD")));
}
}

@ -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

@ -9,3 +9,13 @@ where
{ {
input.lines().map(cons).collect() input.lines().map(cons).collect()
} }
pub fn transpose<T>(v: Vec<Vec<T>>) -> Vec<Vec<T>>
where
T: Clone,
{
assert!(!v.is_empty());
(0..v[0].len())
.map(|i| v.iter().map(|inner| inner[i].clone()).collect::<Vec<T>>())
.collect()
}

Loading…
Cancel
Save