-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday-5.rs
107 lines (91 loc) · 2.54 KB
/
day-5.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
use std::str::FromStr;
const INPUT: &str = include_str!("day-5.input");
#[derive(Clone, Copy)]
struct Point {
x: usize,
y: usize,
}
impl FromStr for Point {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (x, y) = s.split_once(',').unwrap();
Ok(Self {
x: x.parse().unwrap(),
y: y.parse().unwrap(),
})
}
}
struct Grid {
cells: Vec<usize>,
width: usize,
}
impl Grid {
fn new(w: usize, h: usize) -> Self {
Self {
cells: vec![0; w * h],
width: w,
}
}
fn ortho_line(&mut self, from: &Point, to: &Point) {
if from.x == to.x {
let x = from.x;
let from_y = from.y.min(to.y);
let to_y = from.y.max(to.y);
for y in from_y..=to_y {
self.set(x, y);
}
} else if from.y == to.y {
let y = from.y;
let from_x = from.x.min(to.x);
let to_x = from.x.max(to.x);
for x in from_x..=to_x {
self.set(x, y);
}
}
}
fn diag_line(&mut self, from: &Point, to: &Point) {
if from.x != to.x && from.y != to.y {
let dx = if from.x < to.x { 1 } else { -1 };
let dy = if from.y < to.y { 1 } else { -1 };
let mut x = from.x;
let mut y = from.y;
self.set(x, y);
while x != to.x && y != to.y {
x = (x as isize + dx) as usize;
y = (y as isize + dy) as usize;
self.set(x, y);
}
}
}
fn set(&mut self, x: usize, y: usize) {
assert!(x < self.width);
self.cells[y * self.width + x] += 1;
}
fn count(&self, min: usize) -> usize {
self.cells.iter().filter(move |&&c| c >= min).count()
}
}
fn main() {
let input: Vec<_> = INPUT
.lines()
.map(|s| {
let (from, to) = s.split_once(" -> ").unwrap();
(from.parse::<Point>().unwrap(), to.parse::<Point>().unwrap())
})
.collect();
let mut max_x = 0;
let mut max_y = 0;
for (from, to) in input.iter() {
max_x = max_x.max(from.x.max(to.x));
max_y = max_y.max(from.y.max(to.y));
}
let mut grid = Grid::new(max_x + 1, max_y + 1);
for (from, to) in input.iter() {
grid.ortho_line(from, to);
}
println!("part 1: {}", grid.count(2));
for (from, to) in input.iter() {
grid.diag_line(from, to);
}
println!("part 2: {}", grid.count(2));
}