main.rs (1943B)
1 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
2 struct Point(i32, i32);
3
4 impl Point {
5 fn new(input: &str) -> Point {
6 let mut it = input.split(',').map(|x| x.parse::<i32>().unwrap());
7 Point(it.next().unwrap(), it.next().unwrap())
8 }
9 }
10
11 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
12 struct Line(Point, Point);
13
14 impl Line {
15 fn new(input: &str) -> Line {
16 let mut it = input.split(" -> ");
17 Line(
18 Point::new(it.next().unwrap()),
19 Point::new(it.next().unwrap()),
20 )
21 }
22
23 fn is_hv(&self) -> bool {
24 self.0 .0 == self.1 .0 || self.0 .1 == self.1 .1
25 }
26
27 fn points(&self) -> Vec<Point> {
28 let mut points = vec![self.0];
29 let mut x = self.0 .0;
30 let mut y = self.0 .1;
31 while x != self.1 .0 || y != self.1 .1 {
32 x += (self.1 .0 - x).signum();
33 y += (self.1 .1 - y).signum();
34 points.push(Point(x, y));
35 }
36 points
37 }
38 }
39
40 fn main() {
41 let input = std::fs::read_to_string("input.txt")
42 .unwrap()
43 .trim()
44 .split('\n')
45 .map(Line::new)
46 .collect::<Vec<Line>>();
47 // 74320
48 println!("Part 1 : {}", part_1(&input));
49 // 21038
50 println!("Part 2 : {}", part_2(&input));
51 }
52
53 fn part_1(input: &Vec<Line>) -> usize {
54 let mut overlap = std::collections::HashMap::<Point, i32>::new();
55 for line in input {
56 if line.is_hv() {
57 for p in line.points() {
58 overlap.insert(p, *overlap.get(&p).get_or_insert(&0) + 1);
59 }
60 }
61 }
62 overlap.values().filter(|&x| *x >= 2).count()
63 }
64
65 fn part_2(input: &Vec<Line>) -> usize {
66 let mut overlap = std::collections::HashMap::<Point, i32>::new();
67 for line in input {
68 for p in line.points() {
69 overlap.insert(p, *overlap.get(&p).get_or_insert(&0) + 1);
70 }
71 }
72 overlap.values().filter(|&x| *x >= 2).count()
73 }