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 y in 1..grid.height - 1 {
41 for x in 1..grid.width - 1 {
42 let point = Point::new(x, y);
43
44 if grid[point] == b'A' {
45 let diagonal = |corner| grid[point + corner].abs_diff(grid[point - corner]);
49 result += u32::from(diagonal(UP + LEFT) == 6 && diagonal(UP + RIGHT) == 6);
50 }
51 }
52 }
53
54 result
55}
56
57fn scan_line(grid: &Grid<u8>, mut point: Point, direction: Point, size: i32) -> u32 {
59 let mut bytes = 0;
60 let mut result = 0;
61
62 for _ in 0..size {
63 bytes = (bytes << 8) | (grid[point] as u32);
64 point += direction;
65 result += (bytes == 0x584d4153 || bytes == 0x53414d58) as u32;
67 }
68
69 result
70}