2
\$\begingroup\$

After thinking for a long hard time, learning about algorithms to find substrings, and coming to really long and tedious code I decided against my solution and to look for help. The solution was much simpler and elegant. After determining that my code was too much for a simple task I came across an explanation of a simple way to find if one string was a rotation of the other. Man I feel dumb for falling down a long rabbit hole however I learned much about many different things and also how to keep it simple stupid. Previous post of this problem here.

#rotated list
def is_rotated(lst1, lst2):
 ''' Is lst2 a rotation of lst1'''
 str1, str2 = ''.join(map(str,lst1)), ''.join(map(str,lst2))
 if not len(str1) == len(str2):
 raise ValueError("Lengths not equal")
 if str2 in (str1 + str1):
 return True
 return False
# rotation
lst1, lst2 = [1,2,3,4,6,4,7], [6,4,7,1,2,3,4]
assert is_rotated(lst1, lst2)
# rotation with repeated numbers
lst1, lst2 = [1,2,3,4,6,4,7,1], [6,4,7,1,1,2,3,4]
assert is_rotated(lst1, lst2)
# different set
lst1, lst2 = [1,2,3,4,6,4,6], [6,4,7,1,2,3,4]
assert not is_rotated(lst1, lst2)
lst1, lst2 = [1,2,3,4,6,4,7], [6,4,6,1,2,3,4]
assert not is_rotated(lst1, lst2)
# equal
lst2 = lst1
assert is_rotated(lst1, lst2)
# empty
lst1, lst2 = [], []
assert is_rotated(lst1, lst2)
# 1 empty, 1 not empty
lst1, lst2 = [], [1]
assert not is_rotated(lst1, lst2)
lst1, lst2 = [1], []
assert not is_rotated(lst1, lst2)
asked Apr 12, 2018 at 23:51
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

Good work! This is certainly primarily an improvement from your previous implementation. However, there are still a few problems.

  1. Don't raise an error when passed two lists of differing length. Not only is this unexpected by users, it breaks some of your tests.

    # 1 empty, 1 not empty
    lst1, lst2 = [], [1]
    assert not is_rotated(lst1, lst2)
    lst1, lst2 = [1], []
    assert not is_rotated(lst1, lst2)
    
  2. The pattern of if condition return True else return False should be replaced with return condition. This is easier to read and reduces the amount of code you have to write!

  3. Joining the lists of integers with the empty string as a separator is dangerous. If I pass in [1, 23] and [12, 3] the function will incorrectly return True. If the function only has to handle integers, you can easily fix this by using a comma (or any other character) as a separator. (Just remember to include it when checking if the string is contained in the other string str1 + ',' + str1)

I would prefer a more general solution that works for lists containing any type of element. Using Nas Banov's answer from Stack Overflow to handle the sub list check, this is a really simple function to write.

def contains_sublist(lst, sublst):
 n = len(sublst)
 return any((sublst == lst[i:i+n]) for i in range(len(lst)-n+1))
def is_rotated(lst1, lst2):
 if not len(lst1) == len(lst2):
 return False
 return len(lst1) == 0 or contains_sublist(lst2 * 2, lst1)
answered Apr 13, 2018 at 1:57
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.