가장 긴 역 구 개미 DNA 서브 스트링


11

아시다시피 DNA 에는 아데닌 ( A), 시토신 ( C), 구아닌 ( G) 및 티민 ( T)의 네 가지 염기가 있습니다 . 일반적 A으로 결합 TC함께 결합 G의 "가로대"의 형성, DNA 이중 나선 구조 .

우리는 정의 보완 즉의 보수 - 염기가 그 채권을 기초로 A한다 T,의 보완 T이다 A,의 보완 C이다 G과의 보완 G이다 C. 또한 DNA 문자열의 보수를 각 염기가 보완 된 문자열로 정의 할 수 있습니다 (예 : GATATCis 의 보수 ) CTATAG.

DNA의 이중 가닥 구조로 인해 한 가닥의 염기는 다른 가닥의 염기와 상보 적입니다. 그러나 DNA에는 방향이 있으며 DNA 전사는 두 가닥에서 반대 방향으로 발생합니다. 따라서 분자 생물 학자들은 종종 DNA 스트링 의 역 보체 에 관심이 있습니다.

이전 예제를 확장하려면의 역 보완 GATATC이다 CTATAG, 그래서 뒤로 GATATC. 보시다시피,이 예에서 역 보체는 원래 문자열과 같습니다. 우리는 이러한 문자열을 역 회문이라고 합니다. *

DNA 문자열이 주어지면 역 회문 인 가장 긴 하위 문자열을 찾을 수 있습니까?

* 나는 Palindrome 의 일반적인 의미와 구별하기 위해 Rosalind 에서 가져온 "Reverse palindrome"이라는 용어를 사용합니다 .


입력

입력은 ACGT대문자 로만 구성된 단일 문자열 입니다. 이 도전에 대한 함수 또는 전체 프로그램을 작성할 수 있습니다.

산출

인쇄 또는 반송을 통해 출력하도록 선택할 수 있습니다 (후자의 선택은 기능의 경우에만 사용 가능).

고유 한 솔루션이있는 경우 프로그램은 입력 문자열의 가장 긴 역 palindromic 하위 문자열을 출력해야합니다. 여러 솔루션이 존재하는 경우 솔루션 중 하나를 출력하거나 모두 선택할 수 있습니다 (선택). 당신이 그들 모두를 출력하도록 선택하면 복제는 괜찮습니다.

입력은 길이 2 이상의 솔루션을 보장합니다.

작동 예

ATGGATCCG -> GGATCC

역 보완 GGATCC자체는 ( GGATCC --complement--> CCTAGG --reverse--> GGATCC)이므로 GGATCC역 회문도 마찬가지 입니다. GATC또한 역 palindome이지만 가장 긴 것은 아닙니다.

테스트 사례

AT -> AT
CGT -> CG
AGCA -> GC
GATTACA -> AT, TA
ATGGATCCG -> GGATCC
CCCCCGGGGG -> CCCCCGGGGG
ACATATATAGACT -> ATATAT, TATATA
ATTCGATCTATGTAAAGAGG -> TCGA, GATC
CGCACGTCTACGTACCTACGTAG -> CTACGTAG
TCAATGCATGCGGGTCTATATGCAT -> ATGCAT, GCATGC [, ATGCAT]
CGCTGAACTTTGCCCGTTGGTAGAACGGACTGATGTGAACGAGTGACCCG -> CG, GC, TA, AT [, GC, CG, CG, CG, CG]
CTCGCGTTTGCATAACCGTACGGGCGGAACAGTCGGCGGTGCCTCCCAGG -> CCGTACGG

채점

이것은 코드 골프이므로 가장 적은 바이트의 솔루션이 이깁니다.


그들 모두를 인쇄하는 데 일종의 보너스가 있다면 더 좋을 것입니다.
Optimizer

@Optimizer는 모든 것을 인쇄하는 것보다 가장 오래 인쇄하기가 어렵습니까?
trichoplax

아니면 가장 긴 것을 모두 인쇄하는 것을 의미합니까?
trichoplax

@ githubphagocyte 네, 두 번째 의견입니다.
Optimizer

답변:


6

Pyth, 37 36 28 24 바이트

ef&}TzqmaCd6T_mx4aCk6Tyz

FryAmTheEggman의 팁과 Peter의 역 회문 검사 트릭을 결합한이 제품은 매우 짧은 버전입니다.

그러나 이것은 Pyth 3.0.1 에서만 작동 하며이 링크 에서 다운로드하여 다음 과 같이 실행할 수 있습니다

python3 pyth.py -c "ef&}TzqmaCd6T_mx4aCk6Tyz" <<< "ATTCGATCTATGTAAAGAGG"

(linux bash 전용. Windows에서는 <<< 대신 Enter를 누른 다음 입력을 입력하십시오)


이것은 내 이전 제출-28 바이트 솔루션

J"ACGT"ef&}TzqTjk_m@_JxJdTyz

이 버전의 FryAmTheEggman에게 감사합니다. 이것은 입력 DNA 스트링의 모든 가능한 서브 세트를 생성하고 서브 세트가 입력의 서브 스트링이고 변환의 역이 서브 세트 자체와 동일한 조건에서 서브 세트를 필터링합니다.

가능한 모든 하위 집합 만들기로 인해 Peter의 답변보다 더 많은 메모리를 차지합니다.


이것은 첫 번째 제출물입니다-36 바이트 솔루션.

J"ACGT"eolNfqTjk_m@_JxJdTm:zhkek^Uz2

이것은 내 CJam 답변 의 정확한 번역입니다 . 나는 이것이 훨씬 작아지기를 바랐지만 번역 방법이 없기 때문에 거의 비슷한 크기로 만들었습니다 (여전히 2 바이트 작음).

여기에서 온라인으로 사용해보십시오


Uz와 같습니다 Ulz.
isaacg

1
J"ACGT"eolNf&}TzqTjk_m@_JxJdTyz사용 y의 하위하지 않은 문자열 집합을 위해 다음 필터링 z: 짧은
FryAmTheEggman

1
아, 그리고 그렇게하면 y이미 길이별로 정렬되어 있으므로 정렬 할 필요가 없습니다 . 당신은 그냥 할 수 있습니다ef...
FryAmTheEggman

5

GolfScript ( 35 34 바이트)

]{{..(;\);}%)}do{{6&}%.{4^}%-1%=}?

테스트 목적으로 사용할 수 있습니다

]{{..(;\);}%.&)}do{{6&}%.{4^}%-1%=}?

.&중복 노력을 줄이기 위해 a 를 추가합니다 .

해부

]{         # Gather string into an array and do-while...
  {        #   Map over each string in the array
    ..     #     Make a couple of copies of the string
    (;     #     Remove the first character from one of them
    \);    #     Remove the last character from the other
  }%
  )        #   Extract the last string from the array
}do        # Loop until that last string is ''
           # Because of the duplication we now have an array containing every substring
           # of the original string, and if we filter to the first occurrence of each
           # string then they're in descending order of length
{          # Find the first element in the string satisfying the condition...
  {6&}%    #   Map each character in the string to its bitwise & with 6
  .{4^}%   #   Duplicate, and map each to its bitwise ^ with 4
           #   This serves to test for A <-> T, C <-> G
  -1%=     #   Reverse and test for equality
}?

q{]{__(;\);}%~}h]{:c:i6f&_4f^W%=}=CJam. 같은 사이즈. 7 길이 이상의 입력에 대해서는 온라인 컴파일러에서 시도하지 마십시오
Optimizer


4

파이썬 3, 125 자

S=input()
l=[]
while S:
 s=_,*S=S
 while s:l+=[s]*all(x+y in"ATA CGC"for x,y in zip(s,s[::-1]));*s,_=s
print(*max(l,key=len))

엄마 봐, 색인 생성 안해! (문자열을 뒤집는 것을 제외하고는 계산되지 않습니다.)

하위 문자열을 반복하는 작업은 별표 할당을 사용하여 앞과 끝에서 문자를 제거하여 수행됩니다 . 외부 루프는로 시작하는 문자를 제거 S하고 접미사마다 s접두사 전체를 반복하여 하나씩 테스트합니다.

역 회문 테스트는 코드로 수행됩니다.

all(x+y in"ATA CGC"for x,y in zip(s,s[::-1]))

각 기호와 그 반대 문자열 대응 문자가 "AT", "TA", "CG"및 "GC"중 하나인지 확인합니다. 또한 세트 기반 솔루션이 한 문자보다 짧다는 것을 알았지 만 사용할 때 외부 parens를 요구하면 두 문자가 손실됩니다.

set(zip(s,s[::-1]))<=set(zip("ACTG","TGAC"))

이것은 여전히 ​​단축 될 수 있다고 생각합니다.

마지막으로 가장 긴 회문이 인쇄됩니다.

print(*max(l,key=len))

공백으로 구분 된 출력이 좋기를 바랍니다. 목록도 괜찮다면 별을 제거 할 수 있습니다. 대신 루프에서 실행 최대 값을 추적하려고 시도했지만 내부 루프를 목록 이해력으로 구성하여 구성하지 않고 최대 값을 직접 가져올 수 있었고 l둘 다 약간 더 길어졌습니다. 그러나 어떤 접근법이 실제로 가장 적합한 지 말하기가 어려울 정도로 근접했습니다.


이 질문에 더 유연 해지기를 원했기 때문에 묶인 솔루션에 대한 정확한 출력 형식을 지정하지 않았습니다. 솔루션이 무엇인지 분명하면 괜찮으므로 목록이 좋습니다.
Sp3000

3

J (45)

{.@(\:#&.>)@,@(('ACGT'&(|.@]-:[{~3-i.)#<)\\.)

이것은 문자열을 취하는 함수입니다.

   {.@(\:#&.>)@,@(('ACGT'&(|.@]-:[{~3-i.)#<)\\.) 'ATGGATCCG'
┌──────┐
│GGATCC│
└──────┘

설명:

{.@(\:#&.>)@,@(('ACGT'&(|.@]-:[{~3-i.)#<)\\.) 

              (                          \\.)  for each prefix of each suffix
               (                      #<)      include the argument if,
                        |.@]                      its reverse
                            -:                    is equal to
                'ACGT'&(      [{~3-i.)            the complement
            ,@                                 ravel
   (\:#&.>)@                                   sort by length of item
{.@                                            take the first one   

3

펄-59 바이트

#!perl -p
$_=$_[~!map$_[length]=$_,/((.)(?R)?(??{'$Q5'^$+.-$+}))/gi]

shebang을 하나로 계산하여 입력을 가져옵니다 STDIN.

샘플 사용법 :

$ echo CTCGCGTTTGCATAACCGTACGGGCGGAACAGTCGGCGGTGCCTCCCAGG | perl dna.pl
CCGTACGG

3

파이썬 2-177 바이트

s=raw_input()
r,l,o=range,len(s),[]
for a in[s[i:j+1]for i in r(l)for j in r(i,l)]:q=['TC GA'.index(c)-2for c in a];o+=[a if[-n for n in q][::-1]==q else'']
print max(o,key=len)

단순한 무차별 대입. 실제 "역 회문"점검은 유일한 흥미로운 부분입니다. 여기에 더 읽기 쉽게 쓰여 있습니다.

check = ['TC GA'.index(c)-2 for c in substring]
if [-n for n in check][::-1] == check:
    # substring is reverse palindromic

가능한 모든 하위 문자열 에서이 작업을 수행하고 사실이라면 목록에 넣습니다. 그것이 거짓이라면, 대신 빈 문자열을 넣습니다. 모든 검사가 완료되면 목록의 가장 긴 요소를 출력합니다. 아무것도 넣지 않고 바이트를 절약하기 때문에 빈 문자열을 사용했지만 솔루션이 없으면 프로그램이 질식하지 않습니다. 빈 줄을 출력하고 정상적으로 종료됩니다.


1
모든 것을 하나의 목록으로 이해할 수 없다면 이것은 더 짧은 것 같습니다. 나는 논리를 조금 바꿔야했지만와 함께 162를 얻었다 s=raw_input();r,l,g=range,len(s),'TGCA';print max([a for a in[s[i:j+1]for i in r(l)for j in r(i,l)]if[g[n]for n in[~g.find(c)for c in a]]==list(a)[::-1]],key=len). 또한, 문자열을 사용하는 find이상 index:
FryAmTheEggman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.