Skip to content

Instantly share code, notes, and snippets.

@nitely
Created January 4, 2016 04:10
Show Gist options
  • Save nitely/c99880de7a68f153f79c to your computer and use it in GitHub Desktop.
Save nitely/c99880de7a68f153f79c to your computer and use it in GitHub Desktop.
Topcoder ABAB problem
"""
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