-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathday_11.rs
125 lines (99 loc) Β· 2.4 KB
/
day_11.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
125
use common::{solution, Answer};
solution!("Dumbo Octopus", 11);
fn part_a(input: &str) -> Answer {
let mut octopi = parse(input);
(0..100)
.map(|_| step_octopi(&mut octopi))
.sum::<usize>()
.into()
}
fn part_b(input: &str) -> Answer {
let mut octopi = parse(input);
let octopi_count = octopi.len() * octopi[0].len();
let mut i = 0;
loop {
i += 1;
let flash = step_octopi(&mut octopi);
if flash == octopi_count {
break;
}
}
i.into()
}
struct Octopus {
state: u8,
flashed: bool,
}
impl Octopus {
fn tick(&mut self) -> bool {
if self.flashed {
return false;
}
self.state += 1;
if self.state > 9 {
self.state = 0;
self.flashed = true;
return true;
}
false
}
}
fn step_octopi(octopi: &mut Vec<Vec<Octopus>>) -> usize {
for y in 0..octopi.len() {
for x in 0..octopi[0].len() {
tick_octopi(octopi, x, y);
}
}
let mut flash = 0;
for i in octopi.iter_mut() {
for j in i.iter_mut() {
if j.flashed {
flash += 1;
}
j.flashed = false;
}
}
flash
}
fn tick_octopi(octopi: &mut Vec<Vec<Octopus>>, x: usize, y: usize) {
let flash = octopi[y][x].tick();
if !flash {
return;
}
for i in octo_neighbors(octopi, x, y) {
tick_octopi(octopi, i.0, i.1);
}
}
fn octo_neighbors(octopi: &[Vec<Octopus>], x: usize, y: usize) -> Vec<(usize, usize)> {
let mut out = Vec::new();
let (lenx, leny) = (octopi[0].len() as isize, octopi.len() as isize);
let (x, y) = (x as isize, y as isize);
for i in 0..3 {
for j in 0..3 {
if i == 1 && j == 1 {
continue;
}
let x = x + i - 1;
let y = y + j - 1;
if x < 0 || y < 0 || x >= lenx || y >= leny {
continue;
}
out.push((x as usize, y as usize));
}
}
out
}
fn parse(raw: &str) -> Vec<Vec<Octopus>> {
let mut out = Vec::new();
for i in raw.lines() {
out.push(
i.chars()
.map(|x| Octopus {
state: x.to_digit(10).unwrap() as u8,
flashed: false,
})
.collect(),
);
}
out
}