Skip to content

Commit f50d7be

Browse files
committed
Add problem 846: Hand of Straights
1 parent 9294d0a commit f50d7be

File tree

4 files changed

+174
-0
lines changed

4 files changed

+174
-0
lines changed

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ pub mod problem_0838_push_dominoes;
691691
pub mod problem_0841_keys_and_rooms;
692692
pub mod problem_0844_backspace_string_compare;
693693
pub mod problem_0845_longest_mountain_in_array;
694+
pub mod problem_0846_hand_of_straights;
694695
pub mod problem_0867_transpose_matrix;
695696
pub mod problem_1143_longest_common_subsequence;
696697
pub mod problem_1192_critical_connections_in_a_network;
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
pub struct Solution;
2+
3+
// ------------------------------------------------------ snip ------------------------------------------------------ //
4+
5+
use std::collections::HashMap;
6+
7+
impl Solution {
8+
pub fn is_n_straight_hand(hand: Vec<i32>, group_size: i32) -> bool {
9+
let group_size = group_size as usize;
10+
11+
if hand.len() % group_size == 0 {
12+
let mut cards = HashMap::new();
13+
14+
for card in hand {
15+
cards.entry(card).and_modify(|count| *count += 1).or_insert(1);
16+
}
17+
18+
let mut cards = cards.into_iter().collect::<Vec<_>>();
19+
20+
cards.sort_unstable_by_key(|&(card, _)| card);
21+
22+
if let Some(max_i) = cards.len().checked_sub(group_size) {
23+
for i in 0..=max_i {
24+
let (&mut (first_card, first_count), rest) = cards[i..i + group_size].split_first_mut().unwrap();
25+
26+
if first_count != 0 {
27+
let mut prev_card = first_card;
28+
29+
for (card, count) in rest {
30+
if *card == prev_card + 1 && *count >= first_count {
31+
*count -= first_count;
32+
prev_card = *card;
33+
} else {
34+
return false;
35+
}
36+
}
37+
}
38+
}
39+
40+
return cards[cards.len() - group_size + 1..]
41+
.iter()
42+
.all(|&(_, count)| count == 0);
43+
}
44+
}
45+
46+
false
47+
}
48+
}
49+
50+
// ------------------------------------------------------ snip ------------------------------------------------------ //
51+
52+
impl super::Solution for Solution {
53+
fn is_n_straight_hand(hand: Vec<i32>, group_size: i32) -> bool {
54+
Self::is_n_straight_hand(hand, group_size)
55+
}
56+
}
57+
58+
#[cfg(test)]
59+
mod tests {
60+
#[test]
61+
fn test_solution() {
62+
super::super::tests::run::<super::Solution>();
63+
}
64+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
pub struct Solution;
2+
3+
// ------------------------------------------------------ snip ------------------------------------------------------ //
4+
5+
use std::collections::hash_map::DefaultHasher;
6+
use std::collections::HashMap;
7+
use std::hash::BuildHasherDefault;
8+
9+
// <https://leetcode.com/problems/hand-of-straights/discuss/137794/Python-true-O(N)-solution>.
10+
11+
impl Solution {
12+
pub fn is_n_straight_hand(hand: Vec<i32>, group_size: i32) -> bool {
13+
if hand.len() % group_size as usize == 0 {
14+
let mut cards = HashMap::with_hasher(BuildHasherDefault::<DefaultHasher>::default());
15+
16+
for card in hand {
17+
cards.entry(card).and_modify(|count| *count += 1).or_insert(1);
18+
}
19+
20+
let mut straights = HashMap::new();
21+
let mut opened = 0;
22+
23+
while let Some(&card) = cards.keys().next() {
24+
let mut card = card;
25+
26+
while cards.contains_key(&(card - 1)) {
27+
card -= 1;
28+
}
29+
30+
while let Some(count) = cards.remove(&card) {
31+
if count < opened {
32+
return false;
33+
}
34+
35+
let new_open = count - opened;
36+
37+
if new_open != 0 {
38+
straights.insert(card, new_open);
39+
}
40+
41+
opened = straights
42+
.remove(&(card - group_size + 1))
43+
.map_or(count, |closed| count - closed);
44+
45+
card += 1;
46+
}
47+
48+
if opened != 0 {
49+
return false;
50+
}
51+
}
52+
53+
true
54+
} else {
55+
false
56+
}
57+
}
58+
}
59+
60+
// ------------------------------------------------------ snip ------------------------------------------------------ //
61+
62+
impl super::Solution for Solution {
63+
fn is_n_straight_hand(hand: Vec<i32>, group_size: i32) -> bool {
64+
Self::is_n_straight_hand(hand, group_size)
65+
}
66+
}
67+
68+
#[cfg(test)]
69+
mod tests {
70+
#[test]
71+
fn test_solution() {
72+
super::super::tests::run::<super::Solution>();
73+
}
74+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
pub mod iterative;
2+
pub mod iterative_2;
3+
4+
pub trait Solution {
5+
fn is_n_straight_hand(hand: Vec<i32>, group_size: i32) -> bool;
6+
}
7+
8+
#[cfg(test)]
9+
mod tests {
10+
use super::Solution;
11+
12+
pub fn run<S: Solution>() {
13+
let test_cases = [
14+
((&[1, 2, 3, 6, 2, 3, 4, 7, 8] as &[_], 3), true),
15+
((&[1, 2, 3, 4, 5], 4), false),
16+
((&[0, 0], 2), false),
17+
(
18+
(
19+
&[
20+
9, 13, 15, 23, 22, 25, 4, 4, 29, 15, 8, 23, 12, 19, 24, 17, 18, 11, 22, 24, 17, 17, 10, 23, 21,
21+
18, 14, 18, 7, 6, 3, 6, 19, 11, 16, 11, 12, 13, 8, 26, 17, 20, 13, 19, 22, 21, 27, 9, 20, 15,
22+
20, 27, 8, 13, 25, 23, 22, 15, 9, 14, 20, 10, 6, 5, 14, 12, 7, 16, 21, 18, 21, 24, 23, 10, 21,
23+
16, 18, 16, 18, 5, 20, 19, 20, 10, 14, 26, 2, 9, 19, 12, 28, 17, 5, 7, 25, 22, 16, 17, 21, 11,
24+
],
25+
10,
26+
),
27+
false,
28+
),
29+
];
30+
31+
for ((hand, group_size), expected) in test_cases {
32+
assert_eq!(S::is_n_straight_hand(hand.to_vec(), group_size), expected);
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)