Implement stream algos except intersect_all

This commit is contained in:
expectocode 2019-12-31 01:32:23 +00:00
parent 8098d2e1bc
commit ba572f9af3
3 changed files with 93 additions and 2 deletions

View File

@ -1,12 +1,12 @@
use std::ops::Add; use std::ops::Add;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone, Hash)]
pub struct Point { pub struct Point {
x: u32, x: u32,
y: u32, y: u32,
} }
#[derive(Debug, Copy, Clone, Eq, PartialEq)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct Rectangle { pub struct Rectangle {
top_left: Point, top_left: Point,
width: u32, width: u32,

View File

@ -1,4 +1,5 @@
mod geometry; mod geometry;
mod stream_algos;
fn main() { fn main() {
let p = geometry::Point::new(2, 3); let p = geometry::Point::new(2, 3);

90
src/stream_algos.rs Normal file
View File

@ -0,0 +1,90 @@
use crate::geometry::{Point, Rectangle};
use std::collections::HashMap;
use std::ops::{Add, Mul};
impl Add<Point> for Rectangle {
type Output = Self;
fn add(self, rhs: Point) -> Self {
Rectangle::from_corner_width_height(self.top_left() + rhs, self.width(), self.height())
}
}
impl Mul<u32> for Rectangle {
type Output = Self;
fn mul(self, rhs: u32) -> Self {
Rectangle::from_corner_width_height(
self.top_left(),
self.width() * rhs,
self.height() * rhs,
)
}
}
/// Returns a stream of rectangles by translating (moving) each rectangle according to the given
/// distance vector.
pub fn translate<T>(rects: T, distance_vector: Point) -> impl Iterator<Item = Rectangle>
where
T: Iterator<Item = Rectangle>,
{
rects.map(move |r| r + distance_vector)
}
/// Returns a stream of rectangles by scaling each rectangle by a given amount.
pub fn scale<T>(rects: T, scale_factor: u32) -> impl Iterator<Item = Rectangle>
where
T: Iterator<Item = Rectangle>,
{
rects.map(move |r| r * scale_factor)
}
/// Returns a stream containing, in order, the bottom-left point of each input rectangle.
pub fn bottom_left_points<T>(rects: T) -> impl Iterator<Item = Point>
where
T: Iterator<Item = Rectangle>,
{
rects.map(|r| r.bottom_left())
}
/// Returns a stream containing all rectangles that intersect with the given rectangle.
pub fn get_all_intersecting<T>(rects: T, rectangle: &Rectangle) -> impl Iterator<Item = Rectangle>
where
T: Iterator<Item = Rectangle>,
{
// We need to satisfy the borrow checker here.
let rectangle = rectangle.clone();
rects.filter(move |r| r.intersects(&rectangle))
}
/// Returns the largest area among the given rectangles
pub fn get_largest_area(rects: impl Iterator<Item = Rectangle>) -> Option<u32> {
rects.map(|r| r.area()).max()
}
/// Returns the largest height among the given rectangles
pub fn get_largest_height(rects: impl Iterator<Item = Rectangle>) -> Option<u32> {
rects.map(|r| r.height()).max()
}
/// Returns the sum of the areas of the rectangles
pub fn get_area_sum(rects: impl Iterator<Item = Rectangle>) -> u32 {
rects.map(|r| r.area()).sum()
}
/// Computes the sum of areas of all rectangles that intersect with the given rectangle.
pub fn get_area_sum_of_intersecting<T>(rects: T, rectangle: &Rectangle) -> u32
where
T: Iterator<Item = Rectangle>,
{
get_area_sum(get_all_intersecting(rects, rectangle))
}
/// Returns map from rectangle to computed area
pub fn get_area_map<T>(rects: T) -> HashMap<Rectangle, u32>
where
T: Iterator<Item = Rectangle>,
{
// The type of the collect() function is chosen based on the return type that it's meant to fit
rects.map(|r| (r, r.area())).collect()
}