Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to count number of strings we can make using grammar rules in Python
Suppose we have a number n, we have to find the number of strings of length n can be generated using the following grammar rules ?
Each character is a lower case vowel [a, e, i, o, u]
"a" may only be followed by one "e"
"e" may only be followed by any of "a" and "i"
"i" may not be followed by another "i"
"o" may only be followed by any of "i" and "u"
"u" may only be followed by one "a"
If the result is very large, mod the result by 10^9 + 7.
So, if the input is like n = 2, then the output will be 10, as we can generate the following two letter strings: ["ae", "ea", "ei", "ia", "ie", "io", "iu", "oi", "ou", "ua"]
Algorithm
To solve this, we will follow these steps ?
m = 10^9 + 7
if n is same as 0, then return 0
define five variables a, e, i, o, u, all are 1 initially
for each position from 2 to n, update the counts based on grammar rules
return (a + e + i + o + u) mod m
How It Works
We use dynamic programming where each vowel variable represents the number of valid strings ending with that vowel. For each position, we calculate how many strings can end with each vowel based on the transition rules ?
class Solution:
def solve(self, n):
m = (10 ** 9 + 7)
if n == 0:
return 0
# Initial count: each vowel can start a string
a = e = i = o = u = 1
# For each additional position
for _ in range(n-1):
# Calculate new counts based on transition rules
new_a = e + i + u # 'a' can follow 'e', 'i', 'u'
new_e = a + i # 'e' can follow 'a', 'i'
new_i = e + o # 'i' can follow 'e', 'o'
new_o = i # 'o' can follow 'i'
new_u = i + o # 'u' can follow 'i', 'o'
a, e, i, o, u = new_a, new_e, new_i, new_o, new_u
return (a + e + i + o + u) % m
# Test the solution
ob = Solution()
print("Strings of length 2:", ob.solve(2))
print("Strings of length 3:", ob.solve(3))
print("Strings of length 1:", ob.solve(1))
Strings of length 2: 10 Strings of length 3: 19 Strings of length 1: 5
Transition Rules Visualization
Example Breakdown
For n=2, we can form these valid strings ?
Starting with 'a': ae (1 string)
Starting with 'e': ea, ei (2 strings)
Starting with 'i': ia, ie, io, iu (4 strings)
Starting with 'o': oi, ou (2 strings)
Starting with 'u': ua (1 string)
Total: 1 + 2 + 4 + 2 + 1 = 10 strings
Conclusion
This dynamic programming approach efficiently counts valid strings by tracking how many strings can end with each vowel at each position. The time complexity is O(n) and space complexity is O(1), making it optimal for large values of n.
