Skip to main content
1 of 3
SylvainD
  • 29.8k
  • 1
  • 49
  • 93

Code organisation

At the moment, the logic handling the output/input and the logic computing the actual result are all mixed up.

This makes things hard to understand, hard to modify and hard to test.

It would be much easier to add a function with 2 parameters returning the string you are interested in.

With minimal changes, you'd get something like:

def get_smallest_string_combination(a, b):
    """Return the lexicographically smallest string ..."""
    la=[]
    lb=[]

    for i in range(max(len(a),len(b))):#creating lists with all possible elements by slicing off the characters
        la.append(a[i:])
        lb.append(b[i:])

    if len(a)>len(b):#removes empty elements
        lb=[x for x in lb if x!='']
    else:
        la=[x for x in la if x!='']

    output = []

    while True:#Create empty list for sorting the 0th elements of 'la' nd 'lb'
        temp=[]
        temp.append(la[0])
        temp.append(lb[0])
        temp=sorted(temp)
        output.append(temp[0][0])#add the 1st character

        if(temp[0] in la):#removing the element after printing the first character
            la.pop(0)
        else:
            lb.pop(0)

        if len(la)==0:#breaks the while loop if a list gets empty
            output.append(temp[1])
            break
        elif len(lb)==0:
            output.append(temp[1])
            break

    return "".join(output)

def automatic_test():
    assert get_smallest_string_combination("ACEG", "BDFH") == "ABCDEFGH"

def interactive_test():
    n=int(input())#number of pairs to input
    for mn in range(n):
        a=input()# String1 in the pair
        b=input()#String2 in the pair
        print(get_smallest_string_combination(a, b))

if __name__ == '__main__':
    automatic_test()

I took this chance to add a function testing the example you've provided.

Also, I've added the beginning of a docstring explaining the point of the function, I'll leave you finish it as an exercice.

More tests and first bug

Now that we have a simple way to write automatic tests, we could add test cases corresponding to edge-cases: empty string, string with one element, etc.

We'd get something like:

def automatic_test():
    # Same length
    assert get_smallest_string_combination("ACEG", "BDFH") == "ABCDEFGH"
    assert get_smallest_string_combination("ABCD", "ABCD") == "AABBCCDD"
    # Empty input
    assert get_smallest_string_combination("ABCD", "") == "ABCD"
    assert get_smallest_string_combination("", "ABCD") == "ABCD"
    # Different length
    assert get_smallest_string_combination("Z", "ABCD") == "ABCDZ"
    assert get_smallest_string_combination("ABCD", "Z") == "ABCDZ"

Which shows that empty inputs are not handled properly.

This can easily be fixed:

def get_smallest_string_combination(a, b):
    """Return the lexicographically smallest string ..."""
    la=[]
    lb=[]

    for i in range(max(len(a),len(b))):#creating lists with all possible elements by slicing off the characters
        la.append(a[i:])
        lb.append(b[i:])

    if len(a)>len(b):#removes empty elements
        lb=[x for x in lb if x!='']
    else:
        la=[x for x in la if x!='']

    output = []

    while la and lb:#Create empty list for sorting the 0th elements of 'la' nd 'lb'
        temp=[]
        temp.append(la[0])
        temp.append(lb[0])
        temp=sorted(temp)
        output.append(temp[0][0])#add the 1st character

        if(temp[0] in la):#removing the element after printing the first character
            la.pop(0)
        else:
            lb.pop(0)

    # Add remaining elements    
    if la:
        output.append(la[0])
    if lb:
        output.append(lb[0])
    return "".join(output)

Logic and complexity

The implementation is very complicated and inefficient but it would be much more simple.

TODO

SylvainD
  • 29.8k
  • 1
  • 49
  • 93