-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathday05.rs
56 lines (46 loc) · 1.4 KB
/
day05.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use crate::util::iter::*;
use crate::util::parse::*;
type Stack = Vec<Vec<char>>;
type Move = [usize; 3];
type Input = (Stack, Vec<Move>);
pub fn parse(input: &str) -> Input {
let (prefix, suffix) = input.split_once("\n\n").unwrap();
let lines: Vec<&str> = prefix.lines().collect();
let width = (lines[0].len() + 1) / 4;
let mut stack: Stack = vec![Vec::new(); width];
for row in lines.iter().rev() {
for (i, c) in row.chars().skip(1).step_by(4).enumerate() {
if c != ' ' {
stack[i].push(c);
}
}
}
let moves: Vec<Move> = suffix
.iter_unsigned()
.chunk::<3>()
.map(|[amount, from, to]| [amount, from - 1, to - 1])
.collect();
(stack, moves)
}
pub fn part1(input: &Input) -> String {
play(input, true)
}
pub fn part2(input: &Input) -> String {
play(input, false)
}
fn play(input: &Input, reverse: bool) -> String {
let (initial, moves) = input;
let mut stack = initial.clone();
let mut crates: Vec<char> = Vec::new();
for &[amount, from, to] in moves {
let start = stack[from].len() - amount;
crates.extend(stack[from].drain(start..));
if reverse {
stack[to].extend(crates.iter().rev());
} else {
stack[to].extend(crates.iter());
}
crates.clear();
}
stack.iter().map(|v| v.last().unwrap()).collect()
}