Special String Again

  • + 63 comments

    Really simple 3 pass solution: 1. Build a list of tuples such that the string "aaabbc" can be squashed down to [("a", 3), ("b", 2), ("c", 1)]. 2. add to answer all combinations of substrings from these tuples which would represent palindromes which have all same letters. 3. traverse this list to specifically find the second case mentioned in probelm

    Here is my code:

    def substrCount(n, s):
        l = []
        count = 0
        cur = None
    
    # 1st pass
        for i in range(n):
            if s[i] == cur:
                count += 1
            else:
                if cur is not None:
                    l.append((cur, count))
                cur = s[i]
                count = 1
        l.append((cur, count))
    
        ans = 0
    		
    # 2nd pass
        for i in l:
            ans += (i[1] * (i[1] + 1)) // 2
    
    # 3rd pass
        for i in range(1, len(l) - 1):
            if l[i - 1][0] == l[i + 1][0] and l[i][1] == 1:
                ans += min(l[i - 1][1], l[i + 1][1])
    
        return ans
    
    • + 12 comments

      Implemented your logic in Java. Had to tweak the code to optimise it and also reduced it to 2 passes

      static class Point {
          public char key;
          public long count;
      
          public Point(char x, long y) {
              key = x;
              count = y;
          }
      }
      
      // Complete the substrCount function below.
      static long substrCount(int n, String s) {
          s = s + " ";
          ArrayList<Point> l = new ArrayList<Point>();
          long count = 1;
          char ch = s.charAt(0);
          for(int i = 1; i <= n ; i++) {
              if(ch == s.charAt(i))
                  count++;
              else {
                  l.add(new Point(ch, count));
                  count = 1;
                  ch = s.charAt(i);
              }
          }
          count = 0;
          if(l.size() >= 3) {   
              Iterator<Point> itr = l.iterator();
              Point prev, curr, next;
              curr = (Point)itr.next();
              next = (Point)itr.next();
              count = (curr.count * (curr.count + 1)) / 2;
              for(int i = 1; i < l.size() - 1; i++) {
                  prev = curr;
                  curr = next;
                  next = itr.next();
                  count += (curr.count * (curr.count + 1)) / 2;
                  if(prev.key == next.key && curr.count == 1)
                      count += prev.count > next.count ? next.count : prev.count;
              }
              count += (next.count * (next.count + 1)) / 2;
          } else {
              for(Point curr:l){
                  count += (curr.count * (curr.count + 1)) / 2;
              }
          }
          return count;
      }
      
      • + 4 comments

        Can you please explain the logic/algo in words?

        • + 0 comments

          here is problem solution in python java and c++ programming. https://programs.programmingoneonone.com/2021/03/hackerrank-special-string-again-solution.html

        • + 0 comments

          My full python implementation and logic is explained in detail.

          Hackerrank - Special String Again Solution

        • + 5 comments

          The trick to solve this problem is to find all substring for each of the two cases.

          Case 1: All characters are same.

          For a string with n characters, we can make a total of n*(n+1)/2 substrings. Note substrings keep the same order and don't skip characters. For instance, aaaa will make a, aa, aa, aa, aaa, aaa and aaaa This is because, for a string of size n we can make n - 1 substrings of size 2 and n - 2 substrings of size 3 and so on. This can be generalized as n-(k-1) where k is the length of the substring. So total number of substrings (of all lenghts) is then n-1 + n-2 + ... + n - (k-1) + ... + n - (n-1). This when written in reverse is same as 1 + 2 + ... + n-2 + n-1 + n. The sum of an arithmetic sequence is = n*(first+last)/2. Therefore, the sum of above sequence is n*(1+n)/2

          Case 2: Odd length string with all characters same except the middle one

          For a string like aaabaaa, the total number of special substrings is equal to the number of repeated characters. For the example above it will be, aba, aabaa, aaabaaa. So when we find a character, c, such that its previous character, pc, is same as its next character, nc, i.e. pc == nc but not same as itself, i.e. pc != c, we can count the number of times that pc and nc are repeated. Note that, number of times pc is repated may be different than the number of times nc is repated, for instance aaabaa. We take the minimum of the repeated times. To add effeciency, we can create an array that stores the number of times a character is repated at every index. For example, for a string like aaabaa the array will contain 333122

          • + 0 comments

            really apperciated, you gave answer to a question asked 2 yrs ago.. it is helpfull for future viewers.

          • + 1 comment

            thanks :) here's the code in c++:

            long substrCount(int n, string s) {
            
            vector<pair<char, int> >v;
            long sst;
            char curr = '\0';
            int ind =-1;
            
            for(int i=0; i<n; i++){
                    if(s[i]==curr)
                            v[ind].second +=1;
            
                    else{
                            curr = s[i];
                            ind++;
                            v.push_back({curr,1});
                    }
            }
            
            sst+= v[0].second* (v[0].second+1)/2;
            
            for(int i=1; i<v.size(); i++){
                    sst += v[i].second * (v[i].second+1)/2;
                    if(v[i-1].first == v[i+1].first and v[i].second==1)
                            sst+= min(v[i-1].second, v[i+1].second);
            }
            
            return sst;
            }
            
            • + 0 comments

              kya baat bhaiya mst mtlb gjb explanation .

          • + 0 comments

            Thank you! I was looking for this explanation.

          • + 0 comments

            Thanks mahak_vmukhi ! I can finally understand everything clearly!

          • + 0 comments

            Thank you, Really appriceated.

        • + 0 comments
          static long substrCount(int n, String s) {
              long count=n;
              for(int i=0; i<n-1; i++){
                  int en=0;
                  int limit=n;
                  boolean flag=true;
                  boolean suc=true;
                  for(int j=i+1; j<limit; j++){
                      if(en==2){
                          break;
                      } else if(flag&&en==1){
                          limit=2*j-i-1;
                          if(limit > n){
                              break;
                          }
                          flag=false;
                      }
                      if(s.charAt(i)==s.charAt(j)){
                          if(suc){
                              count++;
                          } else if(j==limit-1){
                              count++;
                          }
                      } else {
                          en++;
                          suc=false;
                      }
                  }
              }
              return count;
          }
          
      • + 6 comments

        It is possible to solve with one loop. :)

        long substrCount(int n, string s) {
            size_t result = 0;
            char ch = '0';
            char oldCh = '0';
            size_t counter = 0;
            size_t oldCounter = 0;
            size_t leftCounter = 0;
            bool special = false;
            for_each(s.begin(), s.end(),
                     [&result, &ch, &oldCh, &counter, &oldCounter, &leftCounter, &special](char& val) {
                if (val == ch) ++counter;
                else
                {
                    if (special)
                        result += counter < leftCounter ? counter : leftCounter;
                    special = counter == 1 && val == oldCh;
                    if (special)
                        leftCounter = oldCounter;
                    result += counter * (counter + 1) / 2;
                    oldCh = ch;
                    ch = val;
                    oldCounter = counter;
                    counter = 1;
                }
            });
            if (special)
                result += counter < leftCounter ? counter : leftCounter;
            result += counter * (counter + 1) / 2;
            return result;
        }
        
        • + 0 comments

          Sweet! I also wanted to solve it with a single pass and no extra structures. I struggled much more than I was hoping for... here for the curious.

        • [deleted]
          + 1 comment

          All I learned here is that I don't know how to read C++ lol

          • + 1 comment

            I'm In the same boat too lol

            • + 0 comments

              O(n) time complexity and O(1) space complexity

              def substrCount(n, s):
                  green=False
                  score=ans=0
                  add=1
                  track=float('-inf')
                  for i in range(1,n):
                      trackconstant=track-(i-track)
                      if s[i]!=s[i-1]:
                          if add>1:
                              ans+=(add-length)
                              add=1
                              score=0
                          track=i-1
                          if trackconstant>=0 and s[i]==s[trackconstant]:
                              ans+=1
                              green=True
                          else:
                              green=False
                      else:
                          length=score+2
                          add=((length)**2)-add
                          score+=1
                          if trackconstant>=0 and s[i]==s[trackconstant]:
                              if green:
                                  ans+=1
                          else:
                              green=False
                  if s[i]==s[i-1] and i==(n-1):
                      ans+=(add-length)
                  return ans+n
              
        • + 5 comments

          Python3 - one loop counting sequences and branch out for xx.xx patterns:

          def substrCount(n, s):
              tot = 0
              count_sequence = 0
              prev = ''
              for i,v in enumerate(s):
                  # first increase counter for all seperate characters
                  count_sequence += 1
                  if i and (prev != v):
                      # if this is not the first char in the string 
                      # and it is not same as previous char, 
                      # we should check for sequence x.x, xx.xx, xxx.xxx etc
                      # and we know it cant be longer on the right side than
                      # the sequence we already found on the left side.
                      j = 1
                      while ((i-j) >= 0) and ((i+j) < len(s)) and j <= count_sequence:
                          # make sure the chars to the right and left are equal
                          # to the char in the previous found squence
                          if s[i-j] == prev == s[i+j]:
                              # if so increase total score and step one step further out
                              tot += 1
                              j += 1
                          else:
                              # no need to loop any further if this loop did 
                              # not find an x.x  pattern
                              break
                      #if the current char is different from previous, reset counter to 1
                      count_sequence = 1  
                  tot += count_sequence            
                  prev = v
            return tot	
          
          • + 0 comments

            liked your approach.

          • + 0 comments

            Thanks mate, this is very clear and concise

        • + 0 comments

          It would be very helpful. If you could provide the explanation of your code, or what is the approach.!

        • + 2 comments

          Now I am waiting for the solution without using any loop :p

          • + 0 comments

            That would be possible with regex, if that would allow to match a matched substring :D

          • + 0 comments

            :D:D:D

      • + 0 comments

        this looks a lot like my code - also using 2 passes only and also declared a inner class to store the string in a different format

      • + 4 comments

        One more Java solution :)

        static long substrCount(int n, String s) {
            long count = 0;
            for (int i = 0; i < s.length(); i++) {
                int innerCounter = 1;
        
                int counterDown = 0;
                int counterUp = 1;
                while (i - innerCounter >= 0 && i + innerCounter < s.length()
                        && s.charAt(i - innerCounter) == s.charAt(i - 1) && s.charAt(i + innerCounter) == s.charAt(i - 1)) {
                    count++;
                    innerCounter++;
                }
        
                while (i - counterDown >= 0 && i + counterUp < s.length() && s.charAt(i - counterDown) == s.charAt(i)
                        && s.charAt(i + counterUp) == s.charAt(i)) {
                    count++;
                    counterDown++;
                    counterUp++;
                }
            }
        
            return count + s.length();
        }
        
        • + 4 comments

          Tried to simplify the code above and optimize a little bit by avoiding iterating over the repeatable symbols and jumping straight to the distinct by incrementing for loop counter and replacing sum with n*(n+1)/2

          public static long substrCount(int length, String s) {
          	long counter = 0;
          	for (int i = 0; i < length; i++) {
          		// if the current symbol is in the middle of palindrome, e.g. aba
          		int offset = 1;
          		while (i - offset >= 0 && i + offset < length && s.charAt(i - offset) == s.charAt(i - 1)
          				&& s.charAt(i + offset) == s.charAt(i - 1)) {
          			counter++;
          			offset++;
          		}
          		// if this is repeatable characters aa
          		int repeats = 0;
          		while (i + 1 < length && s.charAt(i) == s.charAt(i + 1)) {
          			repeats++;
          			i++;
          		}
          		counter += repeats * (repeats + 1) / 2;
          	}
          	return counter + length;
          }
          
          • + 0 comments

            Crazy thinking... Good one bro

          • + 0 comments

            beauty

          • + 0 comments

            Super-cool! I used it (together with some luck that allowed me to find more small and meaningful test cases) to debug a similar idea I had, only that it works strictly forward rather than expanding from the middle:

                static long substrCount(final int n, final String s) {
                    long specials = n;
            
                    int i = 0, j = 1;
                    while (j < n) {
                        if (s.charAt(i) != s.charAt(j)) { // Different char and maybe middle char of special substring
                            final int repeatedCharStringLen = j - i;
            
                            // All len 2+ substrings of same-char string with fixed start are special
                            specials += repeatedCharStringLen - 1;
            
                            // If there is a mirrored same-char substring after the different char, then special
                            final int newStringAfterSpecialIdx = j + 1 + repeatedCharStringLen;
                            if (j + 1 < n &&
                                newStringAfterSpecialIdx <= n &&
                                s.substring(i, j).equals(s.substring(j + 1, newStringAfterSpecialIdx))) {
            
                                specials++;
                            }
            
                            // Advance
                            i++;
                            j = i;
                        }
            
                        // Expand substring to the right
                        j++;
                    }
            
                    specials += substringsInLen(j - i) - (j - i); // All len 2+ substrings
            
                    return specials;
                }
            
                private static long substringsInLen(final int len) {
                    if (len <= 0)
                        return 0;
            
                    return len * (len + 1) / 2;
                }
            
          • + 4 comments

            Just as a question,

            len * (len +1) / 2

            Where is this formula from?

            • + 0 comments

              Mount the sequence and you will have a better idea:

              2 chars: 2 + 1 = 3

              3 chars: 3 + 2 + 1 = 6

              4 chars: 4 + 3 + 2 + 1 = 10

              Notice? The val of 2 chars is ( 2 + 1 ) * 2 / 2

            • + 0 comments

              Total number of substring that can be produced out of string of length n is n*(n+1)/2.

            • + 0 comments

              it's the triangle numbers!

            • + 0 comments

              It comes from calculate the number of substring in the string. I saw it using an old technique, imagine that "0" are characters and "1" are separators between chars. Then a string can be represented as a binary chain "101010101...1". And a substring is then any subchain which start in "1" and ends in another different "1", being the chars between "1" the substring. Then, is just calculate how many differents ways there are to take two differents "1" in this repr, due two differents "1" always define a substring. If there are n "0" then there are n+1 "1" and to take two "1" in n + 1 possibles is equal to combinations(n + 1, 2) = n+ 1!/(n+1 - 2)!* 2, wich is equals to (n+1) * n / 2.

        • + 0 comments

          very good man ,impressed

        • + 0 comments

          Brilliant man!!

        • + 0 comments

          Thank you Your code helped me and it is easy to understand.

      • + 0 comments

        here is my java solution

          long count = 0; 
          int i = 0;
          while(i<s.length()) {
             char c = s.charAt(i);
             int l = 0; 
             int r = 0; 
             while(i<s.length() &&s.charAt(i)==c) {
                l++;
                i++; 
             } 
          if(i+1<s.length()&&s.charAt(i+1)==c) {
              int index = i;
              int index2 = i+1;
              i++;
              while(i<s.length() && s.charAt(i)==c) {
                r++;
                i++; 
             } 
             if(i<s.length()&&r==1&&s.charAt(i)==s.charAt(index)) {
                count += Math.min(l,r)+1;
             }
             else {
                 count += Math.min(l,r); 
             }
             if(i+1<s.length()&&s.charAt(index2)==s.charAt(i+1)) {
                 i = index2; 
             }    
          }             
        }
        for(int j=0; j<s.length(); j++) {
          char c = s.charAt(j);
          long same = 0; 
          while(j<s.length()&&s.charAt(j)==c) {
             same++;
             j++;
          }
             j--;
             count += same*(same+1)/2;   
        }  
        return count; 
        
      • + 0 comments

        This is an absolutely brilliant approach

      • + 0 comments

        This is what I came up with. It works for the cases given in the description. But not for the submit cases. Do you have any idea as to why it doesn't work for other cases

        static long substrCount(int n, String s) {
        
            char chAr[] = s.toCharArray();
        
        long res = 1l;
        int m = 1;
        for (int i = 0; i < n - 1; i++) {
        
          if (chAr[i] == chAr[i + 1]) {
            m++;
            res += m;
          } else {
            m = n - 2 - i >= m ? m : n - i - 2;
            for (int j = 0; j < m; j++) {
              if (chAr[i - j] == chAr[i + j + 2]) {
                res++;
              }
            }
            m = 1;
            res += 1;
          }
        }
        
        return res;
        

        }

      • + 0 comments

        Here is my C# version:

        class Segment {
            public char Key { get; set; }
            public long Count { get; set; }
        }
        
        // Complete the SubstrCount function below.
        static long SubstrCount(int n, string s) {        
            var count = 0L;
            List<Segment> segments = ToSegments(s);
        
            for (var i = 0; i < segments.Count; i++)
                count += GetCount(segments, i);
        
            return count;
        }
        
        private static List<Segment> ToSegments(string s) {
            List<Segment> segments = new List<Segment>();
            var str = s + " ";
            var count = 1L;
            var ch = str[0];
            for (int i = 1; i <= s.Length ; i++) {
                if(str[i].Equals(ch)) {
                    count++;
                } else {
                    segments.Add(new Segment { Key = ch, Count = count });
                    count = 1;
                    ch = str[i];
                }
            }
            return segments;
        }
        
        private static long GetCount(List<Segment> segments, int i) {
            return IsMid(segments, i)
                ? Math.Min(segments[i - 1].Count, segments[i + 1].Count) + 1
                : SegmentToCount(segments[i]);
        }
        
        private static bool IsMid(List<Segment> segments, int i) {
            return i > 0 
                && i < segments.Count - 1
                && segments[i].Count == 1 
                && segments[i - 1].Key == segments[i + 1].Key;
        }
        
        private static long SegmentToCount(Segment s) {
            return (s.Count * (s.Count + 1)) / 2;
        }
        
      • + 0 comments

        Here is another solution in C# without using additional list:

        // Complete the SubstrCount function below.
        static long SubstrCount(int n, string s) {
            var count = 0L;
            for (var x = 0; x < n; x++) {
                var firstDiff = FindFirstDifferent(s, x, s[x]);
                if (firstDiff > -1) {
                    if (IsMidPointer(s, x)) {
                        count +=  GetMidCount(s, x) + 1;
                    } else {
                        count +=  firstDiff - x;
                    }                             
                } else {
                    count += n - x;
                }                
            }
            return count;
        
        }
        
        private static int FindFirstDifferent(string s, int start, char thisChar) {
            var firstDiff = -1;
            for (var x = start; x < s.Length; x++) {
                if (!s[x].Equals(thisChar)) {
                    firstDiff = x;
                    x = s.Length;
                }
            }
            return firstDiff;
        }
        
        private static bool IsMidPointer(string s, int index) {
            return index > 0
                && index < s.Length - 1
                && !s[index + 1].Equals(s[index])
                &&  s[index + 1].Equals(s[index - 1]);
        }
        
        private static long GetMidCount(string s, int index) {
            var midCount = 0L;
            var offset = 1;
            char next = s[index + 1];
            while (index - offset >= 0
                    && index + offset < s.Length
                    && s[index + offset].Equals(next)
                    && s[index - offset].Equals(next)) {
                    midCount++;
                    offset++;
                }
        
            return midCount;
        }
        
      • + 0 comments

        class point{ public: char key; long count; point(char key,long count){ this->key = key; this->count = count; } };

        int main() { std::vector _v; long count = 1; int n; scanf("%d",&n); char str[n]; std::cin >> str; char ch = str[0];

        for(int i = 1; i <= n; i++) {
            if (ch == str[i])
                count += 1;
            else
            {
                _v.push_back(point(ch,count));
                count = 1;
                ch = str[i];
            }
        }
        count = 0;
        for(auto p : _v)
            count += (p.count * (p.count + 1)) / 2;
        
        for(int i = 1; i < _v.size() - 1; i++) {
            if (_v[i - 1].key == _v[i + 1].key && _v[i].count == 1)
                count += std::min(_v[i - 1].count,_v[i + 1].count);
        }
        
        
        printf("%ld\n",count);
        return 0;
        

        }

    • + 1 comment

      can youb explain me 3rd pass

      • + 1 comment

        Checks if it forms a palindrome. The condition for that is the current element should have count 1, and we take the least of the counts on either side of the current element if they are equal. Eg., aaabaa b is the current element and we take the palindrome (aabaa)

    • + 0 comments

      Smart solution. Thank you!

    • + 1 comment

      i didn't understand here, for i in range(1, len(l) - 1): f l[i - 1][0] == l[i + 1][0] and l[i][1] == 1: ans += min(l[i - 1][1], l[i + 1][1]) please explain me..!!

      • + 1 comment

        This is the 3rd pass, it tries to find a letter cluster with length 1, and its left letter cluster and right letter cluster are the same letter. For example bbbabb. 'a' it the letter cluster with length 1, and its left letter cluster "bbb" and its right letter cluster "bb" have the same letter 'b'. And number of the palindrome is limited by the min length of those two side letter cluster. For example, it has "bab", "bbabb", two palindrome, equals to the length of right letter cluster. I am sorry for my English. Hope you can understand.

        • + 2 comments

          How this logic will work to count 'cbbabbc' ? Since it's checking only i-1, i and i+1 it will count 'bbabb' correctly but how about 'cbbabbc' palindrome string ?

          Can you please explain ?

          • + 0 comments

            Because this is special palindrome string, case 2: All characters except the middle one are the same, e.g. aadaa. So there is no need to consider i-2 and i+2. two neibors should be same.

    • + 2 comments

      Why this approach return 11 for input 'cbbabbc' as an example ?

      Correct answer should be 12 in this case. (c, b, b, a, b, b, c, bb, bb, bab, bbabb, cbbabbc)

      I think there is a bug in 3rd testCase as its only checking i-1, i and i+1.

      There should be a recursive way to keep check n-1 and n+1 terms until they are matching or something like that, then start taking min of each of those.

      • + 1 comment

        "cbbabbc" is a palindrome, but the question is asking for special palindromes, which are palindromes that consist of only one letter (e.g., "bbbb", "aa", "ccccc") or palindromes that consist of only one letter and are separated by a single letter (e.g., "bbbabbb", "cac").

        Since "cbbabbc" contains two different letters on either side of the dividing letter, it's not counted

        • + 1 comment

          Is there any way to do it using regex?

          • + 5 comments

            Yes, in some way.

            I used two regular expressions, this is my python 3 code:

            count = len(s)
            
            exp1 = r'(([a-z])\2*)(?!\1)(?=[a-z]\1)'
            m = re.finditer(exp1,s)
            count += sum([len(x.group(0)) for x in m])
            
            exp2 = r'([a-z])\1+'
            m = re.finditer(exp2,s)
            count += sum([triangular_number(len(x.group(0))-1) for x in m])
            
            return count
            

            I used triangular number to sum all repeated words:

            def triangular_number(n):
                  return (pow(n,2)+n)//2
            

            triangular number function t1=1, t2=3, t3=6, t4=10, t5=15

            that is if you sum (len -1) of repeated words sequence, you'll have all combinations. eg. aaaa: (3²)+3//2 = 6

            • + 1 comment

              This works! I wish I understood the triangular number part

              • + 0 comments

                The triangular number sequence is simple:

                (sequence number) -> (value)

                t0 -> 0

                t1 -> 1

                t2 -> 3

                t3 -> 6

                t4 -> 10

                ...

                The result of next value is the sum of previous sequence number (t+1) plus previous value.

                There are many applications using this sequence. You can see more about here: https://en.wikipedia.org/wiki/Triangular_number

                In this problem it's possible to find the number of repeated char combinations throught triangular number sequence. Here an example:

                t0 -> a -> 0

                t1 -> aa -> 1

                t2 -> aaa -> 3

                t3 -> aaaa -> 6

                t4 -> aaaaa -> 10

                ...

                It's the same sequence, but you'll need to use len()-1.

            • + 0 comments

              So far, the best solution that I found it.

            • + 1 comment

              Hello, can you explain your logic without using regular expessions? How can I do this problem just using the triangle number?

              thx in advance

              • + 0 comments

                Hi. I'm not sure if is possible to solve the problem using triangular number only. Triangular number is just an especific sequence and in this solution, triangular number is part of the solution. I'll try explain the solution step by step :

                1) len(s) -> count all char of the word;

                2) exp1 -> count all words that follow this rule: a_a also aaaa_aaaa;

                3) exp2 -> count all repeated char of the word and with triangular number all combinations of these repeated chars. Example of this step is: aaaa has the combination of:

                'aa'+'aa'+'aa'

                +'aaa'+'aaa'

                +'aaaa' = 6 (realize 6 is the same T3 of triangular number sequence).

                The final answer is the sum of all these steps.

            • + 1 comment

              I don't understand exp1. I mean why do you need to put group #3 (?!\1) ? can you please explain?

              • + 0 comments

                I little late but ... I'll try to explain. As I said before, exp1 -> count all words that follow this rule: a_a also aaaa_aaaa; So, in this case the middle word needs to be different from match group 1, that's why this negative lookahead (?!\1) is required.

            • + 0 comments

              Could you please explain step by step why (([a-z])\2*)(?!\1)(?=[a-z]\1) could find out the pattern aa_aa, aaa_aaa and so forth?

      • + 0 comments

        there are three different character in your last substring which is not allowed.

    • + 1 comment

      May I know why this works?

      (i[1] * (i[1] + 1)) // 2

      • + 0 comments

        Yeah this doesn't make sense to me. Wouldn't this result in 12 for the tuple ['a', 3]?

        EDIT: Oh I see. The // 2 showed up as a comment in the code, and I forgot this was Python.

    • + 0 comments

      wow how did you think of that 0.o

    • + 0 comments

      No Need for the // in ans += (i[1] * (i[1] + 1)) // 2 as i[1] will always be greater than 1 and hence i[1]+1 will be even when i[1] is odd and vice-versa. So this formula yeilds only integer results.

    • + 0 comments

      very nice!

    • + 5 comments

      Thanks for the logic and style, I'm sure many have learned from it! Following the same logic described, I have the same solution written in C++ for anyone who wanted to see it in the language

      Here it is:

      long substrCount(int n, string s) {

      long count = 0;
      vector<std::pair<char, int>> frequencies;
      int i=0, j=0;
      
      for ( i = 0; i < n; i++)
      {
          for( j = i+1; j < n; j++)
          {
              if (s[j] == s[i])
                  continue;
              else
                  break;
          }
          frequencies.push_back(std::make_pair(s[i],j-i));
          i = j-1;
      }
      
      for (i=0; i < frequencies.size(); i++)
          count += (frequencies[i].second+1) * frequencies[i].second / 2;
      
      for (i=1; i < frequencies.size()-1; i++)
      {
          if ( frequencies[i].second == 1 && frequencies[i-1].first == frequencies[i+1].first)
              count += min(frequencies[i-1].second, frequencies[i+1].second);
      }
      
      return count;
      

      }

      • + 0 comments

        After this, my code passed all tests. I really like the logic. The for inside for actually could be done with just one for loop. Here is my relevant JAVA solution. It passed all the tests.

        static class Point{ char text; long counter;

            Point(char t, long c){
                text = t;
                counter = c;
            }
        }
        // Complete the substrCount function below.
        static long substrCount(int n, String s) {
            long palindromeCount = 0L;
            long equalCounter = 1L;
            List<Point> countList = new ArrayList<Point>();
        
            for(int i=1; i<s.length();i++){
                if(s.charAt(i)==s.charAt(i-1)){
                    equalCounter++;
                }
                else{
                    countList.add(new Point(s.charAt(i-1),equalCounter));
                    equalCounter = 1L;
                }
            }
            countList.add(new Point(s.charAt(s.length()-1), equalCounter));
        
            for(int i=0; i<countList.size(); i++){
                palindromeCount += (countList.get(i).counter+1)*countList.get(i).counter/2;
            }
            for (int i = 1; i < countList.size()-1; i++) {
                if(countList.get(i).counter == 1
                && countList.get(i-1).text == countList.get(i+1).text){
                    palindromeCount += Math.min(countList.get(i-1).counter,countList.get(i+1).counter);
                }
            }
        
            return palindromeCount;
        }
        
      • + 0 comments

        Thank you

      • + 0 comments

        please explain or tell about your concept

      • + 0 comments

        how on earth did you came up with this solution? can someone be trained on being able to find such logics? do you have an advice? because i would have never found the solution you made yet i want to be this good at finding solutions like this.

    • + 0 comments

      Nice solution! One thing that condenses the code a bit is using itertools.groupby to turn the logic of the first loop into a 1 liner:

      l = [(ch, len(list(g))) for ch, g in groupby(s)]
      
    • + 0 comments

      Thanks!

    • + 1 comment

      For those who doesn't understand this line,

      for i in l: ans += (i[1] * (i[1] + 1)) / 2

      its from a formula n(n+1)/2 which give the sum of all term, like n = 5, 1+2+3+4+5 = 5(5+1)/2 = 15.

      Its used because if you have "aaaa" , you can have "a,a,a,a", "aa,aa,aa", "aaa,aaa" and "aaaa", we can see the partern of 4,3,2,1 groups, so in this case there's 15 groups!

      • + 0 comments

        thank you!

    • + 0 comments

      excellent solution - there is a detailed explanation on this page if anyone else is interested

    • + 1 comment

      Wow nice solution. I didn't understand the intuition behind this line: ans += (i[1] * (i[1] + 1)) i.e if all chars are same. Can anyone comment on that ?

      • + 1 comment

        i think it's looking to count all possible sub-strings of a string. so if the string length is n, the number of sub-strings will be (n*(n+1))/2. you can see the 2 commented out in the solution - not sure why

        • + 0 comments

          it's floor division and not a acomment

    • + 0 comments

      Appears that RLE (run length encoding) compression is the consensus; I did so too. My implementation ran through the list twice instead - just makes the code all the more clear.

    • + 0 comments

      Nice solution, thanks!!

    • + 0 comments

      I feel this is a very complicated answer. You can solve this problem in 10 lines, using the same logic as you would manually do when you solve it by hand : For each index i in the string, I create a cursor k that starts from i and goes forward until it meets a different letter than s[i] at s[i+k]. Then I check if the string starting from s[i] centrered on s[i+k] could be a palindrome.

      I put my code in this discussion

    • + 0 comments

      I can't quite figure out the formula in the 2nd pass

      ans += (i[1] * (i[1] + 1)) // 2
      

      How is this derived? Emprically I understand that it is correct. But I can't quite understand why.

    • + 0 comments
          static int palindromHalfLength(int i, String s) {
              int step = 1;
              char palChar = s.charAt(i-1);
              while (i-step>=0 && i+step<s.length()
                      && s.charAt(i-step) == palChar
                      && s.charAt(i+step) == palChar) step++;
      
              return step-1;
          }
          // Complete the substrCount function below.
          static long substrCount(int n, String s) {
              if (s.length() == 0) return 0;
              long res = 1;
              int countSimChar = 1;
              for (int i = 1; i < s.length(); i++) {
                  if (s.charAt(i-1) == s.charAt(i)) {
                      countSimChar++;
                  }  else {
                      res += palindromHalfLength(i, s);
                      countSimChar = 1;
                  }
                  res += countSimChar;
              }
              return res;
          }
      

      If there are k similar characters in a raw, number of palindroms will be 1+2+..+k; If current character differs from the prvious one it might also be a palindrom, and half length of the palindrom would be the number of palindroms: aaacaaa -> half length is 3 and there are 3 palindroms: aca, aacaa, aaacaaa

    • + 0 comments

      Simplified way of writing 1st pass, no count, cur required:

      for i in range(n):
      	if not l or s[i] != s[i-1]:
      		l.append((s[i],1))
      		continue
      	l[-1] = (s[i],(l[-1][1] + 1))
      
    • + 0 comments

      C# Code:

      I passed 3 test cases but when I click on submit it doesn't pass any other. I can't even debug as the data is very large and I can only feed 40kb in the input field. Please help me!

      Thanks.

      long count = 0;
              string tempStr;
              for(int i = 0; i < n - 1; i++){
                  for(int j = 2; j <= n - i; j++){
                      tempStr = s.Substring(i,j);
                      int flag = 0;
                      int testStr = tempStr[0];
                      int x = 0;
                      int y = tempStr.Length - 1;
                      Console.WriteLine(tempStr);
                      while(x < y){
                          if(tempStr[x] == testStr && tempStr[y] == testStr){
                              Console.WriteLine(tempStr[x] + " " + tempStr[y]);
                              x++;
                              y--;
                          }
                          else{
                              flag = 1;
                              break;
                          }
                      }
                      Console.WriteLine(flag);
                      if(flag == 0)
                          count++;
                  }
              }
      
              return count + n;
      
    • + 0 comments

      Nice solution :)

    • + 0 comments

      Similar solution by using groupby() function:

       def substrCount(n, s):
                       import itertools as it
                      if n == 1:
                              return 1      
                      s = [list(g) for k, g in it.groupby(s)]
                      res = sum([int(len(i)*(len(i)+1)/2) for i in s])
      
                      for i in range(len(s)):
                              if i == 0 or i == len(s)-1 or len(s[i]) > 1 :
                                      continue
      
                              if s[i-1][0] == s[i+1][0]:
                                      res+= min(len(s[i-1]), len(s[i+1]))
                      return res
      
    • + 0 comments

      Here's a rendition that made a bit more sense to me. The second pass uses the "nth triangle number" https://math.stackexchange.com/questions/593318/factorial-but-with-addition

      def substrCount(n, s):
      
              counts = []
      
              for i in range(len(s)):
                      if counts == []:
                              counts.append([s[i], 1])
                      elif s[i] == counts[-1][0]:
                              counts[-1][1] = counts[-1][1] + 1
                      else:
                              counts.append([s[i], 1])
      
              ans = 0
              for pair in counts:
                      ans += pair[1] * (pair[1] + 1) / 2
      
              for i in range(len(counts) - 2):
                      if counts[i + 1][1] == 1 and counts[i][0] == counts[i + 2][0]:
                              m = min(counts[i][1], counts[i + 2][1])
                              ans += m
      
              return int(ans)
      
    • + 0 comments

      Here's my implementation your logic with 2 passes:

      def substrCount(n, s):
          
          prevChar = s[0]
          count = 1
          allChars = []
          res = 0 
      
          for c in s[1:]:
              if (c == prevChar):
                  count += 1
              else:
                  allChars.append((prevChar, count))
                  res += ((count) * (count + 1)) // 2
                  count = 1
                  prevChar = c
          
          allChars.append((prevChar, count))
          res += ((count) * (count + 1)) // 2
      
          for i, val in enumerate(allChars[1:len(allChars)-1], start=1):
              left, right = allChars[i-1], allChars[i+1]
              if ((val[1] == 1) and (left[0] == right[0])):
                  res += min(left[1], right[1])
                  
          return res
      
    • + 0 comments

      I programmed like a hell but turned out this much easy. Thank you!

    • + 0 comments

      First pass can be done without using second variable 'cur'

       l = []
      count = 1
      for i in range(len(s)):
          try:
              if s[i] == s[i+1]:
                  count+=1
              else:
                  l.append((s[i],count))
                  count = 1
          except:
              l.append((s[i],count))
      ans = 0
      
    • + 0 comments

      I have done in similar way considering a dict.Can u please explain the 3rd pass in detail(logic)

    • + 0 comments

      great approach

    • + 0 comments

      Here is a single pass implemetation of the same logic....

      def substrCount(n, s):
          l = []
          count = 0
          cur = None
          ans =0
          s_no = 0
      
          for i in range(n):
              if s[i] == cur:
                  count += 1
              else:
                  if cur is not None:
                      l.append((cur, count))
          
                      ans += (count * (count+1))//2
                      s_no +=1 
          
                      if s_no>=3:
                         if l[s_no - 3][0] == l[s_no-1][0] and l[s_no-2][1] == 1:
                              ans += min(l[s_no-3][1], l[s_no-1][1]) 
          
                  cur = s[i]
                  count = 1
          
          l.append((cur, count))
          
          ans += (count * (count+1))//2
          s_no+=1
      
          if s_no>=3:
              if l[s_no - 3][0] == l[s_no-1][0] and l[s_no-2][1] == 1:
                  ans += min(l[s_no-3][1], l[s_no-1][1])
      
          return ans
      
    • + 0 comments

      I pretty much had the same solution, in two passes and with a few minor differences. in c++:

      struct x {
          char c;
          int n;
      };
      
      long substrCount(int n, string s) {
          long total = 0;
          vector<x> table;
      
          for (int i = 0; i < s.length();) {
              char c = s[i];
              int len = 0;
              while (len + i < s.length() && s[i + len] == c)
                  ++len;
              table.push_back({c, len});
              i += len;
          }
          for (int i = 0; i < table.size(); ++i) {
              total += (table[i].n * (table[i].n + 1)) / 2;
              if (table[i].n == 1
                      && i > 0 && i < table.size() - 1
                      && table[i - 1].c == table[i + 1].c) {
                  total += min(table[i - 1].n, table[i + 1].n);
              }
          }
          return total;
      }
      
    • + 0 comments

      That is wonderful code!

    • + 0 comments

      Can anyone explain me 2nd & 3rd pass?

    • + 0 comments

      I have explained in detail the complete logic and program for beginners while intermediates can just read the logic part to get the idea. The logic is faster than using regex method by 5% and the complexity is O(n). I have used recursions. The link to the github page is here.

      The raw code is here,

      # Complete the substrCount function below.
      def count_centered(s,i,j,length,n):
          if (i < n-1) and (j > 0) and (s[i+1] == s[j-1]) and (s[i+1] == s[i]):
              return count_centered(s,i+1,j-1,length+1,n)
          else:
              return length + 1
      
      def count_same(s,i,length,n):
          if (i < n-1) and (s[i+1] == s[i]):
              return count_same(s,i+1,length+1,n)
          else:
              return (length*(length + 1)/2)-1,i
      
      def substrCount(n, s):
          count = 1
          i = 1
          while i < n:
              if s[i] == s[i-1]:
                  temp,i = count_same(s,i,2,n)
                  count += temp
              elif (i > 1) and s[i] == s[i-2]:
                  count += count_centered(s,i,i-2,1,n)
              else:
                  count += 1
              i+= 1
                  
          return int(count)
      
    • + 0 comments

      Thank you for the solution! I've implemented it similarly in C#:

          static long substrCount(int n, string s) {
              int result = 0; 
              
              // Gather sequences of characters into a list of tuples.
              List<(char, int)> sequences = new List<(char, int)>();
              int firstCharInSequence = 0;
              for (int i = 1; i < n; i++) {
                  if (s[i] != s[i-1]) {
                      // Save the sequence to our list
                      sequences.Add((s[i-1], i - firstCharInSequence));
      
                      // Reset the counters
                      firstCharInSequence = i;
                  }
              }
              // Add the remainder
              sequences.Add((s[n-1], n - firstCharInSequence));        
              // now e.g. for aabaa we have a list of ('a', 2), ('b', 1), ('a', 2).
      				
              // Second pass - add all repeated sequences of chars into the total count
              foreach (var seq in sequences) 
                  result += seq.Item2 * (seq.Item2 + 1) / 2; 
                  // triangular number sequence
              
      
              // Third pass - account for all palindromes with a different char in the middle
              int j = 0;
              while (j < sequences.Count - 2) {
                  // We're moving the window of 3 numbers, from left to right.
                  var left = sequences[j];
                  var center = sequences[j+1];
                  var right = sequences[j+2];
                  
                  // If the characters are the same on the sides,
                  // and if there's only one character in the middle
                  // Then count the widest substring, and all narrower ones.
                  // e.g. aaa_aaa gives us 3 substrings: aaa_aaa, aa_aa, a_a. 
                  if (left.Item1 == right.Item1 && center.Item2 == 1)
                      result += Math.Min(left.Item2, right.Item2);
                  
                  j++; // Move the window one position to the right
              }
              
              return result;
          }
      
    • + 0 comments

      great solution! I implemented it in C++ Cheers!

    • + 0 comments

      I do not understand why in the 3rd pass is ans+=min(l[i - 1][1], l[i + 1][1]) and not the summatory of min f.e in aaabaaa the possible ones aren't aba aabaa aaabaaa ??? whith your code is only aaabaaa

    • + 0 comments
      def summi(num):
          if num == 1:
              return 1
          if num == 0:
              return 0
          if num == 2:
              return 3
          return num + summi(num-1)
      
      
      
      def substrCount(n, s):
          stri = []
          count = 0
          for i,a in groupby(s):
              stri.append((i , len(list(a))))
          for i in range(len(stri)):
              count += summi(stri[i][1])
          for i in range(len(stri)-2):
              if stri[i][0] == stri[i+2][0] and stri[i+1][1] == 1:
                  count += min(stri[i][1] , stri[i+2][1])
          return count
      
    • + 0 comments

      I've tried to understand the algorithm at first place by just reading your 3 steps description, but I fail.

      Thanks for you code (I knew it's bad not thinking by myself), but without the code I cannot make it. It's genious solution.

    • + 0 comments

      Hi! can you explain me why this formula: (i[1] * (i[1] + 1)) // 2 works?

      Maybe is related with combinatorics, the thing is that I don't understand that.

      Thank you for your time

    • + 0 comments

      converted to java using your logic a simplified

      import java.io.; import java.math.; import java.security.; import java.text.; import java.util.; import java.util.concurrent.; import java.util.regex.*;

      class point { char ch; int count; point(char ch,int count) { this.ch=ch; this.count=count; } } public class Solution {

      // Complete the substrCount function below.
      static long substrCount(int n, String s) 
      {
          char ch=' ';
          int count=1;
      
          ArrayList<point> ar = new ArrayList<point>();
      
          for(int i=0;i<n;i++)
          {
              if(s.charAt(i)==ch)
              {
                  count++;
              }
              else
              {
                  ar.add(new point(ch,count));
                  ch=s.charAt(i);
                  count=1;
              }
          }
          ar.add(new point(ch,count));
      
          long ans=0;
      
          for(int i=0;i<ar.size();i++)
          {
              int k= ar.get(i).count;
              ans+=(k*(k+1))/2;
          }
      
          //  System.out.println(ans);
          for(int i=1;i<ar.size()-1;i++)
          {
              if(ar.get(i-1).ch==ar.get(i+1).ch && ar.get(i).count==1)
              {
                  ans+=Math.min(ar.get(i-1).count,ar.get(i+1).count);
              }
          }
      
          return ans-1;
      
      }
      
      private static final Scanner scanner = new Scanner(System.in);
      
      public static void main(String[] args) throws IOException {
          BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
      
          int n = scanner.nextInt();
          scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
      
          String s = scanner.nextLine();
      
          long result = substrCount(n, s);
      
          bufferedWriter.write(String.valueOf(result));
          bufferedWriter.newLine();
      
          bufferedWriter.close();
      
          scanner.close();
      }
      

      }

    • + 0 comments

      Thanks for the simple solution. I especially found the 3rd pass to be verify useful (that was the 'aha' moment for me):

      if l[i - 1][0] == l[i + 1][0] and l[i][1] == 1:

      ans += min(l[i - 1][1], l[i + 1][1])

    • + 0 comments

      fucking good :)

      here is java

      import java.io.; import java.math.; import java.security.; import java.text.; import java.util.; import java.util.concurrent.; import java.util.regex.*;

      public class Solution {

      // Complete the substrCount function below.
      //1 3 6 10
      static long substrCount(int n, String s) {
          char[] ch = new char[1000000];
          char tempCh = s.charAt(0);
          int[] num = new int[1000000];
          ch[0] = tempCh;
          num[0] = 1;
          int index = 0;
          int result = 0;
          for(int i = 1; i<s.length(); i++){
              if(tempCh == s.charAt(i)){
                  num[index]++;
              } else{
                  tempCh = s.charAt(i); 
                  index++;
                  num[index] = 1;
                  ch[index] = s.charAt(i);
              }
          }
          for(int i = 0; i<index+1; i++){
              result += (num[i] * (num[i]-1))/2 + num[i];
          }
          for(int i = 1; i<index; i++){
              if(ch[i-1] == ch[i+1] && num[i] == 1){
                  result += num[i-1] > num[i+1] ? num[i+1] : num[i-1];
              }
          }
          return result;
      }
      
      private static final Scanner scanner = new Scanner(System.in);
      
      public static void main(String[] args) throws IOException {
          BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
      
          int n = scanner.nextInt();
          scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
      
          String s = scanner.nextLine();
      
          long result = substrCount(n, s);
      
          bufferedWriter.write(String.valueOf(result));
          bufferedWriter.newLine();
      
          bufferedWriter.close();
      
          scanner.close();
      }
      

      }

    • + 0 comments

      Thanks! I didn't think of first organising into tuple array

    • + 0 comments

      c++ code

      long substrCount(int n, string s) {

      long ans=0;
      vector<pair<char,int>>v;
      int occur=1;
      for(int i=1;i<n;i++)
      {
          if(s[i]==s[i-1])
          occur++;
          else
          {
              v.push_back({s[i-1],occur});
              occur=1;
          }
      }
      v.push_back({s[n-1],occur});
      
      for(int i=0;i<v.size();i++)
      {
          ans+= (v[i].second * (v[i].second+1))/2;
      
          if(i!=0 && i!=v.size()-1)
          {
              if(v[i].second==1 && v[i-1].first==v[i+1].first)
              ans+= min(v[i-1].second,v[i+1].second);
          }
      }
      
      return ans;
      

      }

      return 0;
      

      }

    • + 0 comments

      I think people should post their pseudocode and explain how it might work to pass all test cases

    • + 0 comments

      Sir, can you please explain about the formula you used in second pass.

    • + 0 comments

      This was alot of help thanks. got really confused at one point, becuase i thought the 2 substrings on the sides of the single character substring had to be the same number of chars. thanks :D

    • + 1 comment
      [deleted]
      • + 0 comments

        No because ab and ba are not the same on either side of abcba. would have to be abcab. i believe havnt looked in a while

    • + 0 comments

      very smart approach to reduce the string to another structure

    • + 0 comments

      Thank you!

    • + 0 comments

      nice thank u

    • + 0 comments

      Great. Super understandable

    • + 0 comments

      Like! Same in java :

      static long substrCount(int n, String s) {
      
          long result = 0;
          int count = 1;
          String temp = null;
      
          ArrayList<String> keys = new ArrayList<>();
          ArrayList<Integer> values = new ArrayList<>();
      
          // 1st pass
          for (String c : s.split("")) {
              if (c.equals(temp))
                  count++;
              else {
                  if (temp != null) {
                      keys.add(temp);
                      values.add(count);
                  }
                  count = 1;
                  temp = c;
              }
          }
      
          keys.add(temp);
          values.add(count);
      
          // 2nd pass
          for (int value : values) {
              result += value * (value + 1) / 2;
          }
      
          // 3d pass
          for (int i = 1; i < values.size() - 1; i++) {
              if (keys.get(i - 1).equals(keys.get(i + 1)) && values.get(i) == 1)
                  result += Math.min(values.get(i - 1), values.get(i + 1));
          }
      
          return result;
      }
      
    • + 1 comment
      [deleted]
      • + 1 comment
        [deleted]
        • + 0 comments

          def substrCount(n, s):

          sdict = []
          x = 1
          
          for i in range(1,n):
              if s[i] != s[i-1]:
                  sdict.append((s[i-1],x))
                  x = 1
              else:
                  x += 1
          sdict.append((s[n-1],x)) 
          
          
          count = 0
          
          # xxxxx....... etc condition count
          for x in sdict:
              count += (x[1] * (x[1] + 1)) // 2
          
          
          # x.x, xx.xx, xxx.xxx .... etc condition count
          for i in range(1,len(sdict)-1):
              if sdict[i][1] == 1:
                  if sdict[i-1][0] == sdict[i+1][0]:
                      count += min(sdict[i-1][1],sdict[i+1][1])
          
          return count
          
    • + 0 comments

      Cool! Here's a Ruby version:

      def substr_count(n, s)
        comp = s.chars.each_with_object([]) do |c, acc|
          if !acc.empty? && acc.last[0] == c
            acc[-1] = [c, acc.last[1] + 1]
          else
            acc << [c, 1]
          end
        end
      
        count = comp.map { |_c, l| l * (l + 1) / 2 }.sum
      
        (1...(comp.length - 1)).each do |i|
          count += [comp[i - 1][1], comp[i + 1][1]].min if comp[i - 1][0] == comp[i + 1][0] && comp[i][1] == 1
        end
        count
      end
      
      
      n = gets.to_i
      s = gets.chomp
      puts substr_count(n, s)
      
    • + 0 comments

      One pass solution with backtracking, collecting all valid palindromes. Passes all tests.

      def substrCount(n, s):
          # print('---', s)
          subs = []
          for i, l in enumerate(s):
              # collect all single chars
              subs.append(l)
      
              if i > 0:
                  # collect all substrings of same chars behind i
                  j = i - 1
                  sub = l
                  while j >= 0 and s[j] == l:
                      sub += s[j]
                      subs.append(sub)
                      j -= 1
      
                  # collect all substrings where middle char is different 
                  # and all chars on left and right are the same
                  j = i - 1
                  if s[j] != l:                
                      k = i + 1
                      sub = l
                      while j >= 0 and k < n and s[j] == s[k]:
                          if j+1 < i and s[j] != s[j+1]:
                              break
      
                          sub = f'{s[j]}{sub}{s[k]}'
                          subs.append(sub)
                          j -= 1
                          k += 1
      
          # print(subs)
      
          return len(subs)
      
    • + 0 comments

      Here is javascript code:

      function substrCount(n, s) { let count = 0; const arr = s.split(''); const tuple = [[arr[0], 1]];

      for (let i = 1; i < arr.length; i++) {
          const element = arr[i];
          if (element == tuple[tuple.length - 1][0]) {
              tuple[tuple.length - 1][1]++
          } else {
              tuple.push([element, 1]);
          }
      }
      
      for (const element of tuple) {
          count += (element[1] * (element[1] +1)) /2
      } 
      
      for (let i = 1; i < tuple.length - 1; i++) {
          const element = arr[i];
          if (tuple[i - 1][0] == tuple[i + 1][0] && tuple[i][1] == 1) {
              const min = tuple[i - 1][1] > tuple[i + 1][1] ? tuple[i + 1][1] :  tuple[i - 1][1]
              count += min;
          } 
      
      }
      return count;
      

      }