이 문제는 Enumerating Gene Orders 문제의 연장선상에 있는 문제입니다. DNA의 재배열(rearrangement)는 점 돌연변이(point mutation)이 조금씩밖에 종의 다양성을 변화시킬 수 있는 것과는 다르게 종을 크게 변화시킬 수 있습니다. 예를 들면 일개 영장류가 인간으로 분화하고, 꼬끼리, 가재, 소, 돼지 등 수많은 종이 존재할 수 있게 된 것도 유전자 재배열에 의하여 이루어졌다고 합니다. 그렇지만 점 돌연변이도 겸상적혈구빈혈증같이 치명적인 질병을 유발할 수 있듯이 긴 DNA 부분이 재배열 되면 대체적으로 치명적입니다. 그래서인지 DNA 재배열은 거의 일어나지 않습니다.
과학자들은 재배열이 잘 일어나지 않는 것을 근거로 비슷한 종은 비슷한 유전자를 가지고 있을 것이라 생각합니다. 그래서 두 종을 비교할 때, 두 종의 DNA가 얼마나 비슷하지를 보죠. 이 때, 과학자들이 종을 비교하기 위해 주목하는 것이 Synteny block 입니다.
(사진 출처: http://rosalind.info/problems/sign/)
과학자들이 두 종을 비교하기 위해서는 아래와 같은 순서를 따릅니다.
이와 같은 방식으로 두 종을 비교할 수가 있습니다.
Enumerating Gene Orders 문제에서는 synteny block을 단순화하기 위해 DNA 나선이 2가닥임에도 불구하고 하나 간주하고 문제를 풀었습니다. 하지만 더 정확하게 염색체를 묘사하기 위해서는 DNA에 방향이 있을음 생각해야 합니다. DNA는 두 가닥이 서로 반대 방향으로 복제 및 전사가 진행되기 때문입니다. 이 문제에서는 이를 반영하여 순열을 구하는 법을 요구합니다.
A signed permutation of length n is some ordering of the positive integers in which each integer is then provided with either a positive or negative sign (for the sake of simplicity, we omit the positive sign). For example, is a signed permutation of length 5.
Given : A positive integer n≤6.
Return : The total number of signed permutations of length n, followed by a list of all such permutations (you may list the signed permutations in any order).
n 값이 주어졌을 때, 정수들 이 각각 양수도 될 수 있고, 음수도 될 수 있다고 했을 때, 순열의 개수와 순서에 상관없이 전체 순열의 경우의 수를 나열하라는 문제로 볼 수 있습니다.
def signed_permutations(n):
# 0 을 제외한다.
ls = [i for i in range(-n, n+1) if i != 0]
# 2nPn 순열을 모두 구한다.
permus = permutations(ls, n)
for p in permus:
# 각 순열의 경우의 수를 nC2 조합을 구한 뒤에 각 조합의 합 중에 0이 없을 경우 통과시킨다.
if all(map(sum, combinations(p, 2))):
yield p
전체 코드는 github rosalind_SIGN.ipynb 에 있습니다.