Maior substrato de DNA palindrômico reverso

11

Como você deve saber, no DNA existem quatro bases - adenina ( A), citosina ( C), guanina ( G) e timina ( T). Tipicamente Aligações com Te Cligações com G, formando os "degraus" da estrutura de hélice dupla de ADN .

Definimos o complemento de uma base para ser a base à qual ele se liga - ou seja, o complemento de Aé T, o complemento de Té A, o complemento de Cé Ge o complemento de Gé C. Também podemos definir o complemento de uma sequência de DNA para ser a sequência com cada base complementada, por exemplo, o complemento de GATATCé CTATAG.

Por causa da estrutura do DNA de fita dupla, as bases em uma fita são complementares às bases na outra fita. No entanto, o DNA tem uma direção e a transcrição do DNA ocorre em direções opostas nas duas cadeias. Portanto, os biólogos moleculares costumam se interessar pelo complemento inverso de uma cadeia de DNA - literalmente, o inverso do complemento da cadeia.

Para estender nosso exemplo anterior, o complemento inverso de GATATCé CTATAGpara trás, então GATATC. Como você deve ter notado, neste exemplo o complemento reverso é igual à string original - chamamos essa string de palíndromo reverso . *

Dada uma sequência de DNA, você consegue encontrar a substring mais longa que é um palíndromo reverso?

* Uso o termo "palíndromo reverso", extraído de Rosalind , para diferenciar do significado usual de palíndromo.


Entrada

A entrada será uma única sequência que consiste apenas nos caracteres ACGTem maiúsculas. Você pode escrever uma função ou um programa completo para esse desafio.

Resultado

Você pode optar por imprimir via impressão ou retorno (a última opção está disponível apenas no caso de uma função).

Seu programa deve gerar a substring palindrômica reversa mais longa da sequência de entrada, se houver uma solução exclusiva. Se existirem várias soluções, você poderá produzir qualquer uma delas ou todas (sua escolha). As duplicatas são válidas se você optar por produzir todas elas.

A entrada é garantida para ter uma solução de pelo menos comprimento 2.

Exemplo trabalhado

ATGGATCCG -> GGATCC

O complemento reverso de GGATCCé ele próprio ( GGATCC --complement--> CCTAGG --reverse--> GGATCC), assim GGATCCcomo um palíndromo reverso. GATCtambém é um palíndromo reverso, mas não é o mais longo.

Casos de teste

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

Pontuação

Isso é código de golfe, então a solução com o menor número de bytes vence.

Sp3000
fonte
Teria sido melhor se imprimir todos eles tivesse algum tipo de bônus.
Optimizer
@Optimizer não está imprimindo apenas o mais longo e mais difícil do que imprimir todos eles?
Trichoplax
Ou você quer dizer imprimir todos os mais longos?
Trichoplax
@githubphagocyte sim, seu segundo comentário.
Optimizer

Respostas:

6

Pitão, 37 36 28 24 bytes

ef&}TzqmaCd6T_mx4aCk6Tyz

Combinando as dicas de FryAmTheEggman e o truque de verificação de palíndromo reverso de Peter, esta é uma versão super curta.

No entanto, isso só funciona com o Pyth 3.0.1, que você pode baixar deste link e executar como

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

(somente linux bash. Nas janelas, pressione Enter em vez de <<< e digite a entrada)


Esta é a minha submissão anterior - solução de 28 bytes

J"ACGT"ef&}TzqTjk_m@_JxJdTyz

Obrigado a FryAmTheEggman por esta versão. Este cria todos os subconjuntos possíveis da cadeia de DNA de entrada, filtra os subconjuntos com a condição de que o subconjunto seja uma subcadeia de entrada e o inverso da transformação seja igual ao próprio subconjunto.

Devido a toda a criação possível de subconjuntos, isso ocupa ainda mais memória do que a resposta de Peter.


Esta é a minha primeira submissão - solução de 36 bytes.

J"ACGT"eolNfqTjk_m@_JxJdTm:zhkek^Uz2

Esta é a tradução exata da minha resposta CJam . Eu esperava que isso fosse muito menor, mas a falta de método de tradução tornou o tamanho quase semelhante (ainda 2 bytes menor)

Experimente online aqui

Optimizer
fonte
Uzé equivalente a Ulz.
Isaacg
1
J"ACGT"eolNf&}TzqTjk_m@_JxJdTyzUsando ypara subconjuntos e depois filtrando as cordas que não são substrings de zé mais curto :)
FryAmTheEggman
1
Ah, e se você fizer isso, não precisará classificar porque yjá está classificado por comprimento. Você pode simplesmente fazeref...
FryAmTheEggman
5

GolfScript ( 35 34 bytes)

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

Para fins de teste, você pode querer usar

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

que adiciona um .&para reduzir o esforço duplicado.

Dissecação

]{         # 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
}?
Peter Taylor
fonte
q{]{__(;\);}%~}h]{:c:i6f&_4f^W%=}=em CJam. Mesmo tamanho. Não tente no compilador on-line para algo maior que 7 entradas de comprimento
Optimizer
4

CJam, 39 38 bytes

Estou certo de que isso pode ser jogado ainda mais ...

q:Q,,_m*{~Q<>}%{,~}${_"ACGT"_W%erW%=}=

Retira a cadeia de DNA de STDIN e gera o DNA palindrômico reverso mais longo para STDOUT

Experimente online aqui

(Explicação em breve) (Salvo 1 byte graças a Peter)

Optimizer
fonte
4

Python 3, 125 caracteres

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))

Olha ma, sem indexação! (Bem, exceto para reverter a string, isso não conta.)

A iteração sobre as substrings é feita retirando os caracteres da frente e do final usando a atribuição com estrela . O loop externo remove caracteres para o início Se, para cada sufixo, faz um sloop em todos os prefixos dele, testando-os um por um.

O teste do palíndromo reverso é feito pelo código

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

que verifica se cada símbolo e sua contraparte de cadeia reversa são "AT", "TA", "CG" e "GC". Também achei que uma solução baseada em conjunto era um caractere menor, mas perde dois caracteres ao exigir parênteses externos quando usada.

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

Ainda parece que pode ser reduzido.

Finalmente, o palíndromo mais longo é impresso.

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

Espero que as saídas separadas por espaço estejam OK. Se uma lista também estiver boa, a estrela pode ser removida. Em vez disso, tentei rastrear o máximo de corrida no loop, além de colocar os loops internos em uma lista de compreensão, para que eu pudesse pegar o máximo diretamente sem construir l, e os dois ficaram um pouco mais longos. Mas, foi suficientemente próximo que é difícil dizer qual abordagem é realmente a melhor.

xnor
fonte
Queria ser mais flexível com esta pergunta, para não especificar um formato exato de saída para soluções vinculadas. Se estiver claro quais são as soluções, tudo bem, então uma lista está correta.
Sp3000
3

J (45)

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

Esta é uma função que aceita uma string:

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

Explicação:

{.@(\:#&.>)@,@(('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   
marinus
fonte
3

Perl - 59 bytes

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

Contando o shebang como um, a entrada é retirada STDIN.

Uso da amostra:

$ echo CTCGCGTTTGCATAACCGTACGGGCGGAACAGTCGGCGGTGCCTCCCAGG | perl dna.pl
CCGTACGG
primo
fonte
3

Python 2 - 177 bytes

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)

Força bruta simples. A verificação "palindrômica reversa" real é a única parte interessante. Aqui está escrito de forma mais fácil:

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

Faço isso em todas as subseqüências possíveis e as coloco em uma lista, se for verdade. Se for falso, eu coloquei uma string vazia. Quando todas as verificações são feitas, produzo o elemento mais longo da lista. Eu usei uma string vazia porque economiza bytes e não coloca nada, mas também significa que o programa não engasgará se não houver solução. Ele gera uma linha vazia e sai normalmente.

undergroundmonorail
fonte
1
Isso parece ser mais curto se você agrupar tudo em uma única lista de compreensão. Eu tive que mudar um pouco a lógica, mas consegui 162 com 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). Além disso, para cordas, usar findmais de index:)
FryAmTheEggman