-
Notifications
You must be signed in to change notification settings - Fork 0
/
day05.rs
109 lines (93 loc) · 2.61 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
use std::collections::LinkedList;
fn parse_crates(input: &str) -> Vec<LinkedList<char>> {
let mut input = input.lines();
// Consume last line first
let crate_count = input
.next_back()
.unwrap()
.split(' ')
.filter(|e| !e.is_empty())
.count();
let mut crates: Vec<LinkedList<char>> = Vec::with_capacity(crate_count);
for _ in 0..crate_count {
crates.push(LinkedList::new());
}
for l in input {
for (i, c) in l.as_bytes().chunks(4).enumerate() {
if c[1] != b' ' {
crates.get_mut(i).unwrap().push_front(c[1] as char);
}
}
}
crates
}
fn parse_moves(input: &str) -> Vec<(usize, usize, usize)> {
input
.lines()
.map(|l| {
let mut digits = l
.split(' ')
.skip(1)
.step_by(2)
.map(|d| d.parse::<usize>().unwrap());
(
digits.next().unwrap(),
digits.next().unwrap() - 1,
digits.next().unwrap() - 1,
)
})
.collect()
}
pub fn part_one(input: &str) -> String {
let mut input = input.split("\n\n");
let mut crates = parse_crates(input.next().unwrap());
let moves = parse_moves(input.next().unwrap());
for (count, from, to) in moves {
let from = &mut crates[from];
let take = from.split_off(from.len() - count);
crates[to].extend(take.iter().rev())
}
crates.iter().filter_map(|ll| ll.back()).collect()
}
pub fn part_two(input: &str) -> String {
let mut input = input.split("\n\n");
let mut crates = parse_crates(input.next().unwrap());
let moves = parse_moves(input.next().unwrap());
for (count, from, to) in moves {
let from = &mut crates[from];
let mut take = from.split_off(from.len() - count);
crates[to].append(&mut take);
}
crates.iter().filter_map(|ll| ll.back()).collect()
}
#[cfg(test)]
mod tests {
#[test]
fn part_one_example() {
assert_eq!(
super::part_one(include_str!("input/day05_example.txt")),
"CMZ"
);
}
#[test]
fn part_one() {
assert_eq!(
super::part_one(include_str!("input/day05.txt")),
"JCMHLVGMG"
);
}
#[test]
fn part_two_example() {
assert_eq!(
super::part_two(include_str!("input/day05_example.txt")),
"MCD"
);
}
#[test]
fn part_two() {
assert_eq!(
super::part_two(include_str!("input/day05.txt")),
"LVMRWSSPZ"
);
}
}