# algorithms.py # Erik Andersen (ela63) and Walker M. White (wmw2) # May 2, 2017 """ Module with algorithms from the sequence algorithm design slides.""" def swap(b, i, j): b[i], b[j] = b[j], b[i] def partition(b, h, k): """Partition list b[h..k] around a pivot x = b[h] Returns: pivot index""" i = h; j = k+1; x = b[h] # invariant: b[h..i-1] <= x, b[i] = x, b[j..k] >= x while i < j-1: if b[i+1] >= x: # Move to end of block. swap(b,i+1,j-1) j = j - 1 else: # b[i+1] < x swap(b,i,i+1) i = i + 1 # post: b[h..i-1] < x, b[i] is x, and b[i+1..k] >= x return i def test_partition(): seq = [-1, 6, -4, 0, 1, 0, -4, -3, 6, 7, -1] partition(seq, 0, len(seq)-1) print seq def rpartition(b): return rpartition_helper(b, b[0]) def rpartition_helper(b, x): if len(b) <= 1: return b left = b[:1] right = b[1:] if b[0] < x: return left + rpartition_helper(right, x) else: return rpartition_helper(right, x) + left def test_rpartition(): seq = [-1, 6, -4, 0, 1, 0, -4, -3, 6, 7, -1] seq = rpartition(seq) print seq def dnf(b, h, k): # Loop variables to satisfy the invariant t = h j = k i= k+1 # inv: b[h..t-1] < 0, b[t..i-1] unknown, b[i..j] = 0, and b[j+1..k] > 0 while t < i: if b[i-1] < 0: b[i-1], b[t] = b[t], b[i-1] t = t+1 elif b[i-1] == 0: i = i-1 else: b[i-1], b[j] = b[j], b[i-1] i = i-1 j = j-1 # post: b[h..i-1] < 0, b[i..j] = 0, and b[j+1..k] > 0 # Return dividers as a tuple return (i, j) def rdnf(b, h, k): rdnf_helper(b, h, k+1, k) def rdnf_helper(b, t, i, j): #print b if t==i: return if b[i-1] < 0: b[i-1], b[t] = b[t], b[i-1] rdnf_helper(b, t+1, i, j) elif b[i-1] == 0: rdnf_helper(b, t, i-1, j) else: b[i-1], b[j] = b[j], b[i-1] rdnf_helper(b, t, i-1, j-1) def test_rdnf(): seq = [-1, 6, -4, 0, 1, 0, -4, -3, 6, 7, -1] rdnf(seq, 0, len(seq)-1) print seq def bsearch(b, v): #find if v is in b using binary partitioning i = 0 j = len(b) while i < j: mid = (i + j) / 2 if b[mid] < v: i = mid + 1 else: #b[mid] >= v j = mid if i < len(b) and b[i] == v: return i else: return -1 def test_bsearch(): seq = [1, 2, 3, 4, 6, 7, 8, 10, 12] key = 50 print bsearch(seq, key) def rbsearch(b, v): """ len(b) > 0 """ return rbsearch_helper(b, v, 0, len(b)) def rbsearch_helper(b, v, i, j): if i >= j: if i < len(b) and b[i] == v: return i else: return -1 mid = (i + j) / 2 if b[mid] < v: return rbsearch_helper(b, v, mid + 1, j) else: # b[mid] >= v return rbsearch_helper(b, v, i, mid) def test_rbsearch(): seq = [1, 2, 3, 3, 3, 3, 4, 6, 7, 8, 10, 12] key = 4 print rbsearch(seq, key) def rbsearch2(seq, key): return rbsearch2_helper(seq, key, 0, len(seq)-1) def rbsearch2_helper(seq, key, lo, hi): if lo > hi: return -1 else: mid = (lo+hi)/2 if seq[mid] == key: return mid elif seq[mid] < key: return rbsearch2_helper(seq, key, mid+1, hi) else: #seq[mid] > key: return rbsearch2_helper(seq, key, lo, mid-1) def test_rbsearch2(): seq = [1, 2, 3, 3, 3, 3, 4, 6, 7, 8, 10, 12] key = 3 print rbsearch2(seq, key) if __name__ == '__main__': test_bsearch() #test_rbsearch() #test_rbsearch2() #test_partition() #test_rpartition()