113 lines
2.6 KiB
Rust
113 lines
2.6 KiB
Rust
use std::cmp::max;
|
|
use std::str::FromStr;
|
|
|
|
use aoc_2022::*;
|
|
|
|
type Input = Ship;
|
|
type Output = String;
|
|
|
|
#[derive(Debug)]
|
|
struct Move {
|
|
count: usize,
|
|
from: usize,
|
|
to: usize,
|
|
}
|
|
|
|
impl FromStr for Move {
|
|
type Err = Report;
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
let split_str: Vec<_> = s.split_whitespace().collect();
|
|
let ints = vec![split_str[1], split_str[3], split_str[5]]
|
|
.iter()
|
|
.map(|x| x.parse::<usize>().unwrap())
|
|
.collect_vec();
|
|
|
|
let (count, from, to) = (ints[0], ints[1], ints[2]);
|
|
|
|
Ok(Move { count, from, to })
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct Ship(Vec<Vec<char>>, Vec<Move>);
|
|
|
|
impl FromStr for Ship {
|
|
type Err = Report;
|
|
|
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
|
let split_s = s.split("\n\n").collect_vec();
|
|
let (stacks_str, moves_str) = (split_s[0], split_s[1]);
|
|
|
|
let mut stacks: Vec<Vec<char>> = Vec::new();
|
|
stacks_str
|
|
.lines()
|
|
.rev()
|
|
.skip(1)
|
|
.map(|l| l.to_string() + " ")
|
|
.for_each(|l| {
|
|
l.chars().skip(1).step_by(4).enumerate().for_each(|(i, c)| {
|
|
if i >= stacks.len() {
|
|
stacks.push(Vec::new());
|
|
}
|
|
|
|
if c != ' ' {
|
|
stacks[i].push(c);
|
|
}
|
|
});
|
|
});
|
|
|
|
let moves = strings_to_structs(moves_str.lines());
|
|
|
|
Ok(Ship(stacks, moves))
|
|
}
|
|
}
|
|
|
|
fn stacks_to_string(stacks: &[Vec<char>]) -> String {
|
|
stacks.iter().fold(String::new(), |acc, stack| {
|
|
if let Some(c) = stack.last() {
|
|
acc + &c.to_string()
|
|
} else {
|
|
acc
|
|
}
|
|
})
|
|
}
|
|
|
|
fn move_crates(input: &Input, one_by_one: bool) -> Output {
|
|
let Ship(stacks, moves) = input;
|
|
let mut stacks = stacks.clone();
|
|
|
|
moves.iter().for_each(|m| {
|
|
let size = stacks[m.from - 1].len();
|
|
let mut s = stacks[m.from - 1].split_off(max(0, size - m.count));
|
|
|
|
if one_by_one {
|
|
s.reverse();
|
|
}
|
|
|
|
stacks[m.to - 1].append(&mut s);
|
|
});
|
|
|
|
stacks_to_string(&stacks)
|
|
}
|
|
|
|
struct Day05;
|
|
impl Solution<Input, Output> for Day05 {
|
|
fn parse_input<P: AsRef<Path>>(pathname: P) -> Input {
|
|
file_to_string(pathname).parse().unwrap()
|
|
}
|
|
|
|
fn part_1(input: &Input) -> Output {
|
|
move_crates(input, true)
|
|
}
|
|
|
|
fn part_2(input: &Input) -> Output {
|
|
move_crates(input, false)
|
|
}
|
|
}
|
|
|
|
fn main() -> Result<()> {
|
|
Day05::main()
|
|
}
|
|
|
|
test_sample!(day_05, Day05, "CMZ".to_string(), "MCD".to_string());
|