Saturday, November 16, 2024
Google search engine
HomeData Modelling & AILook-and-Say Sequence

Look-and-Say Sequence

Find the n’th term in Look-and-say (Or Count and Say) Sequence. The look-and-say sequence is the sequence of the below integers: 
1, 11, 21, 1211, 111221, 312211, 13112221, 1113213211, … 

How is the above sequence generated? 
n’th term is generated by reading (n-1)’th term.

The first term is "1"
Second term is "11", generated by reading first term as "One 1"
(There is one 1 in previous term)
Third term is "21", generated by reading second term as "Two 1"
Fourth term is "1211", generated by reading third term as "One 2 One 1"
and so on

How to find n’th term? 

Example: 

Input: n = 3
Output: 21
Input: n = 5
Output: 111221

Recommended Practice

The idea is simple, we generate all terms from 1 to n. First, two terms are initialized as “1” and “11”, and all other terms are generated using previous terms. To generate a term using the previous term, we scan the previous term. While scanning a term, we simply keep track of the count of all consecutive characters. For a sequence of the same characters, we append the count followed by the character to generate the next term.

Below is an implementation of the above idea.  

C++




// C++ program to find n'th term in look and say
// sequence
#include <bits/stdc++.h>
using namespace std;
 
// Returns n'th term in look-and-say sequence
string countnndSay(int n)
{
    // Base cases
    if (n == 1)      return "1";
    if (n == 2)      return "11";
 
    // Find n'th term by generating all terms from 3 to
    // n-1.  Every term is generated using previous term
    string str = "11"; // Initialize previous term
    for (int i = 3; i<=n; i++)
    {
        // In below for loop, previous character
        // is processed in current iteration. That
        // is why a dummy character is added to make
        // sure that loop runs one extra iteration.
        str += '$';
        int len = str.length();
 
        int cnt = 1; // Initialize count of matching chars
        string  tmp = ""; // Initialize i'th term in series
 
        // Process previous term to find the next term
        for (int j = 1; j < len; j++)
        {
            // If current character doesn't match
            if (str[j] != str[j-1])
            {
                // Append count of str[j-1] to temp
                tmp += cnt + '0';
 
                // Append str[j-1]
                tmp += str[j-1];
 
                // Reset count
                cnt = 1;
            }
 
            //  If matches, then increment count of matching
            // characters
            else cnt++;
        }
 
        // Update str
        str = tmp;
    }
 
    return str;
}
 
// Driver program
int main()
{
    int N = 3;
    cout << countnndSay(N) << endl;
    return 0;
}


Java




// Java program to find n'th
// term in look and say sequence
 
class GFG
{
 
    // Returns n'th term in
    // look-and-say sequence
    static String countnndSay(int n)
    {
    // Base cases
    if (n == 1)     return "1";
    if (n == 2)     return "11";
 
    // Find n'th term by generating
    // all terms from 3 to n-1.
    // Every term is generated
    // using previous term
     
    // Initialize previous term
    String str = "11";
    for (int i = 3; i <= n; i++)
    {
        // In below for loop, previous
        // character is processed in
        // current iteration. That is
        // why a dummy character is
        // added to make sure that loop
        // runs one extra iteration.
        str += '$';
        int len = str.length();
 
        int cnt = 1; // Initialize count
                     // of matching chars
        String tmp = ""; // Initialize i'th
                         // term in series
        char []arr = str.toCharArray();
         
        // Process previous term
        // to find the next term
        for (int j = 1; j < len; j++)
        {
            // If current character
            // doesn't match
            if (arr[j] != arr[j - 1])
            {
                // Append count of
                // str[j-1] to temp
                tmp += cnt + 0;
 
                // Append str[j-1]
                tmp += arr[j - 1];
 
                // Reset count
                cnt = 1;
            }
 
            // If matches, then increment
            // count of matching characters
            else cnt++;
        }
 
        // Update str
        str = tmp;
    }
 
    return str;
    }
     
    // Driver Code
    public static void main(String[] args)
    {
        int N = 3;
        System.out.println(countnndSay(N));
    }
}
 
// This code is contributed
// by ChitraNayal


Python3




# Python 3 program to find
# n'th term in look and
# say sequence
 
# Returns n'th term in
# look-and-say sequence
def countnndSay(n):
     
    # Base cases
    if (n == 1):
        return "1"
    if (n == 2):
        return "11"
 
    # Find n'th term by generating
    # all terms from 3 to n-1.
    # Every term is generated using
    # previous term
     
    # Initialize previous term
    s = "11"
    for i in range(3, n + 1):
         
        # In below for loop,
        # previous character is
        # processed in current
        # iteration. That is why
        # a dummy character is
        # added to make sure that
        # loop runs one extra iteration.
        s += '$'
        l = len(s)
 
        cnt = 1 # Initialize count
                # of matching chars
        tmp = "" # Initialize i'th
                 # term in series
 
        # Process previous term to
        # find the next term
        for j in range(1 , l):
             
            # If current character
            # doesn't match
            if (s[j] != s[j - 1]):
                 
                # Append count of
                # str[j-1] to temp
                tmp += str(cnt + 0)
 
                # Append str[j-1]
                tmp += s[j - 1]
 
                # Reset count
                cnt = 1
             
            # If matches, then increment
            # count of matching characters
            else:
                cnt += 1
 
        # Update str
        s = tmp
    return s;
 
# Driver Code
N = 3
print(countnndSay(N))
 
# This code is contributed
# by ChitraNayal


C#




// C# program to find n'th
// term in look and say sequence
using System;
 
class GFG
{
 
    // Returns n'th term in
    // look-and-say sequence
    static string countnndSay(int n)
    {
    // Base cases
    if (n == 1)     return "1";
    if (n == 2)     return "11";
 
    // Find n'th term by generating
    // all terms from 3 to n-1.
    // Every term is generated using
    // previous term
     
    // Initialize previous term
    string str = "11";
    for (int i = 3; i <= n; i++)
    {
        // In below for loop, previous
        // character is processed in
        // current iteration. That is
        // why a dummy character is
        // added to make sure that loop
        // runs one extra iteration.
        str += '$';
        int len = str.Length;
 
        int cnt = 1; // Initialize count of
                     // matching chars
        string tmp = ""; // Initialize i'th
                         // term in series
        char []arr = str.ToCharArray();
         
        // Process previous term
        // to find the next term
        for (int j = 1; j < len; j++)
        {
            // If current character
            // doesn't match
            if (arr[j] != arr[j - 1])
            {
                 // Append count of
                // str[j-1] to temp
                tmp += cnt + 0;
 
                // Append str[j-1]
                tmp += arr[j - 1];
 
                // Reset count
                cnt = 1;
            }
 
            // If matches, then increment
            // count of matching characters
            else cnt++;
        }
 
        // Update str
        str = tmp;
    }
 
    return str;
    }
     
    // Driver Code
    public static void Main()
    {
        int N = 3;
        Console.Write(countnndSay(N));
    }
}
 
// This code is contributed
// by ChitraNayal


Javascript




<script>
 
// Javascript program to find n'th
// term in look and say sequence
     
// Returns n'th term in
// look-and-say sequence
function countnndSay(n)
{
     
    // Base cases
    if (n == 1)    
        return "1";
    if (n == 2)    
        return "11";
   
    // Find n'th term by generating
    // all terms from 3 to n-1.
    // Every term is generated
    // using previous term
       
    // Initialize previous term
    let str = "11";
     
    for(let i = 3; i <= n; i++)
    {
         
        // In below for loop, previous
        // character is processed in
        // current iteration. That is
        // why a dummy character is
        // added to make sure that loop
        // runs one extra iteration.
        str += '$';
        let len = str.length;
         
        // Initialize count
        // of matching chars
        let cnt = 1;
         
        // Initialize i'th
        // term in series
        let tmp = "";
        let arr = str.split("");
           
        // Process previous term
        // to find the next term
        for(let j = 1; j < len; j++)
        {
             
            // If current character
            // doesn't match
            if (arr[j] != arr[j - 1])
            {
                 
                // Append count of
                // str[j-1] to temp
                tmp += cnt + 0;
   
                // Append str[j-1]
                tmp += arr[j - 1];
   
                // Reset count
                cnt = 1;
            }
   
            // If matches, then increment
            // count of matching characters
            else cnt++;
        }
   
        // Update str
        str = tmp;
    }
    return str;
}
 
// Driver Code
let N = 3;
 
document.write(countnndSay(N));
 
// This code is contributed by avanitrachhadiya2155
 
</script>


PHP




<?php
// PHP program to find
// n'th term in look
// and say sequence
 
// Returns n'th term in
// look-and-say sequence
function countnndSay($n)
{
    // Base cases
    if ($n == 1)    
        return "1";
    if ($n == 2)    
        return "11";
 
    // Find n'th term by generating
    // all terms from 3 to n-1.
    // Every term is generated
    // using previous term
     
    // Initialize previous term
    $str = "11";
    for ($i = 3;
         $i <= $n; $i++)
    {
        // In below for loop,
        // previous character is
        // processed in current
        // iteration. That is why
        // a dummy character is
        // added to make sure that
        // loop runs one extra iteration.
        $str = $str.'$';
        $len = strlen($str);
 
        $cnt = 1; // Initialize count of
                  // matching chars
        $tmp = ""; // Initialize i'th
                   // term in series
 
        // Process previous term
        // to find the next term
        for ($j = 1; $j < $len; $j++)
        {
            // If current character
            // doesn't match
            if ($str[$j] != $str[$j - 1])
            {
                // Append count of
                // str[j-1] to temp
                $tmp = $tmp.$cnt + 0;
 
                // Append str[j-1]
                $tmp = $tmp. $str[$j - 1];
 
                // Reset count
                $cnt = 1;
            }
 
            // If matches, then increment
            // count of matching characters
            else $cnt++;
        }
 
        // Update str
        $str = $tmp;
    }
 
    return $str;
}
 
// Driver Code
$N = 3;
echo countnndSay($N);
return 0;
 
// This code is contributed
// by ChitraNayal
?>


Output

21






Time Complexity : O(n2

Auxiliary Space : O(1)

Another Approach(Using STL): There is one more idea where we can use unordered_map from c++ stl to track the count of digits. Basic idea is to use a generator function that will generate a string from the previous string. In the count and say function we will iterate over integers from 1 to n-1 and keep updating our result.

C++




#include <bits/stdc++.h>
using namespace std;
 
// generator function returns int string from prev int
// string e.g. -> it will return '1211' for '21' ( One 2's
// and One 1)
string generator(string str)
{
    string ans = "";
 
    unordered_map<char, int>
        tempCount; // It is used to count integer sequence
 
    for (int i = 0; i < str.length() + 1; i++) {
        // when current char is different from prev one we
        // clear the map and update the ans
        if (tempCount.find(str[i]) == tempCount.end()
            && i > 0) {
            auto prev = tempCount.find(str[i - 1]);
            ans += to_string(prev->second) + prev->first;
            tempCount.clear();
        }
        // when current char is same as prev one we increase
        // it's count value
        tempCount[str[i]]++;
    }
 
    return ans;
}
 
string countnndSay(int n)
{
    string res = "1"; // res variable keep tracks of string
                      // from 1 to n-1
 
    // For loop iterates for n-1 time and generate strings
    // in sequence "1" -> "11" -> "21" -> "1211"
    for (int i = 1; i < n; i++) {
        res = generator(res);
    }
 
    return res;
}
 
int main()
{
 
    int N = 3;
    cout << countnndSay(N) << endl;
    return 0;
}


Java




import java.io.*;
import java.util.*;
 
class GFG {
  // generator function returns int string from prev int
  // string e.g. -> it will return '1211' for '21' ( One 2's
  // and One 1)
  static String generator(String str)
  {
    String ans = "";
 
    HashMap<Character, Integer>tempCount = new HashMap<>(); // It is used to count integer sequence
 
    for (int i = 0; i < str.length() + 1; i++) {
      // when current char is different from prev one we
      // clear the map and update the ans
      if (i == str.length()  || tempCount.containsKey(str.charAt(i)) == false && i > 0) {
        ans += String.valueOf(tempCount.get(str.charAt(i-1))) + str.charAt(i-1);
        tempCount.clear();
      }
      // when current char is same as prev one we increase
      // it's count value
 
      if(i == str.length()){
        tempCount.put(null, 1);
      }
      else{
        if(tempCount.containsKey(str.charAt(i))){
          tempCount.put(str.charAt(i), tempCount.get(str.charAt(i))+1);
        }
        else{
          if(i != str.length())tempCount.put(str.charAt(i), 1);
        }
      }
    }
    return ans;
  }
 
  static String countnndSay(int n)
  {
    String res = "1"; // res variable keep tracks of string
    // from 1 to n-1
 
    // For loop iterates for n-1 time and generate strings
    // in sequence "1" -> "11" -> "21" -> "1211"
    for (int i = 1; i < n; i++) {
      res = generator(res);
    }
 
    return res;
  }
 
  // Driver Code
  public static void main(String args[])
  {
    int N = 3;
    System.out.println(countnndSay(N));
  }
}
 
// This code is contributed by shinjanpatra


Python3




def generator(s):
   
    # variable to store the result string
    ans = ""
     
    # use a dictionary to count the integer sequence
    tempCount = {}
     
    # loop through the input string
    for i in range(len(s) + 1):
       
        # when the current character is different from the previous one
        # or the end of the input string has been reached
        # update the result string and clear the dictionary
        if i == len(s) or s[i] not in tempCount and i > 0:
            ans += str(tempCount[s[i-1]]) + s[i-1]
            tempCount.clear()
             
        # when the end of the input string has been reached
        if i == len(s):
            tempCount[None] = 1
        else:
           
            # when the current character is the same as the previous one
            # increase its count value
            if s[i] in tempCount:
                tempCount[s[i]] += 1
            else:
               
                # add the character to the dictionary with a count of 1
                tempCount[s[i]] = 1
                 
    # return the result string
    return ans
 
def countAndSay(n):
   
    # initialize the result string with "1"
    res = "1"
     
    # loop n-1 times to generate the sequence of strings
    for i in range(1, n):
        res = generator(res)
         
    # return the result string
    return res
 
N = 3
 
# call the countAndSay function with input N and print the result
print(countAndSay(N))
 
# This Code is Contributed by chinmaya121221


C#




using System;
using System.Collections.Generic;
 
class GFG {
   
  // generator function returns int string from prev int
  // string e.g. -> it will return '1211' for '21' ( One 2's
  // and One 1)
  static string generator(string str)
  {
    string ans = "";
 
    Dictionary<char, int> tempCount = new Dictionary<char, int>(); // It is used to count integer sequence
 
    for (int i = 0; i < str.Length + 1; i++) {
       
      // when current char is different from prev one we
      // clear the map and update the ans
      if (i == str.Length || !tempCount.ContainsKey(str[i]) && i > 0) {
        ans += tempCount[str[i - 1]].ToString() + str[i - 1];
        tempCount.Clear();
      }
       
      // when current char is same as prev one we increase
      // it's count value
      if(i == str.Length){
        tempCount.Add('\0', 1);
      }
      else{
        if(tempCount.ContainsKey(str[i])){
          tempCount[str[i]]++;
        }
        else{
          if(i != str.Length)tempCount.Add(str[i], 1);
        }
      }
    }
    return ans;
  }
 
  static string countnndSay(int n)
  {
    string res = "1"; // res variable keep tracks of string
    // from 1 to n-1
 
    // For loop iterates for n-1 time and generate strings
    // in sequence "1" -> "11" -> "21" -> "1211"
    for (int i = 1; i < n; i++) {
      res = generator(res);
    }
 
    return res;
  }
 
  // Driver Code
  public static void Main()
  {
    int N = 3;
    Console.WriteLine(countnndSay(N));
  }
}


Javascript




// generator function returns the count-and-say string for the previous string
// e.g. it will return '1211' for '21' (One 2's and One 1's)
function generator(str) {
  let ans = "";
  let tempCount = new Map(); // It is used to count integer sequences
 
  for (let i = 0; i < str.length + 1; i++) {
    // When the current character is different from the previous one,
    // we clear the map and update the ans
    if (!tempCount.has(str[i]) && i > 0) {
      const prev = tempCount.get(str[i - 1]);
      ans += prev + str[i - 1];
      tempCount.clear();
    }
 
    // When the current character is the same as the previous one,
    // we increase its count value
    tempCount.set(str[i], (tempCount.get(str[i]) || 0) + 1);
  }
 
  return ans;
}
 
function countAndSay(n) {
  let res = "1"; // res variable keeps track of strings from 1 to n-1
 
  // For loop iterates n-1 times and generates strings in sequence
  // "1" -> "11" -> "21" -> "1211"
  for (let i = 1; i < n; i++) {
    res = generator(res);
  }
 
  return res;
}
 
const N = 3;
console.log(countAndSay(N));


Output

21






Thanks to Utkarsh and Neeraj for suggesting the above solution.

Please write comments if you find anything incorrect, or if you want to share more information about the topic discussed above

Using dynamic programming:

The idea behind the dynamic programming solution to this problem is to generate each row of the look-and-say pattern based on the previous row, and store all the intermediate results in a vector of strings. By doing this, we avoid repeating the same calculations for multiple rows and reduce the overall time complexity of the solution.

The intuition behind this approach is that the look-and-say pattern is self-referential, meaning that each row can be generated from the previous row by counting the consecutive occurrences of each character. Therefore, if we have the ‘i’th row of the look-and-say pattern, we can generate the ‘i+1’th row by counting the consecutive occurrences of each character in the ‘i’th row.

Follow the steps to implement the above approach:

1. Initialize a vector of strings to store the intermediate results. Set the first element of the vector to “1”, which represents the first row of the look-and-say pattern.

2. Use a for loop to generate each row of the look-and-say pattern, starting from the second row (i = 1) up to the nth row (i < n).

3. For each iteration of the loop, initialize an empty string temp to store the next row of the look-and-say pattern.

4. Use a for loop to iterate through the current row of the look-and-say pattern, stored in the i-1th element of the vector.

5. Within the inner for loop, use a while loop to count the number of consecutive occurrences of the same character.

6. After the while loop, append the count of consecutive occurrences and the current character to the temp string.

7. After the inner for loop, add the temp string to the vector of strings as the ith element, which represents the next row of the look-and-say pattern.

8. After the outer for loop, return the nth element of the vector of strings, which represents the nth row of the look-and-say pattern

Below is the implementation of the above approach

C++




// C++ code to implement the above approach
#include <iostream>
#include <vector>
 
using namespace std;
 
// Function to generate the nth row of the look-and-say
// pattern
 
string generateNthRow(int n)
{
  //vector to store all the intermediary results
    vector<string> dp(n + 1);
  //initialization
    dp[1] = "1";
    for (int i = 2; i <= n; i++) {
        string prev = dp[i - 1];
        string curr = "";
        for (int j = 0; j < prev.size(); j++) {
            int count = 1;
            while (j + 1 < prev.size()
                   && prev[j] == prev[j + 1]) {
                count++;
                j++;
            }
            curr += to_string(count) + prev[j];
        }
        dp[i] = curr;
    }
    return dp[n];
}
 
int main()
{
    int n = 3;
    cout << generateNthRow(n) << endl;
    return 0;
}
//This code is contributed by Veerendra Singh Rajpoot


Java




// Java program for the above approach
import java.util.*;
 
public class Main {
  public static String generateNthRow(int n)
  {
 
    // vector to store all the intermediary results
    List<String> dp = new ArrayList<>(n + 1);
 
    // initialization
    dp.add("1");
    for (int i = 2; i <= n; i++) {
      String prev = dp.get(i - 1 - 1);
      String curr = "";
      for (int j = 0; j < prev.length(); j++) {
        int count = 1;
        while (j + 1 < prev.length() && prev.charAt(j) == prev.charAt(j + 1)) {
          count++;
          j++;
        }
        curr += Integer.toString(count) + prev.charAt(j);
      }
      dp.add(curr);
    }
    return dp.get(n - 1);
  }
 
  public static void main(String[] args) {
    int n = 3;
    System.out.println(generateNthRow(n));
  }
}
 
// This code is contributed by codebraxnzt


Python3




# Function to generate the nth row of the look-and-say pattern
def generateNthRow(n):
    # List to store all the intermediary results
    dp = [''] * (n + 1)
    # Initialization
    dp[1] = '1'
    for i in range(2, n + 1):
        prev = dp[i - 1]
        curr = ''
        j = 0
        while j < len(prev):
            count = 1
            while j + 1 < len(prev) and prev[j] == prev[j + 1]:
                count += 1
                j += 1
            curr += str(count) + prev[j]
            j += 1
        dp[i] = curr
    return dp[n]
 
# Example usage
n = 3
print(generateNthRow(n))


C#




using System;
using System.Collections.Generic;
 
public class Program
{
    public static string GenerateNthRow(int n)
    {
        // Vector to store all the intermediary results
        List<string> dp = new List<string>(n + 1);
 
        // Initialization
        dp.Add("1");
 
        for (int i = 2; i <= n; i++)
        {
            // Get the previous row of the sequence
            string prev = dp[i - 1 - 1];
 
            // Create the current row of the sequence
            string curr = "";
            for (int j = 0; j < prev.Length; j++)
            {
                int count = 1;
 
                // Count the number of consecutive digits in the previous row
                while (j + 1 < prev.Length && prev[j] == prev[j + 1])
                {
                    count++;
                    j++;
                }
 
                // Add the count and digit to the current row
                curr += count.ToString() + prev[j];
            }
 
            // Add the current row to the list of intermediary results
            dp.Add(curr);
        }
 
        // Return the Nth row of the sequence
        return dp[n - 1];
    }
 
  // Driver code
    public static void Main(string[] args)
    {
        int n = 3;
        Console.WriteLine(GenerateNthRow(n));
    }
}


Javascript




// JavaScript program for the above approach
function generateNthRow(n) {
 
// array to store all the intermediary results
let dp = ["1"];
 
// initialization
for (let i = 2; i <= n; i++) {
let prev = dp[i - 1 - 1];
let curr = "";
for (let j = 0; j < prev.length; j++) {
let count = 1;
while (j + 1 < prev.length && prev.charAt(j) == prev.charAt(j + 1)) {
count++;
j++;
}
curr += count.toString() + prev.charAt(j);
}
dp.push(curr);
}
return dp[n - 1];
}
 
// Driver Code
let n = 3;
console.log(generateNthRow(n));


Output

21






Explanation of the above code: here we are using a vector of strings dp to store the generated rows of the look-and-say pattern. We initialize the first element of the dp vector with the string “1”.

In the for loop, we iterate from the 2nd row to the nth row and generate each row based on the previous row. We use a nested for loop to iterate over each character of the previous row. The outer for loop keeps track of the current character, and the inner while loop counts the number of consecutive occurrences of the same character. After counting the number of occurrences, we add the count and the current character to the curr string, which represents the current row of the look-and-say pattern. Finally, we update the dp[i] with the curr string.

After the loop, we return the nth row stored in dp[n]

Time Complexity :O(n*m) where n is the number of rows to generate, and m is the maximum length of a row in the look-and-say pattern. 

space complexity : O(n * m), where n is the number of rows to generate and m is the maximum length of a row in the look-and-say pattern. 

Another Approach(Using Stacks):

Intuition:
the problem is simpler if we understand it as just feeding the output of the counting function into itself n times.

f(1) => 11 // base case
f(11) => 21
f(21) => 1211
f(1211) => 111221
.
.
.
n times

each time we are passing a number into the function we are just counting the number of same digits in a sequence and replacing the digit with the count and the digit

eg 33333 -> there are 5 threes so we return 53(count + digit)

Approach:
we use a stack to count the digits.
if the stack is empty we push to the stack
if the current digit is same as the digit on the top of the stack then we push to the stach.
if the current digit is not the same then we get the length of the stack and the digit in top of the stack return the len + digit as a string, empty the stack and push the current element to the top of the stack

we do this n times. each time the output of the function will be the input to the next iteration.

C++




// C++ code to implement the above approach
#include <bits/stdc++.h>
 
using namespace std;
 
// Function to generate the nth row of the look-and-say
// pattern
 
string countAndSay(int n)
{
    if (n == 1)
        return "1";
 
    std::string ret{ "" };
    std::string strToCount{ countAndSay(
        n - 1) }; // we need to count and say the n-1th term
    std::stack<char> stack;
 
    for (int i{ 0 }; i <= strToCount.length(); ++i) {
        // if we're at the end OR we find a num that's
        // different... we add the length of the stack to ret
        // and also the num we've been counting then, we
        // empty the stack to count the next number
        if (i == strToCount.length()
            || !stack.empty()
                   && stack.top() != strToCount[i]) {
            std::stringstream ss;
            std::string toAdd{ "" };
            ss << stack.size();
            ss >> toAdd;
            ret += toAdd;
            ret += stack.top();
            while (!stack.empty())
                stack.pop();
        }
        if (i != strToCount.length())
            stack.push(strToCount[i]);
    }
    return ret;
}
 
int main()
{
    int n = 3;
    cout << countAndSay(n) << endl;
    return 0;
}


Java




/*package whatever //do not write package name here */
 
import java.io.*;
 
import java.util.Stack;
 
public class GFG{
    public static String countAndSay(int n) {
        if (n == 1)
            return "1";
 
        String strToCount = countAndSay(n - 1);
        StringBuilder ret = new StringBuilder();
        Stack<Character> stack = new Stack<>();
 
        for (int i = 0; i <= strToCount.length(); ++i) {
            if (i == strToCount.length() || (!stack.empty() && stack.peek() != strToCount.charAt(i))) {
                ret.append(stack.size()).append(stack.peek());
                stack.clear();
            }
            if (i != strToCount.length())
                stack.push(strToCount.charAt(i));
        }
        return ret.toString();
    }
 
    public static void main(String[] args) {
        int n = 3;
        System.out.println(countAndSay(n));
    }
}


Python3




# Function to generate the nth row of the look-and-say pattern
def count_and_say(n):
    if n == 1:
        return "1"
 
    ret = ""
    # we need to count and say the n-1th term
    str_to_count = count_and_say(n - 1)
    stack = []
 
    for i in range(len(str_to_count) + 1):
        # if we're at the end OR we find a num that's different... we add the length of the stack to ret
        # and also the num we've been counting then, we empty the stack to count the next number
        if i == len(str_to_count) or (stack and stack[-1] != str_to_count[i]):
            to_add = str(len(stack)) + stack[-1]
            ret += to_add
            stack.clear()
 
        if i != len(str_to_count):
            stack.append(str_to_count[i])
 
    return ret
 
 
def main():
    n = 3
    print(count_and_say(n))
 
 
if __name__ == "__main__":
    main()
 
 
# This code is contributed by shivamgupta310570


C#




// C# code to implement the above approach
using System;
using System.Collections.Generic;
 
namespace CountAndSay
{
    class Program
    {
        // Function to generate the nth term of the "count and say" sequence
        static string CountAndSay(int n)
        {
            // Base case: return "1" for n = 1
            if (n == 1)
                return "1";
 
            // String to store the current term being generated
            string ret = "";
 
            // Recursively calculate the (n-1)th term
            string strToCount = CountAndSay(n - 1);
 
            // Stack to count consecutive occurrences of the same digit
            Stack<char> stack = new Stack<char>();
 
            // Loop through the characters of the (n-1)th term
            for (int i = 0; i <= strToCount.Length; ++i)
            {
                // If we're at the end of the string or the stack is not empty and the current character is different from the top of the stack
                if (i == strToCount.Length || (stack.Count > 0 && stack.Peek() != strToCount[i]))
                {
                    // Add the count and digit value to the result
                    ret += stack.Count.ToString() + stack.Peek();
 
                    // Clear the stack to count the next number
                    stack.Clear();
                }
 
                // If we're not at the end of the string, push the current character onto the stack
                if (i != strToCount.Length)
                    stack.Push(strToCount[i]);
            }
 
            // Return the nth term of the "count and say" sequence
            return ret;
        }
 
        static void Main(string[] args)
        {
            int n = 3;
             
            // Generate and print the 3rd term of the "count and say" sequence
            Console.WriteLine(CountAndSay(n));
        }
    }
}


Javascript




function countAndSay(n) {
    if (n === 1)
        return "1";
 
    let strToCount = countAndSay(n - 1);
    let ret = "";
    let stack = [];
 
    for (let i = 0; i <= strToCount.length; ++i) {
        if (i === strToCount.length || (stack.length !== 0 && stack[stack.length - 1] !== strToCount[i])) {
            ret += stack.length + stack[stack.length - 1];
            stack = [];
        }
        if (i !== strToCount.length)
            stack.push(strToCount[i]);
    }
    return ret;
}
 
let n = 3;
console.log(countAndSay(n));


Output

21






Time complexity: O(kn),since we are calling the function n times and for k length of the string
Auxiliary Space: O(kn),stack space needed.

Feeling lost in the world of random DSA topics, wasting time without progress? It’s time for a change! Join our DSA course, where we’ll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!

RELATED ARTICLES

Most Popular

Recent Comments