1use crate::util::grid::*;
10use crate::util::point::*;
11
12pub fn parse(input: &str) -> Grid<u8> {
13 Grid::parse(input)
14}
15
16pub fn part1(grid: &Grid<u8>) -> u32 {
17 let size = grid.width;
18 let mut result = 0;
19
20 for i in 0..size {
22 result += scan_line(grid, Point::new(i, 0), DOWN, size);
23 result += scan_line(grid, Point::new(0, i), RIGHT, size);
24 }
25
26 for i in 0..size - 3 {
28 result += scan_line(grid, Point::new(i, 0), DOWN + RIGHT, size - i);
29 result += scan_line(grid, Point::new(0, i + 1), DOWN + RIGHT, size - 1 - i);
30 result += scan_line(grid, Point::new(size - 1 - i, 0), DOWN + LEFT, size - i);
31 result += scan_line(grid, Point::new(size - 1, i + 1), DOWN + LEFT, size - 1 - i);
32 }
33
34 result
35}
36
37pub fn part2(grid: &Grid<u8>) -> u32 {
38 let mut result = 0;
39
40 for x in 1..grid.width - 1 {
41 for y in 1..grid.height - 1 {
42 let point = Point::new(x, y);
43
44 if grid[point] == b'A' {
45 let ul = grid[Point::new(x - 1, y - 1)];
46 let ur = grid[Point::new(x + 1, y - 1)];
47 let dl = grid[Point::new(x - 1, y + 1)];
48 let dr = grid[Point::new(x + 1, y + 1)];
49 result += (ul.abs_diff(dr) == 6 && ur.abs_diff(dl) == 6) as u32;
53 }
54 }
55 }
56
57 result
58}
59
60fn scan_line(grid: &Grid<u8>, mut point: Point, direction: Point, size: i32) -> u32 {
62 let mut bytes = 0;
63 let mut result = 0;
64
65 for _ in 0..size {
66 bytes = (bytes << 8) | (grid[point] as u32);
67 point += direction;
68 result += (bytes == 0x584d4153 || bytes == 0x53414d58) as u32;
70 }
71
72 result
73}