Created
February 20, 2024 09:43
-
-
Save Michaelgathara/7272d8f6f279e58a7dd201415e2ec461 to your computer and use it in GitHub Desktop.
overlapping lines problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub mod overlapping_line { | |
#[derive(Debug, Clone)] | |
pub enum Linetree { | |
Empty, | |
Filled, | |
Node { | |
pivot: i64, | |
left: Box<Linetree>, | |
right: Box<Linetree>, | |
} | |
} | |
#[derive(Debug, Clone)] | |
pub struct Line { | |
x0: i64, | |
x1: i64, | |
} | |
impl Linetree { | |
pub fn insert(&self, line: &Line) -> Linetree { | |
match line { | |
Line { x0, x1 } => { | |
if x0 == x1 { | |
return self.clone(); | |
} | |
match self { | |
Linetree::Filled => Linetree::Filled, // If the section is already filled then just return filled | |
Linetree::Empty => Linetree::Node { // If the section is empty then insert the line, pick your first pivot as x0, where to the left of that is empty and to the right you have a pivot of x1 where the left is filled and the right is empty | |
/* | |
Say you have a line from 1 to 4 | |
---EMPTY----x0--------COVERED---------x1--EMPTY--- | |
---EMPTY----1--------COVERED----------4---EMPTY--- | |
------------p0------------------------p1----------*/ | |
pivot: *x0, | |
left: Box::new(Linetree::Empty), | |
right: Box::new(Linetree::Node { | |
pivot: *x1, | |
left: Box::new(Linetree::Filled), | |
right: Box::new(Linetree::Empty), | |
}), | |
}, | |
Linetree::Node { pivot, left, right } => { | |
/* | |
If you already have a Node within your Linetree, then you'd want to organize this by the pivot and insert the line down both sides | |
First up is left side: so pivot is p0 | |
To the left, we either have a new pivot of x0 or the same pivot depending on which is shorter | |
To the right, we have a new pivot of x1 or the same pivot depending on which is longer | |
---EMPTY----x0--------COVERED---------x1--EMPTY--- | |
---EMPTY----1--------COVERED----------4---EMPTY--- | |
------------p0------------------------p1---------- | |
now you insert a line from 1 to 2 | |
---EMPTY----x0--------COVERED---------x1--EMPTY--- | |
---EMPTY----1--------COVERED----------4---EMPTY--- | |
------------p0------------------------p1---------- | |
Notice the left pivot is the same, but the right pivot is the same, because the entirety of the line is covered within the left/right pivots | |
Now you insert a line from 2 to 6 | |
---EMPTY----x0--------COVERED---------x1--EMPTY--- | |
---EMPTY----1--------COVERED----------7---EMPTY--- | |
------------p0------------------------p1---------- | |
Notice the left pivot stayed the same, but the right pivot changed to 7, because the new line to the right of the pivot is longer than the previous pivot. Thus now the entirety of line from 1 to 7 is covered within the left/right pivots | |
*/ | |
Linetree::Node { | |
pivot: *pivot, | |
left: Box::new(left.insert(&Line { x0: std::cmp::min(*x0, *pivot), x1: std::cmp::min(*x1, *pivot) })), | |
right: Box::new(right.insert(&Line { x0: std::cmp::max(*x0, *pivot), x1: std::cmp::max(*x1, *pivot) })), | |
} | |
} | |
} | |
} | |
} | |
} | |
pub fn cov_area(&self, x0: i64, x1: i64) -> i64 { | |
match self { | |
Linetree::Empty => 0, | |
Linetree::Filled => x1 - x0, | |
Linetree::Node {pivot, left, right} => { | |
left.cov_area(x0, *pivot) + right.cov_area(*pivot, x1) | |
} | |
} | |
} | |
} | |
impl Line { | |
pub fn new(x0: i64, x1: i64) -> Line { | |
Line { x0, x1 } | |
} | |
} | |
pub fn total_line_area(lines: Vec<Line>) -> i64 { | |
let mut tree = Linetree::Empty; | |
for line in lines { | |
tree = tree.insert(&line); | |
} | |
return tree.cov_area(i64::MIN, i64::MAX); | |
} | |
} | |
fn main() { | |
let lines = vec! [ | |
overlapping_line::Line::new(1,4), | |
overlapping_line::Line::new(1,7), | |
]; | |
let result = overlapping_line::total_line_area(lines); | |
println!("{}", result); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment