AdventOfCode/y2022/src/days/d5.rs

111 lines
2.7 KiB
Rust

fn is_string_numeric(str: &str) -> bool {
for c in str.chars() {
if !c.is_numeric() {
return false;
}
}
true
}
fn parse_move(crane_move: &str) -> (usize, usize, usize) {
let mut crane_move = crane_move
.split(" ")
.filter(|s| is_string_numeric(s))
.map(|m| m.parse::<usize>().unwrap());
(
crane_move.next().unwrap(),
crane_move.next().unwrap() - 1,
crane_move.next().unwrap() - 1,
)
}
fn parse_moves(crane_moves: &str) -> Vec<(usize, usize, usize)> {
crane_moves.lines().map(parse_move).collect()
}
fn parse_stacks(stacks: &str) -> Vec<String> {
let mut lines: Vec<&str> = stacks.lines().collect();
let mut last_line = lines.pop().unwrap().trim().to_string();
let num_stacks = last_line.pop().unwrap().to_digit(10).unwrap();
let mut parsed_stacks = vec!["".to_string(); num_stacks as usize];
for line in lines {
for (idx, c) in line.chars().skip(1).step_by(4).enumerate() {
if c.is_alphabetic() {
parsed_stacks[idx].insert(0, c);
}
}
}
parsed_stacks
}
pub fn process_part1(input: &str) -> String {
let (stacks, crane_moves) = input.split_once("\n\n").unwrap();
let mut stacks = parse_stacks(stacks);
let crane_moves = parse_moves(crane_moves);
for (iterations, from, to) in crane_moves {
for _i in 0..iterations {
let popped = stacks[from].pop().unwrap();
stacks[to].push(popped);
}
}
let mut result = "".to_string();
for mut stack in stacks {
result.push(stack.pop().unwrap());
}
result
}
pub fn process_part2(input: &str) -> String {
let (stacks, crane_moves) = input.split_once("\n\n").unwrap();
let mut stacks = parse_stacks(stacks);
let crane_moves = parse_moves(crane_moves);
for (iterations, from, to) in crane_moves {
let from_len = stacks[from].len();
let from_old = stacks[from].clone();
let (new_from, popped) = from_old.split_at(from_len - iterations);
stacks[from] = new_from.to_string();
stacks[to].push_str(popped);
}
let mut result = "".to_string();
for mut stack in stacks {
result.push(stack.pop().unwrap());
}
result
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT: &str = " [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";
#[test]
fn part1() {
let result = process_part1(INPUT);
assert_eq!(result, "CMZ");
}
#[test]
fn part2() {
let result = process_part2(INPUT);
assert_eq!(result, "MCD");
}
}