Add 2022/05
This commit is contained in:
parent
4e7420463d
commit
5a86a400ef
|
@ -3,27 +3,93 @@ extern crate test;
|
|||
use aoc2022::{boilerplate, common::*};
|
||||
|
||||
const DAY: usize = 5;
|
||||
type Parsed = Vec<usize>;
|
||||
type Parsed = (Vec<Vec<u8>>, Vec<Move>);
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Move {
|
||||
n: usize,
|
||||
src: usize,
|
||||
dst: usize,
|
||||
}
|
||||
|
||||
fn parse_input(raw: &str) -> Parsed {
|
||||
parse_nums(raw)
|
||||
let mut lines = raw.lines();
|
||||
let mut raw_stacks = Vec::new();
|
||||
let stack_numbers = loop {
|
||||
match lines.next() {
|
||||
Some(line) if line.contains('[') => raw_stacks.push(line),
|
||||
Some(line) => break line,
|
||||
None => unreachable!(),
|
||||
}
|
||||
};
|
||||
let num_stacks = (stack_numbers.trim().bytes().last().unwrap() - b'0') as usize;
|
||||
let mut stacks = vec![vec![]; num_stacks];
|
||||
for s in raw_stacks.iter().rev() {
|
||||
for n in 0..num_stacks {
|
||||
match s.as_bytes().get(1 + 4 * n) {
|
||||
Some(b' ') | None => (),
|
||||
Some(&c) => stacks[n].push(c),
|
||||
}
|
||||
}
|
||||
}
|
||||
let moves = lines
|
||||
.skip(1)
|
||||
.map(|l| {
|
||||
let (n, pos) = l[5..].split_once(" from ").unwrap();
|
||||
let (src, dst) = pos.split_once(" to ").unwrap();
|
||||
Move { n: parse_num(n), src: parse_num::<usize>(src) - 1, dst: parse_num::<usize>(dst) - 1 }
|
||||
})
|
||||
.collect();
|
||||
(stacks, moves)
|
||||
}
|
||||
|
||||
fn part1(parsed: &Parsed) -> usize {
|
||||
unimplemented!()
|
||||
fn part1((stacks, moves): &Parsed) -> String {
|
||||
let mut stacks = stacks.to_owned();
|
||||
for mov in moves {
|
||||
for _ in 0..(mov.n) {
|
||||
let e = stacks[mov.src].pop().unwrap();
|
||||
stacks[mov.dst].push(e);
|
||||
}
|
||||
}
|
||||
stacks.iter().filter_map(|s| s.last()).map(|&b| b as char).collect()
|
||||
}
|
||||
|
||||
fn part2(parsed: &Parsed) -> usize {
|
||||
unimplemented!()
|
||||
fn part2((stacks, moves): &Parsed) -> String {
|
||||
let mut stacks = stacks.to_owned();
|
||||
let mut temp = Vec::new();
|
||||
for mov in moves {
|
||||
// Sadly can’t drain from one into the other because the compiler doesn’t know
|
||||
// src and dst are always different :feelsBadMan:
|
||||
let start_index = stacks[mov.src].len() - mov.n;
|
||||
temp.extend(stacks[mov.src].drain(start_index..));
|
||||
for e in temp.drain(..) {
|
||||
stacks[mov.dst].push(e);
|
||||
}
|
||||
}
|
||||
stacks.iter().filter_map(|s| s.last()).map(|&b| b as char).collect()
|
||||
}
|
||||
|
||||
boilerplate! {
|
||||
TEST_INPUT == "",
|
||||
TEST_INPUT ==
|
||||
" [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",
|
||||
tests: {
|
||||
part1: { TEST_INPUT => 0 },
|
||||
part2: { TEST_INPUT => 0 },
|
||||
part1: { TEST_INPUT => "CMZ" },
|
||||
part2: { TEST_INPUT => "MCD" },
|
||||
},
|
||||
bench1 == 0,
|
||||
bench2 == 0,
|
||||
bench_parse: Vec::len => 0,
|
||||
bench1 == "QMBMJDFTD",
|
||||
bench2 == "NBTVTJNFJ",
|
||||
bench_parse: check_input => 504,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn check_input((_, moves): &Parsed) -> usize {
|
||||
moves.len()
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ macro_rules! boilerplate {
|
|||
|
||||
$($(paste::paste! {
|
||||
#[test]
|
||||
fn [<$part _test_ $to>]() {
|
||||
fn [<$part _test_ $to:lower>]() {
|
||||
let input = parse_input($tpi);
|
||||
assert_eq!($part(&input), $to);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user