-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.rs
127 lines (109 loc) · 3.21 KB
/
main.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
127
use std::{
collections::HashSet,
fmt,
io::{self, BufRead},
};
use rusttype::Point as RPoint;
type Filter = Vec<bool>;
type Point = RPoint<i32>;
struct Map {
pub hashset: HashSet<Point>,
pub min_x: i32,
pub max_x: i32,
pub min_y: i32,
pub max_y: i32,
pub outside_cell_state: bool,
}
impl Map {
pub fn new() -> Self {
Self {
hashset: HashSet::new(),
min_x: 0,
max_x: 0,
min_y: 0,
max_y: 0,
outside_cell_state: false,
}
}
pub fn insert(&mut self, p: Point) {
self.min_x = if p.x < self.min_x { p.x } else { self.min_x };
self.max_x = if p.x > self.max_x { p.x } else { self.max_x };
self.min_y = if p.y < self.min_y { p.y } else { self.min_y };
self.max_y = if p.y > self.max_y { p.y } else { self.max_y };
self.hashset.insert(p);
}
pub fn calc_filter_index(&self, p: Point) -> usize {
let mut bits: Vec<char> = vec![];
for y in p.y - 1..=p.y + 1 {
for x in p.x - 1..=p.x + 1 {
if x < self.min_x || x > self.max_x || y < self.min_y || y > self.max_y {
bits.push(if self.outside_cell_state { '1' } else { '0' });
continue;
}
bits.push(if self.hashset.contains(&Point { x, y }) {
'1'
} else {
'0'
})
}
}
usize::from_str_radix(&bits.iter().collect::<String>(), 2).unwrap()
}
pub fn apply_filter(&self, filter: &Filter) -> Self {
let mut new_map = Map::new();
for y in self.min_y - 1..=self.max_y + 1 {
for x in self.min_x - 1..=self.max_x + 1 {
let point = Point { x, y };
let i = self.calc_filter_index(point);
if filter[i] {
new_map.insert(point);
}
}
}
new_map.outside_cell_state = if self.outside_cell_state {
filter[511]
} else {
filter[0]
};
new_map
}
}
impl fmt::Display for Map {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let mut str = "".to_owned();
for y in self.min_y..=self.max_y {
for x in self.min_x..=self.max_x {
str.push(if self.hashset.contains(&Point { x, y }) {
'#'
} else {
'.'
});
}
str.push('\n');
}
write!(f, "{}", str)
}
}
fn main() {
let stdin = io::stdin();
let mut lines = stdin.lock().lines();
let mut filter = Filter::new();
for c in lines.next().unwrap().unwrap().chars() {
filter.push(c == '#');
}
lines.next();
let mut map = Map::new();
for (_line, y) in lines.zip(0..) {
let line = _line.unwrap();
for (c, x) in line.chars().zip(0..) {
if c == '#' {
map.insert(Point { x, y });
}
}
}
let mut filterd_map = map;
for _ in 0..50 {
filterd_map = filterd_map.apply_filter(&filter);
}
println!("ans {}", filterd_map.hashset.len());
}