Skip to content

Instantly share code, notes, and snippets.

@davidrusu
Last active March 13, 2016 04:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidrusu/03a768ed51030d7742c0 to your computer and use it in GitHub Desktop.
Save davidrusu/03a768ed51030d7742c0 to your computer and use it in GitHub Desktop.
from random import shuffle
from math import log2, floor
def main():
A = list(range(15))
B = list(range(10))
print("Before:\t A =", A)
print("\t B =", B)
N = len(A)
P = 5 # Number of procs
block_size = floor(N / P) # minimum block size
b_block_start = 0
result = []
for p in range(P):
a_block_start = p * block_size + min(p, N % P)
a_block_size = block_size + (1 if p < N % P else 0)
last_val_in_a_block = A[a_block_start + a_block_size - 1]
b_block_end = last_index_less_or_eq_to(B,
last_val_in_a_block,
b_block_start)
if b_block_end is None:
b_block_size = 0
else:
b_block_size = b_block_end - b_block_start + 1
merge_result = merge(A, a_block_start, a_block_size,
B, b_block_start, b_block_size)
result += merge_result
b_block_start += b_block_size
print("Merged:\t", result)
def last_index_less_or_eq_to(xs, value, start_index):
prev_index = None
for i, x in enumerate(xs[start_index:]):
if x > value:
break
else:
prev_index = i + start_index
return prev_index
def merge(A, a_start, a_size, B, b_start, b_size):
result = []
a_index = a_start
b_index = b_start
# because of the way we choose b_size, the last value in the B block
# will always be < last value in A block, so B block will be consumed
# first
while b_index < b_start + b_size:
if A[a_index] < B[b_index]:
result.append(A[a_index])
a_index += 1
else:
result.append(B[b_index])
b_index += 1
while a_index < a_start + a_size:
result.append(A[a_index])
a_index += 1
return result
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment