summaryrefslogtreecommitdiff
path: root/2018/src/day6.rs
blob: 67a00852965fa90a701715ee5a74e6278f8534f3 (plain)
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
use std::io;
use std::io::BufRead;

fn dist(a: (i32, i32), b: (i32, i32)) -> i32 {
    (b.0 - a.0).abs() + (b.1 - a.1).abs()
}

pub fn main<T: BufRead>(reader: T) -> io::Result<(String, String)> {
    let pts: Vec<(i32, i32)> = reader.lines().map(|l| l.unwrap()).map(|line| {
        let mut spl = line.split(", ").map(|s| s.parse().unwrap());
        let x = spl.next().unwrap();
        let y = spl.next().unwrap();
        (x, y)
    }).collect();

    let &max_x = pts.iter().map(|(x, _)| x).max().unwrap();
    let &max_y = pts.iter().map(|(_, y)| y).max().unwrap();
    let min_x = -1;
    let min_y = -1;

    let mut borderpts = vec![false; pts.len()];
    let mut size = vec![0; pts.len()];
    let mut nsafe = 0;

    for y in min_y..max_y+1 {
        for x in min_x..max_x+1 {
            let mut closest = 0;
            let mut closest_dist = dist(pts[0], (x, y));
            for i in 1..pts.len() {
                let d = dist(pts[i], (x, y));
                if d < closest_dist {
                    closest_dist = d;
                    closest = i;
                } else if d == closest_dist {
                    closest = usize::max_value();
                }
            }

            if closest != usize::max_value() {
                if x == min_x || x == max_x || y == min_y || y == max_y {
                    borderpts[closest] = true;
                } else {
                    size[closest] += 1;
                }
            }

            let distsum: i32 = pts.iter().map(|&p| dist(p, (x, y))).sum();
            if distsum < 10000 {
                nsafe += 1;
            }
        }
    }

    let part1 = size[(0..pts.len()).max_by_key(|&i| if borderpts[i] { -1 } else { size[i] }).unwrap()].to_string();
    let part2 = nsafe.to_string();

    Ok((part1, part2))
}