121 lines
3.1 KiB
Rust
121 lines
3.1 KiB
Rust
use std::collections::HashMap;
|
|
use std::io::{self, BufRead};
|
|
|
|
fn distance(a: (i32, i32), b: (i32, i32)) -> i32 {
|
|
(a.0 - b.0).abs() + (a.1 - b.1).abs()
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
enum State {
|
|
Empty,
|
|
Owner(usize, i32),
|
|
Equal(i32),
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
enum Area {
|
|
Infinite,
|
|
Finite(usize),
|
|
}
|
|
|
|
fn main() {
|
|
let coordinates = io::stdin()
|
|
.lock()
|
|
.lines()
|
|
.filter_map(Result::ok)
|
|
.map(|line| {
|
|
let coords = line
|
|
.split(", ")
|
|
.map(|coord| coord.parse::<i32>().unwrap())
|
|
.collect::<Vec<_>>();
|
|
|
|
(coords[0], coords[1])
|
|
})
|
|
.collect::<Vec<_>>();
|
|
|
|
let width = coordinates
|
|
.iter()
|
|
.map(|(x, _)| *x as usize)
|
|
.max()
|
|
.expect("failed to find max x")
|
|
+ 1;
|
|
|
|
let height = coordinates
|
|
.iter()
|
|
.map(|(_, y)| *y as usize)
|
|
.max()
|
|
.expect("failed to find max y")
|
|
+ 1;
|
|
|
|
let mut grid_view = vec![State::Empty; width * height].into_boxed_slice();
|
|
|
|
for x in 0..width {
|
|
for y in 0..height {
|
|
for (i, c) in coordinates.iter().enumerate() {
|
|
let distance = distance(*c, (x as i32, y as i32));
|
|
let state = &mut grid_view[x + (y * width)];
|
|
|
|
*state = match state {
|
|
State::Empty => State::Owner(i, distance),
|
|
State::Owner(_, d) if *d > distance => State::Owner(i, distance),
|
|
State::Owner(o, d) if *d == distance && *o != i => State::Equal(distance),
|
|
State::Equal(d) if *d > distance => State::Owner(i, distance),
|
|
_ => *state,
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
let mut areas = HashMap::new();
|
|
|
|
for x in 0..width {
|
|
for y in 0..height {
|
|
if let State::Owner(o, _) = grid_view[x + (y * width)] {
|
|
let a = areas.entry(o).or_insert(Area::Finite(0));
|
|
|
|
if x == 0 || x == width - 1 || y == 0 || y == height - 1 {
|
|
*a = Area::Infinite;
|
|
} else {
|
|
match a {
|
|
Area::Infinite => (),
|
|
Area::Finite(area) => *area += 1,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let (_, area) = areas
|
|
.iter()
|
|
.filter_map(|(i, area)| {
|
|
if let Area::Finite(area) = area {
|
|
Some((i, area))
|
|
} else {
|
|
None
|
|
}
|
|
})
|
|
.max_by_key(|(_, area)| *area)
|
|
.expect("failed to find max area");
|
|
|
|
println!("part.one={}", area);
|
|
|
|
let mut grid_view = vec!['.'; width * height].into_boxed_slice();
|
|
|
|
for y in 0..height {
|
|
for x in 0..width {
|
|
let total = coordinates
|
|
.iter()
|
|
.map(|c| distance(*c, (x as i32, y as i32)))
|
|
.sum::<i32>();
|
|
|
|
if total < 10_000 {
|
|
grid_view[x + (y * width)] = '#';
|
|
}
|
|
}
|
|
}
|
|
|
|
let area = grid_view.iter().filter(|r| **r == '#').count();
|
|
|
|
println!("part.two={}", area);
|
|
}
|