En uzun ters palindromik DNA alt dizisi


11

Bildiğiniz gibi, DNA'da dört baz vardır - adenin ( A), sitozin ( C), guanin ( G) ve timin ( T). Tipik Aile bağlar Tve Cile bağlar Gve "basamakları" oluşturan DNA çift sarmal yapısı .

Bu tanımlar tamamlayıcı yani tamamlayıcı - bir baz ile o bağları temel olduğu Aolduğu T, tamamlayıcısı Tolan A, tamamlayıcısı Colan Gve tamamlayıcı Golan C. Ayrıca örneğin tamamlayıcı tamamlanmaktadır, her baz ile dize için bir DNA dizisinin tamamlayıcı tanımlayabilir GATATCIS CTATAG.

DNA'nın çift sarmallı yapısı nedeniyle, bir sarmal üzerindeki bazlar, diğer sarmal üzerindeki bazları tamamlayıcıdır. Bununla birlikte DNA'nın bir yönü vardır ve DNA transkripsiyonu iki şerit üzerinde zıt yönlerde meydana gelir. Bu nedenle moleküler biyologlar genellikle bir DNA dizisinin ters komplemanı ile ilgilenirler - kelimenin tam anlamıyla ipin komplemanının tersi.

Daha önceki örnekte uzatmak için, ters tamamlayıcı GATATColan CTATAG, yani geriye GATATC. Fark etmiş olabileceğiniz gibi, bu örnekte ters tamamlayıcı orijinal dizeye eşittir - böyle bir dizeye ters palindrom diyoruz . *

Bir DNA dizisi verildiğinde, ters palindrom olan en uzun alt dizeyi bulabilir misiniz?

* Palindromun olağan anlamından ayırt etmek için Rosalind'den alınan "ters palindrom" terimini kullanıyorum .


Giriş

Girdi, yalnızca ACGTbüyük harf karakterlerden oluşan tek bir dize olacaktır . Bu zorluk için bir işlev veya tam bir program yazabilirsiniz.

Çıktı

Çıktıyı yazdırma veya geri gönderme yoluyla seçebilirsiniz (ikinci seçenek yalnızca bir işlev durumunda kullanılabilir).

Benzersiz bir çözüm varsa, programınız giriş dizesinin en uzun ters palindromik alt dizesini çıkarmalıdır. Birden fazla çözüm varsa, bunlardan herhangi birini veya tümünü (seçiminiz) çıktı alabilirsiniz. Hepsini çıkarmayı seçerseniz, kopyalar tamamdır.

Girişin en az 2 uzunluğunda bir çözeltisi olması garanti edilir.

Çalışılan örnek

ATGGATCCG -> GGATCC

Ters tamamlayıcı GGATCCkendisi ( GGATCC --complement--> CCTAGG --reverse--> GGATCC), yani GGATCCters palindromdur. GATCaynı zamanda bir ters palindomdur, ancak en uzun olanı değildir.

Test senaryoları

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

puanlama

Bu kod golf, bu yüzden en az bayt içindeki çözüm kazanır.


Hepsini yazdırmanın bir çeşit bonusu olsaydı daha güzel olurdu.
Doktor

@Optimizer hepsini yazdırmaktan daha uzun süre daha zor değil mi?
trichoplax

Yoksa en uzun olanların hepsini yazdırmak mı demek istediniz?
trichoplax

@githubphagocyte evet, ikinci yorumunuz.
Doktor

Yanıtlar:


6

Pyth, 37 36 28 24 bayt

ef&}TzqmaCd6T_mx4aCk6Tyz

FryAmTheEggman'ın ipuçlarını ve Peter'ın ters palindrom kontrol numarasını birleştiren bu süper kısa bir versiyon.

Ancak, bu yalnızca bu bağlantıdan indirip aşağıdaki gibi çalıştırabileceğiniz Pyth 3.0.1 ile çalışır

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

(yalnızca linux bash. Pencerelerde <<< yerine Enter tuşuna basın ve ardından girişi yazın)


Bu benim önceki gönderim - 28 bayt çözüm

J"ACGT"ef&}TzqTjk_m@_JxJdTyz

Bu sürüm için FryAmTheEggman'a teşekkürler. Bu, giriş DNA dizesinin tüm olası alt kümelerini oluşturur, alt kümenin bir girdi alt dizesi olması ve dönüştürmenin tersinin alt kümenin kendisine eşit olması koşuluyla alt kümeleri filtreler.

Tüm olası altküme oluşturma nedeniyle, bu Peter'ın cevabından daha fazla bellek gerektirir.


Bu benim ilk gönderim - 36 baytlık çözüm.

J"ACGT"eolNfqTjk_m@_JxJdTm:zhkek^Uz2

Bu benim CJam cevabımın tam çevirisidir . Bu çok daha küçük olacağını umuyordum ama çeviri yönteminin eksikliği neredeyse benzer bir boyut kazandı (yine de 2 bayt daha küçük)

Buradan çevrimiçi deneyin


Uzeşittir Ulz.
isaacg

1
J"ACGT"eolNf&}TzqTjk_m@_JxJdTyzyz
Alt

1
Oh, ve bunu yaparsanız, sıralamaya gerek yoktur çünkü yzaten uzunluğa göre sıralanmıştır. Sadece yapabilirsinef...
FryAmTheEggman

5

GolfScript ( 35 34 bayt)

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

Test amacıyla kullanmak isteyebilirsiniz

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

bu .&da yinelenen çabayı azaltmak için a ekler .

teşrih

]{         # 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. Aynı boyutta. 7 uzunluk girişinden daha büyük bir şey için çevrimiçi derleyicide denemeyin
Optimizer

4

CJam, 39 38 bayt

Eminim bu daha fazla golf olabilir ...

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

DNA dizesini STDIN'den alır ve en uzun ters palindromik DNA'yı STDOUT'a verir

Buradan çevrimiçi deneyin

(Yakında açıklama) (Peter sayesinde 1 bayt kaydedildi)


4

Python 3, 125 karakter

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

Bak anne, indeksleme yok! (Dizeyi tersine çevirmek dışında sayılmaz.)

Alt dizeler üzerinde yineleme işlemi, önden ve sondan karakterlerin çıkarılmasıyla yapılır. yıldızlı atama . Dış döngü, başlangıcı için karakterleri kaldırır Sve her bir sonek için stüm öneklerinin üzerine döner ve bunları tek tek test eder.

Ters palindromun testi kod tarafından yapılır

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

bu, her sembolün ve ters dize karşılığının "AT", "TA", "CG" ve "GC" den biri olup olmadığını kontrol eder. Ayrıca bir karakter daha kısa bir set tabanlı çözüm buldum, ancak kullanıldığında dış parens gerektiren iki karakter kaybeder.

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

Bu hala kısaltılabilir gibi geliyor.

Son olarak, en uzun palindrom yazdırılır.

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

Umarım boşlukla ayrılmış çıktılar iyi olur. Bir liste de iyi olursa, yıldız kaldırılabilir. Bunun yerine döngüdeki çalışan max'ı izlemeyi denedim ve iç döngüleri bir liste kavrayışına tıkıştırdım, böylece max'ı inşa etmeden doğrudan alabilirdim lve her ikisi de biraz daha uzun çıktı. Ancak, hangi yaklaşımın aslında en iyi olduğunu söylemek zor.


Bu soru ile daha esnek olmak istedim, bu yüzden bağlı çözümler için kesin bir çıktı biçimi belirtmedim. Çözümlerin ne olduğu açıksa, o zaman sorun değil, bu yüzden bir liste tamam.
Sp3000

3

J (45)

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

Bu bir dize alan bir işlevdir:

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

Açıklama:

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

Perl - 59 bayt

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

Mesele bir olarak sayılır, girdi alınır STDIN.

Örnek kullanım:

$ echo CTCGCGTTTGCATAACCGTACGGGCGGAACAGTCGGCGGTGCCTCCCAGG | perl dna.pl
CCGTACGG

3

Python 2-177 bayt

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)

Basit kaba kuvvet. Gerçek "ters palindromik" kontrol tek ilginç kısımdır. Burada daha okunabilir bir şekilde yazılmıştır:

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

Bunu her olası alt dize üzerinde yapıyorum ve doğruysa bir listeye koyuyorum. Yanlışsa, bunun yerine boş bir dize koydum. Tüm kontroller yapıldığında listenin en uzun elemanını çıkarıyorum. Boş bir dize kullandım çünkü hiçbir şey koymadan baytları kurtarıyor, ama aynı zamanda çözüm yoksa programın boğulmayacağı anlamına geliyor. Boş bir satır çıkarır ve incelikle çıkar.


1
Eğer her şeyi tek bir liste halinde anlayamazsanız bu daha kısa görünüyor. Mantığı biraz değiştirmek zorunda kaldım, ama 162 ile aldım 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). Ayrıca, dizeler için, findüzerinde kullanın index:)
FryAmTheEggman
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.