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