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
|
use std::{
error::Error,
fs,
ops::{Add, Mul},
};
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
struct Point {
pub x: i64,
pub y: i64,
}
impl Point {
fn new(x: i64, y: i64) -> Self {
Self { x, y }
}
}
impl Mul<i64> for Point {
type Output = Self;
fn mul(self, rhs: i64) -> Self::Output {
Point {
x: self.x * rhs,
y: self.y * rhs,
}
}
}
impl Add<Point> for Point {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Point {
x: self.x + rhs.x,
y: self.y + rhs.y,
}
}
}
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
enum Dir {
North,
NorthEast,
East,
SouthEast,
South,
SouthWest,
West,
NorthWest,
}
impl Dir {
const DIRS: [Dir; 8] = [
Dir::North,
Dir::NorthEast,
Dir::East,
Dir::SouthEast,
Dir::South,
Dir::SouthWest,
Dir::West,
Dir::NorthWest,
];
fn grid_offset(self) -> Point {
match self {
Dir::North => Point::new(0, 1),
Dir::NorthEast => Point::new(1, 1),
Dir::East => Point::new(1, 0),
Dir::SouthEast => Point::new(1, -1),
Dir::South => Point::new(0, -1),
Dir::SouthWest => Point::new(-1, -1),
Dir::West => Point::new(-1, 0),
Dir::NorthWest => Point::new(-1, 1),
}
}
}
fn index_at(board: &[&[u8]], point: Point) -> Option<u8> {
Some(
*board
.get(usize::try_from(point.y).ok()?)?
.get(usize::try_from(point.x).ok()?)?,
)
}
fn main() -> Result<(), Box<dyn Error>> {
let mut xmas_count = 0;
let mut x_mas_count = 0;
let to_find = b"XMAS";
let input = fs::read("input/4")?;
let input: Box<[&[u8]]> = input.trim_ascii_end().split(|e| *e == b'\n').collect();
for y in 0..input.len() {
for x in 0..input[y].len() {
let p = Point::new(x as i64, y as i64);
for d in Dir::DIRS {
if to_find
.iter()
.copied()
.enumerate()
.all(|c| index_at(&input, p + d.grid_offset() * c.0 as i64) == Some(c.1))
{
xmas_count += 1;
}
}
if input[y][x] == b'A' {
let check = |a, b| {
(a == Some(b'M') && b == Some(b'S')) || (a == Some(b'S') && b == Some(b'M'))
};
if check(
index_at(&input, p + Dir::NorthEast.grid_offset()),
index_at(&input, p + Dir::SouthWest.grid_offset()),
) && check(
index_at(&input, p + Dir::NorthWest.grid_offset()),
index_at(&input, p + Dir::SouthEast.grid_offset()),
) {
x_mas_count += 1;
}
}
}
}
println!("{xmas_count}\n{x_mas_count}");
Ok(())
}
|