2021 day5/rust: add solution

This commit is contained in:
Xiretza 2021-12-05 10:01:53 +01:00
parent d3c4e526f1
commit 4ee0046b97
2 changed files with 92 additions and 0 deletions

View file

@ -0,0 +1,9 @@
[package]
name = "day5_rs"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
vector2d = "2.2.0"

View file

@ -0,0 +1,83 @@
#![warn(clippy::pedantic)]
use std::{
collections::HashMap,
convert::Infallible,
io::{stdin, BufRead},
str::FromStr,
};
use vector2d::Vector2D;
#[derive(Copy, Clone, Debug)]
struct Line {
start: Vector2D<usize>,
end: Vector2D<usize>,
}
impl Line {
pub fn is_straight(&self) -> bool {
self.start.x == self.end.x || self.start.y == self.end.y
}
pub fn expand(&self) -> Vec<Vector2D<usize>> {
let delta = self.end.as_isizes() - self.start.as_isizes();
#[allow(clippy::if_not_else)]
let len = if delta.x != 0 {
delta.x.abs()
} else if delta.y != 0 {
delta.y.abs()
} else {
unreachable!()
};
let step = delta / len;
(0..=len)
.scan(self.start, |acc, _| {
let prev = *acc;
*acc = (acc.as_isizes() + step).as_usizes();
Some(prev)
})
.collect()
}
}
impl FromStr for Line {
type Err = Infallible;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let parts: Vec<_> = s.split(' ').collect();
let start: Vec<_> = parts[0].split(',').map(|n| n.parse().unwrap()).collect();
let end: Vec<_> = parts[2].split(',').map(|n| n.parse().unwrap()).collect();
Ok(Line {
start: Vector2D::new(start[0], start[1]),
end: Vector2D::new(end[0], end[1]),
})
}
}
fn count_overlaps<'a>(it: impl IntoIterator<Item = &'a Line>) -> usize {
let counts: HashMap<(usize, usize), usize> =
it.into_iter()
.flat_map(Line::expand)
.fold(HashMap::new(), |mut map, point| {
*map.entry(point.into()).or_default() += 1;
map
});
counts.into_iter().filter(|&(_k, v)| v >= 2).count()
}
fn main() {
let lines: Vec<Line> = stdin()
.lock()
.lines()
.map(|s| s.unwrap().parse().unwrap())
.collect();
println!(
"{}",
count_overlaps(lines.iter().filter(|line| line.is_straight()))
);
println!("{}", count_overlaps(&lines));
}