haar_lib/math/
closed_interval.rs

1//! 閉区間
2
3/// 両端の点を含む閉区間を扱う。
4#[derive(Clone, Default, Debug, PartialEq, Eq)]
5pub struct ClosedInterval<T> {
6    /// 閉区間の開始地点
7    pub start: T,
8    /// 閉区間の終了地点
9    pub end: T,
10}
11
12impl<T> ClosedInterval<T> {
13    /// [`ClosedInterval<T>`]を生成する
14    pub fn new(start: T, end: T) -> Self {
15        Self { start, end }
16    }
17}
18
19impl<T: Ord + PartialEq + Copy> ClosedInterval<T> {
20    /// 2つの閉区間に共通部分があれば、統合した結果を`Ok`に包んで返す。
21    ///
22    /// 共通部分がなければ、`Err`に元の2つの閉区間を包んで返す。
23    pub fn merge(self, other: Self) -> Result<Self, (Self, Self)> {
24        if self.end < other.start || other.end < self.start {
25            Err((self, other))
26        } else {
27            Ok(Self {
28                start: self.start.min(other.start),
29                end: self.end.max(other.end),
30            })
31        }
32    }
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn test() {
41        type I = ClosedInterval<i64>;
42
43        assert_eq!(
44            I::new(0, 3).merge(I::new(4, 7)),
45            Err((I::new(0, 3), I::new(4, 7)))
46        );
47        assert_eq!(I::new(0, 3).merge(I::new(3, 6)), Ok(I::new(0, 6)));
48        assert_eq!(I::new(0, 3).merge(I::new(-2, 5)), Ok(I::new(-2, 5)));
49        assert_eq!(I::new(0, 3).merge(I::new(-2, 2)), Ok(I::new(-2, 3)));
50        assert_eq!(I::new(0, 3).merge(I::new(1, 2)), Ok(I::new(0, 3)));
51    }
52}