-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday04.rs
111 lines (91 loc) · 3.05 KB
/
day04.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
fn count_xmas_occurrences(grid: &Vec<String>) -> i64 {
let step_directions = [
(0, 1), // → Right
(1, 0), // ↓ Down
(1, 1), // ↘ Sideways (top-left to bottom-right)
(1, -1), // ↙ Sideways (top-right to bottom-left)
];
let words = ["XMAS", "SAMX"];
let rows = grid.len();
let cols = grid[0].len();
let mut count = 0;
for r in 0..rows {
for c in 0..cols {
for &(row_step, col_step) in &step_directions {
for &word in &words {
if grid_has_word(grid, word, r, c, row_step, col_step) {
count += 1;
}
}
}
}
}
count
}
fn grid_has_word(
grid: &Vec<String>,
word: &str,
start_row: usize,
start_col: usize,
row_step: isize,
col_step: isize,
) -> bool {
let rows = grid.len() as isize;
let cols = grid[0].len() as isize;
for (i, expected_char) in word.chars().enumerate() {
let row = start_row as isize + i as isize * row_step;
if row < 0 || row >= rows {
return false;
}
let col = start_col as isize + i as isize * col_step;
if col < 0 || col >= cols {
return false;
}
let current_char = grid[row as usize].chars().nth(col as usize);
if current_char != Some(expected_char) {
return false;
}
}
true
}
fn count_x_mas_occurrences(grid: &Vec<String>) -> i64 {
let mut count = 0;
let rows = grid.len();
let cols = grid[0].len();
for r in 1..rows - 1 {
for c in 1..cols - 1 {
let current_char = grid[r].chars().nth(c).unwrap();
if current_char == 'A' {
let top_left = grid[r - 1].chars().nth(c - 1).unwrap();
let top_right = grid[r - 1].chars().nth(c + 1).unwrap();
let bottom_left = grid[r + 1].chars().nth(c - 1).unwrap();
let bottom_right = grid[r + 1].chars().nth(c + 1).unwrap();
// ↘ Down right diagonal (top-left to bottom-right)
//
// M.. | S..
// .A. | .A.
// ..S | ..M
let is_down_right_diagonal =
(top_left == 'M' && bottom_right == 'S') || (top_left == 'S' && bottom_right == 'M');
// ↙ Down left diagonal (top-right to bottom-left)
//
// ..M | ..S
// .A. | .A.
// S.. | M..
let is_down_left_diagonal =
(top_right == 'M' && bottom_left == 'S') || (top_right == 'S' && bottom_left == 'M');
// If both are present, we have a valid X-MAS occurrence, yay!
if is_down_right_diagonal && is_down_left_diagonal {
count += 1;
}
}
}
}
count
}
pub fn part1(input: &Vec<String>) -> i64 {
count_xmas_occurrences(input)
}
pub fn part2(input: &Vec<String>) -> i64 {
count_x_mas_occurrences(input)
}