year2017/
day14.rs
1use crate::knot_hash::knot_hash;
2use utils::bit::BitIterator;
3use utils::prelude::*;
4
5#[derive(Clone, Debug)]
11pub struct Day14 {
12 grid: [u128; 128],
13}
14
15impl Day14 {
16 pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
17 let mut grid = [0u128; 128];
18
19 let mut buf = Vec::with_capacity(input.len() + 4);
20 buf.extend_from_slice(input.as_bytes());
21 buf.push(b'-');
22
23 for (i, row) in grid.iter_mut().enumerate() {
24 buf.truncate(input.len() + 1);
25 if i < 10 {
26 buf.push(b'0' + (i as u8));
27 } else if i < 100 {
28 buf.push(b'0' + ((i / 10) as u8));
29 buf.push(b'0' + ((i % 10) as u8));
30 } else {
31 buf.push(b'0' + ((i / 100) as u8));
32 buf.push(b'0' + (((i / 10) % 10) as u8));
33 buf.push(b'0' + ((i % 10) as u8));
34 }
35
36 let hash = knot_hash(buf.iter().copied());
37 *row = u128::from_be_bytes(hash);
38 }
39
40 Ok(Day14 { grid })
41 }
42
43 #[must_use]
44 pub fn part1(&self) -> u32 {
45 self.grid.iter().map(|x| x.count_ones()).sum()
46 }
47
48 #[must_use]
49 pub fn part2(&self) -> u32 {
50 let mut regions = 0;
51 let mut visited = [0u128; 128];
52
53 for (r, &row) in self.grid.iter().enumerate() {
54 for (_, bit) in BitIterator::ones(row) {
55 if visited[r] & bit == 0 {
56 regions += 1;
57 self.visit(&mut visited, r, bit)
58 }
59 }
60 }
61
62 regions
63 }
64
65 fn visit(&self, visited: &mut [u128; 128], r: usize, bit: u128) {
66 visited[r] |= bit;
67
68 if r > 0 && self.grid[r - 1] & bit != 0 && visited[r - 1] & bit == 0 {
69 self.visit(visited, r - 1, bit);
70 }
71 if r < 127 && self.grid[r + 1] & bit != 0 && visited[r + 1] & bit == 0 {
72 self.visit(visited, r + 1, bit);
73 }
74
75 let left = bit << 1;
76 if left != 0 && self.grid[r] & left != 0 && visited[r] & left == 0 {
77 self.visit(visited, r, left);
78 }
79 let right = bit >> 1;
80 if right != 0 && self.grid[r] & right != 0 && visited[r] & right == 0 {
81 self.visit(visited, r, right);
82 }
83 }
84}
85
86examples!(Day14 -> (u32, u32) [
87 {input: "flqrgnkx", part1: 8108, part2: 1242},
88]);