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
|
extern crate advent_of_code_2018;
use advent_of_code_2018::*;
use std::error::Error;
use std::path::PathBuf;
use std::collections::{HashSet, HashMap};
// cargo watch -cs "cargo run --release --bin day_6"
fn main() -> Result<(), Box<Error>> {
let input = read_file(&PathBuf::from("inputs/6.txt"))?;
let coordinates = input.iter().map(|line| {
let mut split = line.split(|c: char| !c.is_numeric());
let x: i32 = split.next().unwrap().parse().unwrap();
let _ = split.next();
let y: i32 = split.next().unwrap().parse().unwrap();
(x, y)
}).collect::<Vec<_>>();
debug!(coordinates);
let min_x = coordinates.iter().map(|(x, _)| x).min().unwrap().clone();
let max_x = coordinates.iter().map(|(x, _)| x).max().unwrap().clone();
let min_y = coordinates.iter().map(|(_, y)| y).min().unwrap().clone();
let max_y = coordinates.iter().map(|(_, y)| y).max().unwrap().clone();
debug!(min_x);
debug!(max_x);
debug!(min_y);
debug!(max_y);
let mut infinite = HashSet::new();
for x in min_x..max_x+1 {
for y in &[0, max_y] {
if let Some(coord) = find_closest(&coordinates, x, *y) {
infinite.insert(coord);
}
}
}
for y in min_y..max_y+1 {
for x in &[0, max_x] {
if let Some(coord) = find_closest(&coordinates, *x, y) {
infinite.insert(coord);
}
}
}
debug!(infinite);
let mut areas = HashMap::new();
for x in min_x..max_x+1 {
for y in min_y..max_y+1 {
if let Some(coord) = find_closest(&coordinates, x, y) {
*areas.entry(coord).or_insert(0) += 1;
}
}
}
debug!(areas);
let biggest_non_infinite = areas.iter()
.filter(|(k,_)| !infinite.contains(&k))
.max_by_key(|(_,v)| *v);
debug!(biggest_non_infinite);
let safe_distance = 10000;
let mut safe_size = 0;
for x in min_x..max_x+1 {
for y in min_y..max_y+1 {
let distance_sum: i32 = coordinates.iter()
.map(|(x1, y1)| manhattan_distance(*x1, *y1, x, y))
.sum();
if distance_sum < safe_distance {
safe_size += 1;
}
}
}
debug!(safe_size);
Ok(())
}
fn find_closest(coordinates: &Vec<(i32, i32)>, x: i32, y: i32) -> Option<usize> {
let mut distances = coordinates.iter()
.map(|(x1, y1)| manhattan_distance(*x1, *y1, x, y))
.enumerate()
.collect::<Vec<_>>();
distances.sort_by_key(|(_, d)| *d);
if distances[0] == distances[1] {
None
}
else {
distances.first().map(|(i, _)| *i)
}
}
fn manhattan_distance(x1: i32, y1: i32, x2: i32, y2: i32) -> i32 {
(x2-x1).abs() + (y2-y1).abs()
}
|