|
|
@ -18,7 +18,7 @@ struct RightState<'a> { |
|
|
|
} |
|
|
|
|
|
|
|
pub struct CompatibilityCache { |
|
|
|
map: HashMap<(usize, usize, usize, bool), bool> |
|
|
|
map: HashMap<(usize, usize, usize, usize, bool), bool> |
|
|
|
} |
|
|
|
|
|
|
|
impl CompatibilityCache { |
|
|
@ -28,12 +28,12 @@ impl CompatibilityCache { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
pub fn is_compatible(&self, left_layout: &SavedLayout, right_layout: &SavedLayout, index: usize, y_axis: bool) -> Option<&bool> { |
|
|
|
self.map.get(&(left_layout.id(), right_layout.id(), index, y_axis)) |
|
|
|
pub fn is_compatible(&self, left_layout: &SavedLayout, right_layout: &SavedLayout, left_update_index: usize, right_update_index: usize, y_axis: bool) -> Option<&bool> { |
|
|
|
self.map.get(&(left_layout.id(), right_layout.id(), left_update_index, right_update_index, y_axis)) |
|
|
|
} |
|
|
|
|
|
|
|
pub fn set_compatible(&mut self, left_layout: &SavedLayout, right_layout: &SavedLayout, index: usize, y_axis: bool, compatible: bool) { |
|
|
|
self.map.insert((left_layout.id(), right_layout.id(), index, y_axis), compatible); |
|
|
|
pub fn set_compatible(&mut self, left_layout: &SavedLayout, right_layout: &SavedLayout, left_update_index: usize, right_update_index: usize, y_axis: bool, compatible: bool) { |
|
|
|
self.map.insert((left_layout.id(), right_layout.id(), left_update_index, right_update_index, y_axis), compatible); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -115,10 +115,10 @@ pub fn try_combine(city: &City, left_layouts: &Vec<SavedLayout>, right_layouts: |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
let compatible = match cache.is_compatible(left.layout, right.layout, x, transposed) { |
|
|
|
let compatible = match cache.is_compatible(left.layout, right.layout, left.line.last_update_x, right.line.last_update_x, transposed) { |
|
|
|
None => { |
|
|
|
let compatible = is_compatible(city, &left.line, &right.line); |
|
|
|
cache.set_compatible(left.layout, right.layout, x, transposed, compatible); |
|
|
|
cache.set_compatible(left.layout, right.layout, left.line.last_update_x, right.line.last_update_x, transposed, compatible); |
|
|
|
compatible |
|
|
|
} |
|
|
|
Some(compatible) => { |
|
|
@ -179,12 +179,14 @@ struct LeftLine { |
|
|
|
covers: Vec<usize>, |
|
|
|
houses: Vec<House>, |
|
|
|
price: u32, |
|
|
|
last_update_x: usize |
|
|
|
} |
|
|
|
|
|
|
|
struct RightLine { |
|
|
|
covers: Vec<usize>, |
|
|
|
houses: VecDeque<House>, |
|
|
|
price: u32, |
|
|
|
last_update_x: usize |
|
|
|
} |
|
|
|
|
|
|
|
impl LeftLine { |
|
|
@ -192,7 +194,7 @@ impl LeftLine { |
|
|
|
// XXX: Careful, default of 0 includes covering first vertical line
|
|
|
|
let covers = vec![0; SIZE]; |
|
|
|
let houses = Vec::new(); |
|
|
|
LeftLine { covers, houses, price: 0 } |
|
|
|
LeftLine { covers, houses, price: 0, last_update_x: 0 } |
|
|
|
} |
|
|
|
|
|
|
|
pub fn add_house(&mut self, house: House, city: &City) { |
|
|
@ -203,6 +205,7 @@ impl LeftLine { |
|
|
|
} |
|
|
|
self.price += city.get_price(house) as u32; |
|
|
|
self.houses.push(house); |
|
|
|
self.last_update_x = house.x; |
|
|
|
} |
|
|
|
|
|
|
|
pub fn get_max_covered_x(&self, y: usize) -> usize { |
|
|
@ -222,7 +225,7 @@ impl RightLine { |
|
|
|
pub fn new() -> Self { |
|
|
|
let covers = vec![usize::MAX; SIZE]; |
|
|
|
let houses = VecDeque::new(); |
|
|
|
RightLine { covers, houses, price: 0 } |
|
|
|
RightLine { covers, houses, price: 0, last_update_x: 0 } |
|
|
|
} |
|
|
|
|
|
|
|
pub fn add_house(&mut self, house: House, city: &City) { |
|
|
@ -233,7 +236,8 @@ impl RightLine { |
|
|
|
} |
|
|
|
|
|
|
|
self.houses.push_back(house); |
|
|
|
self.price += city.get_price(house) as u32 |
|
|
|
self.price += city.get_price(house) as u32; |
|
|
|
self.last_update_x = house.x; |
|
|
|
} |
|
|
|
|
|
|
|
pub fn remove_houses(&mut self, x: usize, city: &City) { |
|
|
@ -264,6 +268,7 @@ impl RightLine { |
|
|
|
} |
|
|
|
|
|
|
|
self.price -= city.get_price(removed_house) as u32; |
|
|
|
self.last_update_x = removed_house.x; |
|
|
|
} else { |
|
|
|
break; |
|
|
|
} |
|
|
|