Skip to content

Instantly share code, notes, and snippets.

@desmondrawls
Created May 27, 2020 03:00
Show Gist options
  • Save desmondrawls/709ffd9a48e693f4d0933eda031e2d72 to your computer and use it in GitHub Desktop.
Save desmondrawls/709ffd9a48e693f4d0933eda031e2d72 to your computer and use it in GitHub Desktop.
# Because the strands are very long, in order to sequence DNA,
# labs will first split the strands into many small overlapping pieces.
# Once they're sequenced, the pieces need to be recombined.
# Write a function that recombines overlapping pieces into a single strand of DNA.
# Each sequenced piece contains Adenine, Thynine, Cystosine and Guanine represented by 'A', 'T', 'C', and 'G', respectively.
# Two pieces can connect if they overlap at least one base pair.
# Assume that there is only one way to combine all the pieces into a single strand.
from functools import reduce, partial
def isRestMatch(first_piece, second_piece, first_index, second_index):
if first_index == len(first_piece):
return True
elif second_index == len(first_piece):
return False
elif first_piece[first_index] != second_piece[second_index]:
return False
else:
return isRestMatch(first_piece, second_piece, first_index + 1, second_index + 1)
def isPredecessor(first_piece, second_piece):
for i, base in enumerate(first_piece):
if base == (second_piece[0]) and isRestMatch(first_piece, second_piece, i + 1, 1):
return True
return False
def predecessors(pieces, accumulator, nextt):
(adjacent, unused) = accumulator
(i, piece) = nextt
used = False
for neighbor_index, piece in enumerate(pieces):
if neighbor_index != i and isPredecessor(pieces[neighbor_index], pieces[i]):
if neighbor_index in adjacent:
adjacent[neighbor_index].append(i)
else:
adjacent[neighbor_index] = [i]
used = True
return (adjacent, []) if used else (adjacent, [i])
def explore(adjacent, vertex, children):
if(len(children) == len(adjacent) + 1):
return children
elif vertex not in adjacent:
return False
for child in adjacent[vertex]:
if child not in children:
explored = explore(adjacent, child, children + [child])
if explored:
return explored
return None
def recombine(pieces):
unused = pieces.copy()
adjacent = {}
(adjacent, unused) = reduce(partial(predecessors, pieces), enumerate(pieces), ({}, []))
start = unused[0]
parents = {start: None}
explored = explore(adjacent, start, [start])
return explored
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment