-
Notifications
You must be signed in to change notification settings - Fork 0
/
day-3.rs
72 lines (64 loc) · 2.16 KB
/
day-3.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
use std::{collections::HashMap, str::from_utf8};
use aoc_2023::str_block;
const INPUT: &str = include_str!("day-3.txt");
#[allow(dead_code)]
const INPUT_EX: &str = str_block! {"
467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598.."};
aoc_2023::aoc! {
struct Day3 {
sum: usize,
gears: HashMap::<(usize, usize), Vec<usize>>,
}
self(input = INPUT) {
let map: Vec<&[u8]> = input.lines().map(|line| line.as_bytes()).collect();
let mut sum = 0;
let mut gears: HashMap::<(usize, usize), Vec<usize>> = HashMap::new();
for y in 0..map.len() {
let mut x = 0;
let linelen = map[y].len();
while x < linelen {
if map[y][x].is_ascii_digit() {
let x0 = x;
while x < linelen && map[y][x].is_ascii_digit() {
x += 1;
}
let num: usize = from_utf8(&map[y][x0..x]).unwrap().parse().unwrap();
let (x0, x1) = (x0.saturating_sub(1), (linelen - 1).min(x));
let (y0, y1) = (y.saturating_sub(1), (map.len() - 1).min(y + 1));
let attached = |y: usize| map[y][x0..=x1].iter().any(|c| !matches!(c, b'0'..=b'9' | b'.'));
if attached(y0) || attached(y) || attached(y1) {
sum += num;
}
#[allow(clippy::needless_range_loop)]
for y in y0..=y1 {
for x in x0..=x1 {
if map[y][x] == b'*' {
gears.entry((x, y)).or_default().push(num);
}
}
}
} else {
x += 1;
}
}
}
Ok(Self { sum, gears })
}
1 part1 usize {
Ok(self.sum)
}
2 part2 usize {
Ok(self.gears.values().filter(|gear| gear.len() == 2).map(|gear| gear[0] * gear[1]).sum())
}
INPUT_EX { 1 part1 = 4361, 2 part2 = 467835 }
INPUT { 1 part1 = 509115, 2 part2 = 75220503 }
}