-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday_23.rs
152 lines (134 loc) · 4.65 KB
/
day_23.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
use std::collections::{HashSet, HashMap};
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
struct Cell {
x: i32,
y: i32
}
impl Cell {
// returns true if there are any cells in W, NW, or SW adjacent positions
fn check_surrounding(&self, map: &HashSet<Cell>) -> bool {
!(self.check_up(map) && self.check_down(map) && self.check_left(map) && self.check_right(map))
}
// returns true if there are no cells in N, NW, or NE adjacent positions
fn check_up(&self, map: &HashSet<Cell>) -> bool {
for i in -1..=1 {
if map.contains(&Cell { x: self.x + i, y: self.y - 1 }) {
return false;
}
}
true
}
// returns true if there are no cells in S, SW, or SE adjacent positions
fn check_down(&self, map: &HashSet<Cell>) -> bool {
for i in -1..=1 {
if map.contains(&Cell { x: self.x + i, y: self.y + 1 }) {
return false;
}
}
true
}
// returns true if there are no cells in W, NW, or SW adjacent positions
fn check_left(&self, map: &HashSet<Cell>) -> bool {
for i in -1..=1 {
if map.contains(&Cell { x: self.x - 1, y: self.y + i }) {
return false;
}
}
true
}
// returns true if there are no cells in E, NE, or SE adjacent positions
fn check_right(&self, map: &HashSet<Cell>) -> bool {
for i in -1..=1 {
if map.contains(&Cell { x: self.x + 1, y: self.y + i }) {
return false;
}
}
true
}
}
pub fn run() {
let input_str = include_str!("../../inputs/input_23.txt");
let mut map: HashSet<Cell> = HashSet::new();
let input: Vec<&str> = input_str.lines().collect();
for (row_index, line) in input.iter().enumerate() {
for (col_index, c) in line.chars().enumerate() {
if c == '#' {
map.insert(Cell {
x: col_index as i32,
y: row_index as i32
});
}
}
}
part_one(&map);
part_two(&map);
}
fn part_one(map: &HashSet<Cell>) {
let mut map = map.clone();
for round in 0..10 {
let proposed_cells = get_proposed_cells(&map, round);
for proposition in &proposed_cells {
if proposed_cells.values().filter(|&cell| cell == proposition.1).count() == 1 {
map.remove(proposition.0);
map.insert(*proposition.1);
}
}
}
let mut highest_x = map.iter().next().unwrap().x;
let mut highest_y = map.iter().next().unwrap().y;
let mut lowest_x = highest_x;
let mut lowest_y = highest_y;
for cell in &map {
highest_x = if cell.x > highest_x { cell.x } else { highest_x };
highest_y = if cell.y > highest_y { cell.y } else { highest_y };
lowest_x = if cell.x < lowest_x { cell.x } else { lowest_x };
lowest_y = if cell.y < lowest_y { cell.y } else { lowest_y };
}
highest_x += 1;
highest_y += 1;
println!("Part one: {}", ((highest_x - lowest_x) * (highest_y - lowest_y)) - map.len() as i32);
}
fn part_two(map: &HashSet<Cell>) {
let mut map = map.clone();
let mut round = 0;
let mut has_moved = true;
while has_moved {
let proposed_cells = get_proposed_cells(&map, round);
has_moved = false;
for proposition in &proposed_cells {
if proposed_cells.values().filter(|&cell| cell == proposition.1).count() == 1 {
map.remove(proposition.0);
map.insert(*proposition.1);
has_moved = true;
}
}
round += 1;
}
println!("Part two: {}", round);
}
fn get_proposed_cells(map: &HashSet<Cell>, round: i32) -> HashMap<Cell, Cell> {
let mut proposed_cells: HashMap<Cell, Cell> = HashMap::new();
for i in map {
if i.check_surrounding(map) {
for r in round..round+4 {
if r % 4 == 0 && i.check_up(map) {
proposed_cells.insert(*i, Cell { x: i.x, y: i.y - 1 });
break;
}
else if r % 4 == 1 && i.check_down(map) {
proposed_cells.insert(*i, Cell { x: i.x, y: i.y + 1 });
break;
}
else if r % 4 == 2 && i.check_left(map) {
proposed_cells.insert(*i, Cell { x: i.x - 1, y: i.y });
break;
}
else if r % 4 == 3 && i.check_right(map) {
proposed_cells.insert(*i, Cell { x: i.x + 1, y: i.y });
break;
}
}
}
}
proposed_cells
}