-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday8.rs
88 lines (80 loc) · 2.18 KB
/
day8.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
use std::collections::BTreeSet;
use itertools::Itertools;
fn solve<I>(data: &str, multiples: I) -> usize
where
I: Clone + IntoIterator<Item = isize>,
{
let (mut height, mut width) = (0, 0);
data.lines()
.enumerate()
.flat_map(|(y, line)| {
height = y + 1;
width = width.max(line.len());
line.bytes().enumerate().filter_map(move |(x, b)| match b {
b'.' => None,
_ => Some((b, (y, x))),
})
})
.into_grouping_map_by(|(b, _)| *b)
.fold_with(
|_, _| vec![],
|mut acc, _, (_, point)| {
acc.push(point);
acc
},
)
.values()
.flat_map(|points| {
points.iter().flat_map(|point0 @ (y0, x0)| {
points
.iter()
.filter(move |point1| point0 != *point1)
.flat_map(|(y1, x1)| {
let (dy, dx) = (*y1 as isize - *y0 as isize, *x1 as isize - *x0 as isize);
multiples.clone().into_iter().map_while(move |i| {
Some((
y1.wrapping_add_signed(i * dy),
x1.wrapping_add_signed(i * dx),
))
.filter(|(y, x)| *y < height && *x < width)
})
})
})
})
.collect::<BTreeSet<_>>()
.len()
}
pub fn part1(data: &str) -> usize {
solve(data, [1])
}
pub fn part2(data: &str) -> usize {
solve(data, 0..)
}
#[cfg(test)]
mod tests {
use super::*;
use indoc::indoc;
use pretty_assertions::assert_eq;
static EXAMPLE: &str = indoc! {"
............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............
"};
#[test]
fn part1_examples() {
assert_eq!(14, part1(EXAMPLE));
}
#[test]
fn part2_examples() {
assert_eq!(34, part2(EXAMPLE));
}
}