Created
January 4, 2016 04:10
-
-
Save nitely/c99880de7a68f153f79c to your computer and use it in GitHub Desktop.
Topcoder ABAB problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Problem Statement | |
One day, Jamie noticed that many English words only use the letters A and B. Examples of such words include "AB" (short for abdominal), "BAA" (the noise a sheep makes), "AA" (a type of lava), and "ABBA" (a Swedish pop sensation). | |
Inspired by this observation, Jamie created a simple game. You are given two s: initial and target. The goal of the game is to find a sequence of valid moves that will change initial into target. There are two types of valid moves: | |
Add the letter A to the end of the string. | |
Reverse the string and then add the letter B to the end of the string. | |
Return "Possible" (quotes for clarity) if there is a sequence of valid moves that will change initial into target. Otherwise, return "Impossible". | |
Definition | |
Class: ABBA | |
Method: canObtain | |
Parameters: string, string | |
Returns: string | |
Method signature: def canObtain(self, initial, target): | |
""" | |
class ABBA: | |
def _canObtain(self, target, index_end, reversed_end): | |
while True: | |
# Try first move | |
try: | |
if target[index_end] == 'A': | |
index_end += 1 | |
continue | |
except IndexError: | |
pass | |
# Try second move | |
try: | |
target = target[::-1] | |
tmp_a = index_end | |
index_end = reversed_end | |
reversed_end = tmp_a | |
if target[index_end] == 'B': | |
index_end += 1 | |
continue | |
else: | |
return False | |
except IndexError: | |
pass | |
return True | |
def canObtain(self, initial, target): | |
# Try starting with the first move | |
index_start = 0 | |
while True: | |
index_start = target.find(initial, index_start) | |
index_end = len(initial) + index_start | |
reversed_start = len(target) - index_end - 1 | |
reversed_end = len(initial) + reversed_start | |
if index_start == -1: | |
break | |
if self._canObtain(target, index_end, reversed_end): | |
return 'Possible' | |
index_start += 1 | |
# Try starting with the second move (reversed) | |
reversed_target = target[::-1] | |
reversed_start = 0 | |
while True: | |
reversed_start = reversed_target.find(initial, reversed_start) | |
reversed_end = len(initial) + reversed_start | |
index_start = len(target) - reversed_end - 1 | |
index_end = len(initial) + index_start | |
if reversed_start == -1: | |
break | |
if self._canObtain(target, index_end, reversed_end): | |
return 'Possible' | |
reversed_start += 1 | |
return 'Impossible' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment