-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathsubpalindrome.py
More file actions
59 lines (53 loc) · 1.84 KB
/
subpalindrome.py
File metadata and controls
59 lines (53 loc) · 1.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
"""
longest_subpalindrome problem from Udacity CS212.
Genesis: https://forums.udacity.com/questions/100051766/using-a-heap-to-avoid-trying-starting-positions-that-cant-possibly-give-the-best-answer#cs212
"""
def find_longest_palindrome(s):
"Return (i,j) such that s[i:j] is a longest palindrome in s."
i, j = 0, 0
for max_width in range(len(s), 0, -1):
if max_width <= j - i:
break
# Check the candidate centers that on growing to max_width
# would reach either the left or the right edge of s.
for m in set([max_width, 2*len(s) - max_width]):
i1, j1 = grow(s, m // 2, (m + 1) // 2)
if j - i < j1 - i1:
i, j = i1, j1
return i, j
def grow(s, i, j):
"Return the slice-indices of the longest palindromic extension of palindrome s[i:j]."
while 0 < i and j < len(s) and s[i-1].lower() == s[j].lower():
i -= 1; j += 1
return i, j
## find_longest_palindrome('')
#. (0, 0)
## find_longest_palindrome('x')
#. (0, 1)
## find_longest_palindrome('xy')
#. (0, 1)
## find_longest_palindrome('xx')
#. (0, 2)
## find_longest_palindrome('xyx')
#. (0, 3)
## find_longest_palindrome('xyy')
#. (1, 3)
## find_longest_palindrome('abracadabra')
#. (3, 6)
## find_longest_palindrome('abracarbra')
#. (1, 8)
def test_suite(n=10):
for L in range(n+1):
for i in range(2**L):
s = bin(i)[2:]
s = '0' * (n - len(s)) + s
test_finder(find_longest_palindrome, s)
def test_finder(finder, string):
i, j = finder(string)
assert 0 <= i <= j <= len(string)
assert string[i:j] == string[i:j][::-1] # assuming string doesn't mix cases
for lo in range(len(string)+1):
for hi in range(lo+j-i+1, len(string)+1):
assert string[lo:hi] != string[lo:hi][::-1]
## test_suite()
# print find_longest_palindrome('x'*100000)