Created
May 27, 2020 03:00
-
-
Save desmondrawls/709ffd9a48e693f4d0933eda031e2d72 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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