From 7fbad410b105e7e64b89018dc8125f85db182134 Mon Sep 17 00:00:00 2001 From: erius Date: Thu, 18 Apr 2024 03:14:34 +0300 Subject: [PATCH] Implemented problems 11-12, improved problem 10 runtime using dynamic programming --- src/bin/10_regular_expression_matching.rs | 107 +++------------------- src/bin/11_container_with_most_water.rs | 20 ++++ src/bin/12_integer_to_roman.rs | 15 +++ 3 files changed, 48 insertions(+), 94 deletions(-) create mode 100644 src/bin/11_container_with_most_water.rs create mode 100644 src/bin/12_integer_to_roman.rs diff --git a/src/bin/10_regular_expression_matching.rs b/src/bin/10_regular_expression_matching.rs index 6354bfb..19f173d 100644 --- a/src/bin/10_regular_expression_matching.rs +++ b/src/bin/10_regular_expression_matching.rs @@ -1,101 +1,20 @@ fn main() { - let matcher = RegexMatcher::new(String::from(".*")); - println!("{}", matcher.match_str(String::from("abaaaddddcccd"))); - println!(); - println!("{}", matcher.match_str(String::from("abcd"))); + println!("{}", is_match(String::from("acaabbaccbbacaabbbb"), String::from("a*.*b*.*a*aa*a*"))) } -// TODO: improve runtime -pub fn is_match(s: String, p: String) -> bool { RegexMatcher::new(p).match_str(s) } - -#[derive(Debug, Clone)] -enum Pattern { - ZeroOrMore(char), - SameAs(String), - AnyChar, - ZeroOrMoreAny -} - - -struct RegexMatcher { - patterns: Vec -} - -impl RegexMatcher { - fn new(p: String) -> RegexMatcher { - let mut patterns: Vec = Vec::new(); - let mut buf: String = String::new(); - let mut is_zero_or_more = false; - for c in p.chars().rev() { - match c { - '*' => { - is_zero_or_more = true; - } - '.' => { - if !buf.is_empty() { - patterns.push(Pattern::SameAs(buf.clone())); - buf.clear(); - } - if is_zero_or_more { - patterns.push(Pattern::ZeroOrMoreAny); - is_zero_or_more = false; - } else { - patterns.push(Pattern::AnyChar); - } - } - _ => { - if is_zero_or_more { - if !buf.is_empty() { - patterns.push(Pattern::SameAs(buf.clone())); - buf.clear(); - } - patterns.push(Pattern::ZeroOrMore(c)); - is_zero_or_more = false; - } else { - buf.insert(0, c); - } - } - } - } - if !buf.is_empty() { patterns.push(Pattern::SameAs(buf)); } - patterns.reverse(); - return Self { patterns }; - } - - fn match_str(&self, s: String) -> bool { Self::match_patterns(&s, &self.patterns) } - - fn match_patterns(s: &str, patterns: &[Pattern]) -> bool { - if patterns.is_empty() { return s.is_empty(); } - return match &patterns[0] { - Pattern::SameAs(str) => { - if str.len() > s.len() || str != &s[0..str.len()] { return false; } - Self::match_patterns(&s[str.len()..], &patterns[1..]) - } - Pattern::AnyChar => { - if s.len() < 1 { return false; } - Self::match_patterns(&s[1..], &patterns[1..]) - } - Pattern::ZeroOrMore(char) => { - if s.is_empty() { return Self::match_patterns(&s, &patterns[1..]); } - let mut max_length = 0usize; - for c in s.chars() { - if c != *char { break; } - max_length += 1; - } - for length in (0..=max_length).rev() { - let result = Self::match_patterns(&s[length..], &patterns[1..]); - if result { return result; } - } - false - } - Pattern::ZeroOrMoreAny => { - if s.is_empty() { return Self::match_patterns(&s, &patterns[1..]); } - for length in (0..=s.len()).rev() { - let result = Self::match_patterns(&s[length..], &patterns[1..]); - if result { return result; } - } - false +pub fn is_match(s: String, p: String) -> bool { + let (s, p) = (s.as_bytes(), p.as_bytes()); + let mut dp = vec![vec![false; p.len() + 1]; s.len() + 1]; + dp[s.len()][p.len()] = true; + for i in (0..=s.len()).rev() { + for j in (0..p.len()).rev() { + let first_match = i < s.len() && (p[j] == b'.' || p[j] == s[i]); + if j + 1 < p.len() && p[j + 1] == b'*' { + dp[i][j] = first_match && dp[i + 1][j] || dp[i][j + 2]; + continue; } + dp[i][j] = first_match && dp[i + 1][j + 1]; } } + return dp[0][0]; } diff --git a/src/bin/11_container_with_most_water.rs b/src/bin/11_container_with_most_water.rs new file mode 100644 index 0000000..5937f31 --- /dev/null +++ b/src/bin/11_container_with_most_water.rs @@ -0,0 +1,20 @@ +fn main() { + println!("{}", max_area(vec![1,8,6,2,5,4,8,3,7])); +} + +pub fn max_area(height: Vec) -> i32 { + let (mut left, mut right) = (0, height.len() - 1); + let mut max_water = 0; + while left < right { + let x = (right - left) as i32; let h; + if height[left] < height[right] { + h = height[left]; + left += 1; + } else { + h = height[right]; + right -= 1; + }; + max_water = max_water.max(h * x); + } + return max_water; +} diff --git a/src/bin/12_integer_to_roman.rs b/src/bin/12_integer_to_roman.rs new file mode 100644 index 0000000..d801fbb --- /dev/null +++ b/src/bin/12_integer_to_roman.rs @@ -0,0 +1,15 @@ +fn main() { + +} + +// TODO: implement solution +pub fn int_to_roman(num: i32) -> String { + let roman_to_int = vec![ + ('M', 1000), ('D', 500), ('C', 100), + ('L', 50), ('X', 10), ('V', 5), ('I', 1) + ]; + for i in 0..roman_to_int.len() { + + } + return String::new(); +}