diff --git a/problems/count-vowels-permutation.rs b/problems/count-vowels-permutation.rs new file mode 100644 index 0000000..cf5cfec --- /dev/null +++ b/problems/count-vowels-permutation.rs @@ -0,0 +1,104 @@ +use std::collections::HashMap; + +type CacheKey = (i32, char); +struct Cache { + cache: HashMap, +} + +impl Cache { + const MODULO: i32 = 1000000007; + + fn new() -> Cache { + let mut cache = HashMap::::new(); + + for c in "aeiou".chars() { + cache.insert((1, c), 1); + } + + Cache { cache: cache } + } + + fn is_precomputed(&self, n: i32) -> bool { + self.cache.keys().any(|key| key.0 == n) + } + + fn get(&self, n: i32) -> i32 { + self.cache + .keys() + .filter(|key| key.0 == n) + .fold(0, |acc, key| { + // Since the answer may be too large, return it modulo 10^9 + 7. + (acc + self.cache.get(key).unwrap_or(&0)) % Self::MODULO + }) + } + + fn precompute(&mut self, n: i32) { + if self.is_precomputed(n) { + return; + } + + if !self.is_precomputed(n - 1) { + self.precompute(n - 1); + } + + for (current, continuation) in vec![ + ('a', "e"), + ('e', "ai"), + ('i', "aeou"), + ('o', "iu"), + ('u', "a"), + ] { + self.cache.insert( + (n, current), + continuation.chars().fold(0, |acc, vowel| { + (acc + self.cache.get(&(n - 1, vowel)).unwrap()) % Self::MODULO + }), + ); + } + } +} + +struct Solution {} +impl Solution { + pub fn count_vowel_permutation(n: i32) -> i32 { + let mut cache = Cache::new(); + cache.precompute(n); + + cache.get(n) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_example_1() { + // Input: n = 1 + // Output: 5 + // Explanation: All possible strings are: "a", "e", "i" , "o" and "u". + assert_eq!(count_vowel_permutation(1), 5); + } + + #[test] + fn test_example_2() { + // Input: n = 2 + // Output: 10 + // Explanation: All possible strings are: All possible strings are: "ae", "ea", "ei", "ia", "ie", "io", "iu", "oi", "ou" and "ua". + assert_eq!(count_vowel_permutation(2), 10); + } + + #[test] + fn test_example_3() { + // Input: n = 5 + // Output: 68 + assert_eq!(count_vowel_permutation(5), 68); + } + + #[test] + fn test_example_4() { + // Input: n = 3 + // Output: 19 + assert_eq!(count_vowel_permutation(3), 19); + } +}