-
Notifications
You must be signed in to change notification settings - Fork 0
/
day-11.rs
126 lines (109 loc) · 3.3 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
126
use std::{str::FromStr, fmt::Debug};
const INPUT: &str = include_str!("day-11.input");
struct Octopuses {
map: Vec<u8>,
next: Vec<u8>,
width: usize,
flashes: usize,
}
impl Octopuses {
fn step(&mut self) -> bool {
fn step(map: &mut [u8], w: usize, x: usize, y: usize) -> usize {
let mut flash = 0;
if map[y * w + x] != 0xff {
map[y * w + x] += 1;
if map[y * w + x] > 9 {
map[y * w + x] = 0xff;
flash += 1;
if y > 0 {
if x > 0 {
flash += step(map, w, x - 1, y - 1);
}
flash += step(map, w, x, y - 1);
if x < w - 1 {
flash += step(map, w, x + 1, y - 1);
}
}
if x > 0 {
flash += step(map, w, x - 1, y);
}
if x < w - 1 {
flash += step(map, w, x + 1, y);
}
if y < map.len() / w - 1 {
if x > 0 {
flash += step(map, w, x - 1, y + 1);
}
flash += step(map, w, x, y + 1);
if x < w - 1 {
flash += step(map, w, x + 1, y + 1);
}
}
}
}
flash
}
self.next.copy_from_slice(&self.map);
let mut new_flashes = 0;
for y in 0..self.map.len() / self.width {
for x in 0..self.width {
new_flashes += step(&mut self.next, self.width, x, y);
}
}
self.flashes += new_flashes;
for (&i, n) in self.next.iter().zip(self.map.iter_mut()) {
*n = if i == 0xff { 0 } else { i };
}
new_flashes == self.map.len()
}
}
impl FromStr for Octopuses {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut width = 0;
let map: Vec<_> = s
.trim()
.lines()
.flat_map(|line| {
let line: Vec<_> = line.trim().chars().map(|c| c as u8 - b'0').collect();
if width != 0 {
assert_eq!(width, line.len())
} else {
width = line.len();
}
line
})
.collect();
let n = map.len();
Ok(Self {
map,
next: vec![0; n],
width,
flashes: 0,
})
}
}
impl Debug for Octopuses {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
for y in 0..self.map.len()/self.width {
for x in 0..self.width {
let i = self.map[y * self.width + x];
write!(f, "{}", i)?;
}
writeln!(f)?;
}
Ok(())
}
}
fn main() {
let mut octopuses: Octopuses = INPUT.parse().unwrap();
for _ in 0..100 {
octopuses.step();
}
println!("part 1: {}", octopuses.flashes);
let mut i = 101;
while !octopuses.step() {
i += 1;
}
println!("part 2: {}", i);
}