-
Notifications
You must be signed in to change notification settings - Fork 0
/
day05.rs
124 lines (109 loc) · 3.39 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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#[derive(Debug)]
pub struct Instructions {
num: usize,
from: usize,
to: usize,
}
trait Stax {
fn hanoi_pt1(&mut self, instr: &[Instructions]);
fn hanoi_pt2(&mut self, instr: &[Instructions]);
fn tops(&self) -> String;
fn uno_reverse_card(&mut self);
}
impl Stax for Vec<Vec<char>> {
fn hanoi_pt1(&mut self, instr: &[Instructions]) {
for instr in instr {
for _ in 0..instr.num {
let reloc = self[instr.from - 1].pop().unwrap();
self[instr.to - 1].push(reloc);
}
}
}
fn hanoi_pt2(&mut self, instr: &[Instructions]) {
for instr in instr {
let cut_loc = self[instr.from - 1].len().saturating_sub(instr.num);
let reloc = self[instr.from - 1].split_off(cut_loc);
self[instr.to - 1].extend(reloc);
}
}
fn tops(&self) -> String {
self.into_iter()
.filter_map(|inner| inner.last())
.collect()
}
fn uno_reverse_card(&mut self) {
for vec in self.iter_mut() {
vec.reverse();
}
}
}
#[aoc_generator(day5)]
pub fn input_generator(input: &str) -> (Vec<Vec<char>>, Vec<Instructions>) {
input
.split_once("\n\n")
.map(|(stacks, instr)| (
{
let num_cols = stacks.lines().last().unwrap().len();
let (new_stacks, last_line) = stacks.trim_end().rsplit_once('\n').unwrap();
let num_stacks = last_line.trim().chars().last().unwrap().to_digit(10).unwrap() as usize;
let mut all_stacks = vec![vec![]; num_stacks];
for line in new_stacks.lines() {
let line_chars: Vec<char> = line.chars().collect();
for c in (1..num_cols-1).step_by(4) {
if line_chars[c] != ' ' {
let stack = (c - 1) / 4;
all_stacks[stack].push(line_chars[c]);
}
}
}
all_stacks.uno_reverse_card();
all_stacks
},
instr
.lines()
.map(|line| {
let mut parts = line
.split_whitespace()
.filter_map(|part| part.parse::<usize>().ok());
Instructions {
num: parts.next().unwrap(),
from: parts.next().unwrap(),
to: parts.next().unwrap(),
}
})
.collect()
))
.unwrap()
}
#[aoc(day5, part1)]
pub fn solve_part1((input_stacks, instr): &(Vec<Vec<char>>, Vec<Instructions>)) -> String {
let mut stax = input_stacks.clone();
stax.hanoi_pt1(instr);
stax.tops()
}
#[aoc(day5, part2)]
pub fn solve_part2((input_stacks, instr): &(Vec<Vec<char>>, Vec<Instructions>)) -> String {
let mut stax = input_stacks.clone();
stax.hanoi_pt2(instr);
stax.tops()
}
#[cfg(test)]
mod tests {
use super::*;
const TEST: &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_test() {
assert_eq!(solve_part1(&input_generator(TEST)), "CMZ");
}
#[test]
fn part2_test() {
assert_eq!(solve_part2(&input_generator(TEST)), "MCD");
}
}