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
|
use std::collections::HashSet;
static DAY: u8 = 14;
fn main() {
let input = advent::read_lines(DAY);
println!("{DAY}a: {}", total_load(&input));
println!("{DAY}b: {}", 0);
}
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
struct Position {
x: isize,
y: isize,
}
struct Map {
round_rocks: HashSet<Position>,
cube_rocks: HashSet<Position>,
_width: isize,
height: isize,
}
impl Map {
fn new(input: &[String]) -> Map {
let mut round_rocks = HashSet::new();
let mut cube_rocks = HashSet::new();
for (y, line) in input.iter().enumerate() {
for (x, rock) in line.chars().enumerate() {
let pos = Position { x: x as isize, y: y as isize };
match rock {
'#' => { cube_rocks.insert(pos); }
'O' => { round_rocks.insert(pos); }
_ => {},
}
}
}
Map { round_rocks, cube_rocks, _width: input[0].len() as isize, height: input.len() as isize }
}
fn tilt(&mut self) {
loop {
let mut round_rocks = self.round_rocks.clone();
for rock in &self.round_rocks {
round_rocks.remove(rock);
let mut new_pos = *rock;
for y in (0 .. rock.y).rev() {
let pos = Position { x: rock.x, y };
if self.cube_rocks.contains(&pos) || round_rocks.contains(&pos) {
break;
}
new_pos = pos;
}
round_rocks.insert(new_pos);
}
if self.round_rocks == round_rocks {
break;
}
self.round_rocks = round_rocks;
}
}
fn load(&self) -> isize {
self.round_rocks.iter()
.map(|rock| self.height - rock.y)
.sum()
}
}
fn total_load(input: &[String]) -> isize {
let mut map = Map::new(input);
map.tilt();
map.load()
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
let input = [
"O....#....",
"O.OO#....#",
".....##...",
"OO.#O....O",
".O.....O#.",
"O.#..O.#.#",
"..O..#O..O",
".......O..",
"#....###..",
"#OO..#....",
].iter().map(|&x| String::from(x)).collect::<Vec<_>>();
assert_eq!(total_load(&input), 136);
}
}
|