+20
-22
2015/18/rust/src/main.rs
+20
-22
2015/18/rust/src/main.rs
···
1
1
use std::mem::swap;
2
2
3
3
#[inline]
4
-
fn get_at(world: &Vec<bool>, size: usize, x: usize, y: usize) -> u8 {
4
+
fn get_at(world: &Vec<u8>, size: usize, x: usize, y: usize) -> u8 {
5
5
// benefits from the integer overflow to simplify code
6
6
if x >= size || y >= size {
7
7
return 0;
8
8
};
9
9
// this is in known bounds
10
-
unsafe { *world.get_unchecked(y * size + x) as u8 }
11
-
}
12
-
13
-
#[inline]
14
-
fn get_at_bool(world: &Vec<bool>, size: usize, x: usize, y: usize) -> bool {
15
-
// this is in known bounds
16
10
unsafe { *world.get_unchecked(y * size + x) }
17
11
}
18
12
19
-
fn generations(times: u32, mut world: Vec<bool>, size: usize, stuck: bool) -> Vec<bool> {
20
-
let mut new_world = vec![false; size * size];
13
+
fn generations(times: u32, mut world: Vec<u8>, size: usize, stuck: bool) -> Vec<u8> {
14
+
let mut new_world = vec![0_u8; size * size];
21
15
let sizem = size - 1;
22
16
if stuck {
23
-
world[0] = true;
24
-
world[sizem] = true;
25
-
world[(size * size) - 1] = true;
26
-
world[size * sizem] = true;
17
+
world[0] = 1;
18
+
world[sizem] = 1;
19
+
world[(size * size) - 1] = 1;
20
+
world[size * sizem] = 1;
27
21
}
28
22
29
23
for _ in 0..times {
···
34
28
let xm = xo.wrapping_sub(1);
35
29
let xp = xo + 1;
36
30
37
-
let was = get_at_bool(&world, size, xo, yo);
31
+
let was = get_at(&world, size, xo, yo) == 1;
38
32
let neighbours = get_at(&world, size, xm, ym)
39
33
+ get_at(&world, size, xo, ym)
40
34
+ get_at(&world, size, xp, ym)
···
43
37
+ get_at(&world, size, xm, yp)
44
38
+ get_at(&world, size, xo, yp)
45
39
+ get_at(&world, size, xp, yp);
46
-
new_world[yo * size + xo] = neighbours == 3 || (neighbours == 2 && was);
40
+
new_world[yo * size + xo] = (neighbours == 3 || (neighbours == 2 && was)) as u8;
47
41
}
48
42
}
49
43
···
51
45
52
46
// i hate the duplication here :(
53
47
if stuck {
54
-
world[0] = true;
55
-
world[sizem] = true;
56
-
world[(size * size) - 1] = true;
57
-
world[size * sizem] = true;
48
+
world[0] = 1;
49
+
world[sizem] = 1;
50
+
world[(size * size) - 1] = 1;
51
+
world[size * sizem] = 1;
58
52
}
59
53
}
60
54
world
···
63
57
fn main() {
64
58
let input = include_str!("../../input.txt").trim();
65
59
let size = input.split_once("\n").expect("invalid input").0.len();
66
-
let input: Vec<bool> = input.replace("\n", "").chars().map(|v| v == '#').collect();
60
+
let input: Vec<u8> = input
61
+
.replace("\n", "")
62
+
.chars()
63
+
.map(|v| (v == '#') as u8)
64
+
.collect();
67
65
68
66
let part_1 = generations(100, input.clone(), size, false)
69
67
.iter()
70
-
.filter(|v| **v)
68
+
.filter(|v| **v == 1)
71
69
.count();
72
70
println!("Part 1: {}", part_1);
73
71
74
72
let part_2 = generations(100, input.clone(), size, true)
75
73
.iter()
76
-
.filter(|v| **v)
74
+
.filter(|v| **v == 1)
77
75
.count();
78
76
println!("Part 2: {}", part_2);
79
77
}