-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday03.rs
119 lines (100 loc) · 2.64 KB
/
day03.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
112
113
114
115
116
117
118
119
use ahash::AHashMap;
struct Schematic {
symbols: AHashMap<(i64, i64), char>,
numbers: Vec<(Vec<(i64, i64)>, i64)>,
}
fn parse(input: &str) -> Schematic {
let mut numbers = vec![];
let mut symbols = AHashMap::new();
for (y, line) in input.lines().enumerate() {
let mut num = String::new();
let mut coords = vec![]; // faster than a hashset in this case
for (x, ch) in line.char_indices() {
if ch.is_ascii_digit() {
num.push(ch);
coords.push((x as i64, y as i64));
} else {
if ch != '.' {
symbols.insert((x as i64, y as i64), ch);
}
if !num.is_empty() {
numbers.push((coords, num.parse::<i64>().unwrap()));
num = String::new();
coords = vec![];
}
}
}
if !num.is_empty() {
numbers.push((coords, num.parse::<i64>().unwrap()));
}
}
Schematic { symbols, numbers }
}
fn adjacent((x, y): (i64, i64)) -> [(i64, i64); 8] {
let dirs = [
(-1, -1),
(-1, 0),
(-1, 1),
(0, -1),
(0, 1),
(1, -1),
(1, 0),
(1, 1),
];
let mut adj = [(0, 0); 8];
for (i, (dir_x, dir_y)) in dirs.iter().enumerate() {
adj[i] = (dir_x + x, dir_y + y);
}
adj
}
fn part1(puzzle: &Schematic) -> i64 {
let mut sum = 0;
for symbol_pos in puzzle.symbols.keys() {
let adj = adjacent(*symbol_pos);
for (coords, number) in &puzzle.numbers {
if adj.iter().any(|c| coords.contains(c)) {
sum += number;
}
}
}
sum
}
fn part2(puzzle: &Schematic) -> i64 {
let mut sum = 0;
for (symbol_pos, _) in puzzle.symbols.iter().filter(|(_, &sy)| sy == '*') {
let adj = adjacent(*symbol_pos);
let mut adj_nums = vec![];
for (coords, number) in &puzzle.numbers {
if adj.iter().any(|c| coords.contains(c)) {
adj_nums.push(number);
}
}
if let [first, second] = adj_nums[..] {
sum += first * second;
}
}
sum
}
fn main() {
let input = include_str!("../../input/input03.txt");
let input = parse(input);
println!("part1 = {}", part1(&input));
println!("part2 = {}", part2(&input));
}
#[test]
fn test_day03() {
let input = "\
467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..";
let input = parse(input);
assert_eq!(part1(&input), 4361);
assert_eq!(part2(&input), 467835);
}