Super Reduced String python

Question:

I’ve been having problems with this simple hackerrank question. My code works in the compiler but hackerrank test is failing 6 test cases. One of which my output is correct for (I didn’t pay premium). Is there something wrong here?

Prompt:
Steve has a string of lowercase characters in range ascii[‘a’..’z’]. He wants to reduce the string to its shortest length by doing a series of operations in which he selects a pair of adjacent lowercase letters that match, and then he deletes them. For instance, the string aab could be shortened to b in one operation.

Steve’s task is to delete as many characters as possible using this method and print the resulting string. If the final string is empty, print Empty String

Ex.

aaabccddd → abccddd → abddd → abd

baab → bb → Empty String

Here is my code:

def super_reduced_string(s):
    count_dict = {}
    for i in s:
        if (i in count_dict.keys()):
            count_dict[i] += 1 
        else:
            count_dict[i] = 1 

    new_string = ''
    for char in count_dict.keys():
        if (count_dict[char] % 2 == 1):
            new_string += char

    if (new_string is ''):
        return 'Empty String'
    else:
        return new_string

Here is an example of output for which it does not work.

print(super_reduced_string('abab'))

It outputs 'Empty String' but should output 'abab'.

Asked By: handavidbang

||

Answers:

By using a counter, your program loses track of the order in which it saw characters. By example with input 'abab', you program sees two a‘s and two b‘s and deletes them even though they are not adjacent. It then outputs 'Empty String' but should output 'abab'.

O(n) stack-based solution

This problem is equivalent to finding unmatched parentheses, but where an opening character is its own closing character.

What this means is that it can be solved in a single traversal using a stack.

Since Python can return an actual empty string, we are going to output that instead of 'Empty String' which could be ambiguous if given an input such as 'EEEmpty String'.

Code

def super_reduced_string(s):
    stack = []
    for c in s:
        if stack and c == stack[-1]:
            stack.pop()
        else:
            stack.append(c)

    return ''.join(stack)

Tests

print(super_reduced_string('aaabab'))     # 'abab'
print(super_reduced_string('aabab'))      # 'bab'
print(super_reduced_string('abab'))       # 'abab'
print(super_reduced_string('aaabccddd ')) # 'abd'
print(super_reduced_string('baab '))      # ''
Answered By: Olivier Melançon

I solved it with recursion:

def superReducedString(s):
    if not s:
        return "Empty String"
    for i in range(0,len(s)):
        if i < len(s)-1:
            if s[i] == s[i+1]:
                return superReducedString(s[:i]+s[i+2:])
    return s

This code loops over the string and checks if the current and next letter/position in the string are the same. If so, these two letters/positions I get sliced from the string and the newly created reduced string gets passed to the function.
This occurs until there are no pairs in the string.

TESTS:

print(super_reduced_string('aaabccddd')) # 'abd'
print(super_reduced_string('aa')) # 'Empty String'
print(super_reduced_string('baab')) # 'Empty String'
Answered By: Tom

I solved it by creating a list and then add only unique letters and remove the last letter that found on the main string. Finally all the tests passed!

def superReducedString(self, s):
    stack = []
    for i in range(len(s)):
        if len(stack) == 0 or s[i] != stack[-1]:
            stack.append(s[i])
        else:
            stack.pop()
    return 'Empty String' if len(stack) == 0 else ''.join(stack)
Answered By: Ahmed

I used a while loop to keep cutting down the string until there’s no change:

def superReducedString(s):

    repeat = set()
    dups = set()
    for char in s:
        if char in repeat:
            dups.add(char + char)
        else:
            repeat.add(char)

    s_old = ''        
    while s_old != s:
        s_old = s
        for char in dups:
            if char in s:
                s = s.replace(char, '')
    
    if len(s) == 0:
        return 'Empty String'
    else:
        return s
Answered By: Yifu Hou

Solved With a while loop and string slicing!

def superReducedString(s):
   
    retString = s
    i=0

    while i < len(retString)-1:
        if retString[i] == retString[i+1]:
            if i == 0:
                retString= retString[2:]
            else:
                retString= retString[:i] + retString[i+2:]
            i = 0
        else:
            i += 1   
    
    return retString if retString else "Empty String"

It passes all the test cases 🙂

Answered By: fabriziogianni7
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.