Skip to content

Commit 047b490

Browse files
committed
Add problem 3143: Maximum Points Inside the Square
1 parent 9372aad commit 047b490

File tree

3 files changed

+124
-0
lines changed

3 files changed

+124
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2104,6 +2104,7 @@ pub mod problem_3136_valid_word;
21042104
pub mod problem_3137_minimum_number_of_operations_to_make_word_k_periodic;
21052105
pub mod problem_3138_minimum_length_of_anagram_concatenation;
21062106
pub mod problem_3142_check_if_grid_satisfies_conditions;
2107+
pub mod problem_3143_maximum_points_inside_the_square;
21072108
pub mod problem_3350_adjacent_increasing_subarrays_detection_ii;
21082109

21092110
#[cfg(test)]
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
pub mod quick_select;
2+
3+
pub trait Solution {
4+
fn max_points_inside_square(points: Vec<Vec<i32>>, s: String) -> i32;
5+
}
6+
7+
#[cfg(test)]
8+
mod tests {
9+
use super::Solution;
10+
11+
pub fn run<S: Solution>() {
12+
let test_cases = [
13+
((&[[2, 2], [-1, -2], [-4, 4], [-3, 1], [3, -3]] as &[_], "abdca"), 2),
14+
((&[[1, 1], [-2, -2], [-2, 2]], "abb"), 1),
15+
((&[[1, 1], [-1, -1], [2, -2]], "ccd"), 0),
16+
];
17+
18+
for ((points, s), expected) in test_cases {
19+
assert_eq!(
20+
S::max_points_inside_square(points.iter().map(Vec::from).collect(), s.to_string()),
21+
expected,
22+
);
23+
}
24+
}
25+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
pub struct Solution;
2+
3+
// ------------------------------------------------------ snip ------------------------------------------------------ //
4+
5+
use std::mem;
6+
7+
impl Solution {
8+
pub fn partition<T>(values: &mut [T], mut f: impl FnMut(&T) -> bool) -> usize {
9+
let mut result = 0;
10+
let mut iter = values.iter_mut();
11+
12+
'outer: while let Some(left) = iter.next() {
13+
if !f(left) {
14+
loop {
15+
if let Some(right) = iter.next_back() {
16+
if f(right) {
17+
mem::swap(left, right);
18+
19+
break;
20+
}
21+
} else {
22+
break 'outer;
23+
}
24+
}
25+
}
26+
27+
result += 1;
28+
}
29+
30+
result
31+
}
32+
33+
pub fn max_points_inside_square(points: Vec<Vec<i32>>, s: String) -> i32 {
34+
let mut points = points
35+
.into_iter()
36+
.zip(s.into_bytes())
37+
.map(|(point, tag)| {
38+
let [x, y] = point.try_into().unwrap();
39+
40+
(x.unsigned_abs().max(y.unsigned_abs()), 1 << (tag - b'a'))
41+
})
42+
.collect::<Vec<_>>();
43+
44+
let sort_key = |&(x, _): &_| x;
45+
46+
if points.len() < 27 {
47+
points.sort_unstable_by_key(sort_key);
48+
} else {
49+
let key = points.select_nth_unstable_by_key(25, sort_key).1.0;
50+
let n = Self::partition(&mut points[26..], |&(x, _)| x == key);
51+
52+
points.truncate(26 + n);
53+
points[..25].sort_unstable_by_key(sort_key);
54+
}
55+
56+
points.dedup_by(|right, left| {
57+
let is_same = left.0 == right.0;
58+
59+
if is_same {
60+
if left.1 & right.1 == 0 {
61+
left.1 |= right.1;
62+
} else {
63+
left.1 = u32::MAX;
64+
}
65+
}
66+
67+
is_same
68+
});
69+
70+
let mut bits = 0;
71+
72+
for point in points {
73+
if point.1 != u32::MAX && point.1 & bits == 0 {
74+
bits |= point.1;
75+
} else {
76+
break;
77+
}
78+
}
79+
80+
bits.count_ones().cast_signed()
81+
}
82+
}
83+
84+
// ------------------------------------------------------ snip ------------------------------------------------------ //
85+
86+
impl super::Solution for Solution {
87+
fn max_points_inside_square(points: Vec<Vec<i32>>, s: String) -> i32 {
88+
Self::max_points_inside_square(points, s)
89+
}
90+
}
91+
92+
#[cfg(test)]
93+
mod tests {
94+
#[test]
95+
fn test_solution() {
96+
super::super::tests::run::<super::Solution>();
97+
}
98+
}

0 commit comments

Comments
 (0)