+7
2015/18/rust/Cargo.lock
+7
2015/18/rust/Cargo.lock
+6
2015/18/rust/Cargo.toml
+6
2015/18/rust/Cargo.toml
+98
2015/18/rust/src/main.rs
+98
2015/18/rust/src/main.rs
···
1
+
use std::mem::swap;
2
+
3
+
#[inline]
4
+
fn get_at(world: &Vec<Vec<bool>>, size: usize, x: isize, y: isize) -> u8 {
5
+
let isize = size as isize;
6
+
if x == isize || x == -1 || y == isize || y == -1 {
7
+
return 0;
8
+
};
9
+
if *world
10
+
.get(y as usize)
11
+
.expect("invalid position")
12
+
.get(x as usize)
13
+
.expect("invalid position")
14
+
{
15
+
1
16
+
} else {
17
+
0
18
+
}
19
+
}
20
+
21
+
#[inline]
22
+
fn get_at_bool(world: &Vec<Vec<bool>>, x: usize, y: usize) -> bool {
23
+
*world
24
+
.get(y)
25
+
.expect("invalid position")
26
+
.get(x)
27
+
.expect("invalid position")
28
+
}
29
+
30
+
fn generations(times: u32, mut world: Vec<Vec<bool>>, size: usize, stuck: bool) -> Vec<Vec<bool>> {
31
+
let mut new_world = vec![vec![false; size]; size];
32
+
if stuck {
33
+
let sizem = size - 1;
34
+
world[0][0] = true;
35
+
world[0][sizem] = true;
36
+
world[sizem][0] = true;
37
+
world[sizem][sizem] = true;
38
+
}
39
+
40
+
for _ in 0..times {
41
+
for y in 0..size {
42
+
for x in 0..size {
43
+
let xo = x as isize;
44
+
let yo = y as isize;
45
+
let xm = xo - 1;
46
+
let ym = yo - 1;
47
+
let xp = xo + 1;
48
+
let yp = yo + 1;
49
+
50
+
let was = get_at_bool(&world, x, y);
51
+
let neighbours = get_at(&world, size, xm, ym)
52
+
+ get_at(&world, size, xo, ym)
53
+
+ get_at(&world, size, xp, ym)
54
+
+ get_at(&world, size, xm, yo)
55
+
+ get_at(&world, size, xp, yo)
56
+
+ get_at(&world, size, xm, yp)
57
+
+ get_at(&world, size, xo, yp)
58
+
+ get_at(&world, size, xp, yp);
59
+
new_world[y][x] = neighbours == 3 || (neighbours == 2 && was);
60
+
}
61
+
}
62
+
63
+
swap(&mut world, &mut new_world);
64
+
65
+
// i hate the duplication here :(
66
+
if stuck {
67
+
let sizem = size - 1;
68
+
world[0][0] = true;
69
+
world[0][sizem] = true;
70
+
world[sizem][0] = true;
71
+
world[sizem][sizem] = true;
72
+
}
73
+
}
74
+
world
75
+
}
76
+
77
+
fn main() {
78
+
let input = include_str!("../../input.txt").trim();
79
+
let size = input.split_once("\n").expect("invalid input").0.len();
80
+
let input: Vec<Vec<bool>> = input
81
+
.split("\n")
82
+
.map(|line| line.chars().map(|v| v == '#').collect())
83
+
.collect();
84
+
85
+
let part_1 = generations(100, input.clone(), size, false)
86
+
.iter()
87
+
.flatten()
88
+
.filter(|v| **v)
89
+
.count();
90
+
println!("Part 1: {}", part_1);
91
+
92
+
let part_2 = generations(100, input.clone(), size, true)
93
+
.iter()
94
+
.flatten()
95
+
.filter(|v| **v)
96
+
.count();
97
+
println!("Part 2: {}", part_2);
98
+
}