RNA 'dan Protein' ya Çeviri


18

RNA , DNA gibi genetik bilgiyi kodlayan hücrelerinde bulunan bir moleküldür. Adenin (A), sitozin (C), guanin (G) ve urasil (U) bazları ile temsil edilen nükleotitlerden oluşur . * Bir kodon , üç nükleotidin bir dizisidir.

Proteinler , saç ve tırnaklarda bulunan keratin ve kan hücrelerinde oksijen taşıyan hemoglobin gibi çok çeşitli işlevleri yerine getiren büyük moleküllerdir. Bunlar oluşur amino asitler , RNA moleküllerinde kodonu olarak kodlanır. Bazen aynı amino asit için farklı kodonlar kodlanabilir. Her amino asit genellikle tek bir harfle temsil edilir, örneğin H, histidin anlamına gelir.

Bir dizi verildiğinde ACGU, karşılık gelen protein dizisine çevirebilir misiniz?

* DNA, T'nin timin olduğu ACGT'den oluşur. DNA'dan RNA'ya transkripsiyon sırasında timinin yerini urasil alır.


Giriş

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

Çıktı

Bir dizeyi yazdırma veya döndürme yoluyla çıktı almayı seçebilirsiniz (ikinci seçenek yalnızca bir işlev durumunda kullanılabilir).

Tercüme bir başlangıç kodonu (başlamalıdır AUG, olarak temsil Mbir durdurma kodonunda) ve sonunda (biri UAA, UAGya da UGA, olarak temsil *). Girdinin geçersiz olabileceği dört durum vardır:

  • Giriş bir başlangıç ​​kodonu ile başlamıyor
  • Giriş bir durdurma kodonu ile bitmiyor
  • Girişin uzunluğu 3'ün katı değil
  • Giriş, sonunda başka bir yerde bir durdurma kodonu içerir

Tüm bu durumlarda çıktı Erroralınmalıdır. Durdurma kodonlarının aksine, başlatma kodonları dizenin başlamasından sonra görünebilir.

Aksi takdirde, her RNA'yı aşağıdaki RNA kodon tablosu aracılığıyla ilgili amino aside dönüştürmelisiniz :

* UAA UAG UGA
A GCU GCC GCA GCG
C UGU UGC
D GAU GAC
E GAA GAG
F UUU UUC
G GGU GGC GGA GGG
H CAU CAC
I AUU AUC AUA
K AAA AAG
L UUA UUG CUU CUC CUA CUG
M AUG
N AAU AAC
P CCU CCC CCA CCG
Q CAA CAG
R CGU CGC CGA CGG AGA AGG
S UCU UCC UCA UCG AGU AGC
T ACU ACC ACA ACG
V GUU GUC GUA GUG
W UGG
Y UAU UAC

... ve çevrilen dizeyi çıktılar.

Örnekler

Geçersiz durumlar:

<empty string> -> Error
AUG -> Error
UAA -> Error
AUGCUAG -> Error
AAAAAAA -> Error
GGGCACUAG -> Error
AUGAACGGA -> Error
AUGUAGUGA -> Error
AUGUUUGUUCCGUCGAAAUACCUAUGAACACGCUAA -> Error

Geçerli durumlar:

AUGUGA -> M*
AUGAGGUGUAGCUGA -> MRCS*
AUGGGUGAGAAUGAAACGAUUUGCAGUUAA -> MGENETICS*
AUGCCAGUCGCACGAUUAGUUCACACGCUCUUGUAA -> MPVARLVHTLL*
AUGCUGCGGUCCUCGCAUCUAGCGUUGUGGUUAGGGUGUGUAACUUCGAGAACAGUGAGUCCCGUACCAGGUAGCAUAAUGCGAGCAAUGUCGUACGAUUCAUAG -> MLRSSHLALWLGCVTSRTVSPVPGSIMRAMSYDS*
AUGAAAAACAAGAAUACAACCACGACUAGAAGCAGGAGUAUAAUCAUGAUUCAACACCAGCAUCCACCCCCGCCUCGACGCCGGCGUCUACUCCUGCUUGAAGACGAGGAUGCAGCCGCGGCUGGAGGCGGGGGUGUAGUCGUGGUUUACUAUUCAUCCUCGUCUUGCUGGUGUUUAUUCUUGUUUUAA -> MKNKNTTTTRSRSIIMIQHQHPPPPRRRRLLLLEDEDAAAAGGGGVVVVYYSSSSCWCLFLF*

Düzenleme: Daha fazla test örneği eklendi

puanlama

Bu kod golf, bu yüzden en az bayt kod kazanır.

Not: Moleküler biyoloji konusunda uzman değilim, bu yüzden bir şey kaçırırsam beni düzeltmekten çekinmeyin :)


1
Doğru bir çevirmen, sadece AUG ile başlayanları değil, herhangi bir dizede açık okuma çerçevesini bulabilmelidir!
Kanadalı

@canadianer Ahaha evet başlangıçta bunu düşündüm, ama açık okuma çerçevelerini getirerek (hatta tek bir dizeden birden fazla proteini çevirerek) soruyu çok karmaşık hale getirmek istemedim :)
Sp3000

Boş dize, yararlı bir test durumu olacaktır, çünkü kod çözülmüş sekansın başlayıp Mbittiği test için bazı yaklaşımları kıracaktır *.
Peter Taylor

@PeterTaylor Birkaç kısa test vakasıyla birlikte eklendi :)
Sp3000

1
Gerçek bir acı olmak istiyorsan, RNA yerine DNA kullanabilirsin, böylece geriye doğru okuma çerçeveleri de var.
user137

Yanıtlar:


6

CJam ( 97 93 92 91 bayt)

q"GACU"f#3/{4b"GGEDAAVVRSKNTTMIRRQHPPLLWC*YSSLF"{_s"MW""I*"er}%=}%s_'*/(1<"M"=*Qa=\"Error"?

Bu, küçük bir tweaked hash işlevine sahip GolfScript çözümümün bir limanıdır, çünkü CJam'ın GolfScript'ten ödünç almadığı bir şey, dizeleri tamsayı dizileri olarak ele alıyor.

Optimizer'ın önerileri sayesinde 6 bayt kaydedildi (denediğimi ve işe yaramadığımı düşündüğüm bir şeyden iki bayt dahil) - ha.


1
q"GACU"f#3/{4b"GGEDAAVVRSKNTTMIRRQHPPLLWC*YSSLF"{_s"MW""I*"er}%=}%s_'*/(1<"M"=*Q="Error"@?- 90
Doktor

@Optimizer, bunlardan bazıları bir gelişme gibi görünüyor. Ancak, bir çalışma zamanı hatası verir ve Qyerine değil [Q], sadece yanlıştır.
Peter Taylor

1. kod yorumlarda birden çok satır yayıldığında, kodu doğru kopyalamamışsanız, satır sonu garip bir unicode karakter alır. Kodu kendiniz manuel olarak yazmanız gerekecektir. Mantığı Bkz 2. Bundan dolayısıyla doğru işe değiştirilmiş [Q]için Qdeğişim doğrudur.
Optimizer

@Optimizer, test davasını deneyinAUGUAGUGA
Peter Taylor

1
Ah tamam. Hala [Q]->Qa
Optimizer

10

JavaScript (ES6) 167 177 karakter olarak UTF8 olarak kodlanmış 167 177 bayt

... umarım herkes mutlu olur.

Edit Aslında, çok kısa son blok için özel bir dava gerek yok. Son 2 (veya 1) karakter eşlenmezse, sonuç dizesi '*' ile bitmez ve yine de hata verir.

F=s=>/^M[^*]*\*$/.test(s=s.replace(/.../g,x=>
"KNKNTTTTRSRSIIMIQHQHPPPPRRRRLLLLEDEDAAAAGGGGVVVV*Y*YSSSS*CWCLFLF"
[[for(c of(r=0,x))r=r*4+"ACGU".search(c)]|r]))?s:'Error'

Açıklaması

Üçüzdeki her karakter 4 değere sahip olabilir, bu nedenle tam olarak 4 ^ 3 == 64 üçüz vardır. C işlevi her üçlüyü 0 ile 63 arasında bir sayı ile eşleştirir. Giriş karakterleri yalnızca ACGU olduğundan hata kontrolüne gerek yoktur.

C=s=>[for(c of(r=0,s))r=r*4+"ACGU".search(c)]|r

Her üçüz, tek bir karakterle tanımlanan bir amino asitle eşleşir. Bunu 64 karakterlik bir dizede kodlayabiliriz. Dizeyi edinmek için Codon Map ile başlayın:

zz=["* UAA UAG UGA","A GCU GCC GCA GCG","C UGU UGC","D GAU GAC","E GAA GAG"
,"F UUU UUC","G GGU GGC GGA GGG","H CAU CAC","I AUU AUC AUA","K AAA AAG"
,"L UUA UUG CUU CUC CUA CUG","M AUG","N AAU AAC","P CCU CCC CCA CCG","Q CAA CAG"
,"R CGU CGC CGA CGG AGA AGG","S UCU UCC UCA UCG AGU AGC","T ACU ACC ACA ACG"
,"V GUU GUC GUA GUG","W UGG","Y UAU UAC"]
a=[],zz.map(v=>v.slice(2).split(' ').map(x=>a[C(x)]=v[0])),a.join('')

... "KNKNTTTTRSRSIIMIQHQHPPPPRRRRLLLLEDEDAAAAGGGGVVVV * Y * YSSSS * CWCLFLF" ediniliyor

Böylece giriş dizesini tarayabilir ve 0..63 kodunu ve koddan amino asit karakterini elde etmek için C fonksiyonunun aynı mantığını kullanabiliriz. Replace işlevi giriş dizesini 3 karakter bloğuna böler ve sonunda yönetilmeyen 1 veya 2 karakter bırakır (bu geçersiz bir sonuç dizesi verir, '*' ile bitmez).

Sonunda, kodlanmış dizenin regexp kullanarak geçerli olup olmadığını kontrol edin: 'M' ile başlamalı, '*' içermemeli ve '*' ile bitmelidir

FireBug / FireFox konsolunda test et

;['AUGCUAG','GGGCACUAG','AUGAACGGA','AUGUAGUGA','AAAAAAA',
'AUGUUUGUUCCGUCGAAAUACCUAUGAACACGCUAA',
'AUGAGGUGUAGCUGA','AUGCCAGUCGCACGAUUAGUUCACACGCUCUUGUAA',
'AUGCUGCGGUCCUCGCAUCUAGCGUUGUGGUUAGGGUGUGUAACUUCGAGAACAGUGAGUCCCGUACCAGGUAGCAUAAUGCGAGCAAUGUCGUACGAUUCAUAG']
.forEach(c=>console.log(c,'->',F(c)))

Çıktı

AUGCUAG -> Error
GGGCACUAG -> Error
AUGAACGGA -> Error
AUGUAGUGA -> Error
AAAAAAA -> Error
AUGUUUGUUCCGUCGAAAUACCUAUGAACACGCUAA -> Error
AUGAGGUGUAGCUGA -> MRCS*
AUGCCAGUCGCACGAUUAGUUCACACGCUCUUGUAA -> MPVARLVHTLL*
AUGCUGCGGUCCUCGCAUCUAGCGUUGUGGUUAGGGUGUGUAACUUCGAGAACAGUGAGUCCCGUACCAGGUAGCAUAAUGCGAGCAAUGUCGUACGAUUCAUAG -> MLRSSHLALWLGCVTSRTVSPVPGSIMRAMSYDS*

İyi fikir! Sadece bunu yapmayı düşünüyordum. Beni dövüyorsun!
Doktor

8

C, 190 bayt (işlev)

f(char*x){int a=0,i=0,j=0,s=1;for(;x[i];i%3||(s-=(x[j++]=a-37?a-9?"KNRSIITTEDGGVVAA*Y*CLFSSQHRRLLPP"[a/2]:77:87)==42,x[j]=a=0))a=a*4+(-x[i++]/2&3);puts(*x-77||i%3||s||x[j-1]-42?"Error":x);}

199 194 bayt (programı)

a,i,j;char x[999];main(s){for(gets(x);x[i];i%3||(s-=(x[j++]=a-37?a-9?"KNRSIITTEDGGVVAA*Y*CLFSSQHRRLLPP"[a/2]:77:87)==42,x[j]=a=0))a=a*4+(-x[i++]/2&3);puts((*x-77||i%3||s||x[j-1]-42)?"Error":x);}

Karma formülünü geliştirerek birkaç bayt kaydetti.

İşte eğlenceli bir test örneği:

AUGUAUCAUGAGCUCCUUCAGUGGCAAAGACUUGACUGA --> MYHELLQWQRLD* 

açıklama

Harflerin üçlüsü bir taban 4 numarasına dönüştürülür. Her harf aşağıdaki gibi özetlenir.

x[i]       ASCII code       Hashed to (-x[i]/2&3) 
A        64+ 1  1000001            00   
G        64+ 7  1000111            01
U        64+21  1010101            10   
C        64+ 3  1000011            11

Bu aralıkta bir sayı verir 0..63. Şimdi fikir edc65 ve Optimizer tarafından kullanılanlara benzer bir arama tablosu kullanmaktır. Ancak, karma, G ve A'nın yan yana ve U ve C'nin yan yana olacağı şekilde tasarlanmıştır.

Https://en.wikipedia.org/wiki/Genetic_code#RNA_codon_table adresindeki tabloya baktığımızda, bu şekilde sıralanan harfler ile genellikle son bitin göz ardı edilebileceğini görüyoruz. İki özel durum dışında yalnızca 32 karakterlik bir arama tablosu gereklidir.

İlk iki harfe ve karşılık gelen amino asitlere bakın (burada 3. harf G / A ve 3. harf U / C'dir). 32 karakterlik tabloya uymayan iki özel durum için düzeltmeler kodlanmıştır.

     A/G U/C          A/G U/C            A/G U/C         A/G U/C  
AAX> K   N       AGX> R   S         AUX> I   I      ACX> T   T
GAX> E   D       GGX> G   G         GUX> V   V      GCX> A   A
UAX> *   Y       UGX> *   C         UUX> L   F      UCX> S   S
CAX> Q   H       CGX> R   R         CUX> L   L      CCX> P   P

Corrections for special cases (where last bit cannot be ignored)
AUG 001001=9 -->  M
UGG 100101=37-->  W

Yorumlanan kod

Golf halindeki versiyonda, i%3kod forbraketin artış konumundadır , ancak yorumlanan kodda daha okunabilir bir konuma taşınır.

a,i,j;char x[999];                                                             //Array x used for storing both input and output. i=input pointer, j=output pointer.
main(s){                                                                       //s is commandline string count. if no arguments, will be set to zero. Will be used to count stops.
  for(gets(x);x[i];)                                                           //Get a string, loop until end of string (zero byte) found
    a=a*4+(-x[i++]/2&3),                                                       //Hash character x[i] to a number 0-3. leftshift any value already in a and add the new value. Increment i.
    i%3||(                                                                     //if i divisible by 3,
      s-=(x[j++]=a-37?a-9?"KNRSIITTEDGGVVAA*Y*CLFSSQHRRLLPP"[a/2]:77:87)==42,  //lookup the correct value in the table. for special cases a=24 and a=32 map to 'M' and 'W' (ASCII 77 and 87). If character is '*' (ASCII42) decrement s.   
      x[j]=a=0                                                                 //reset a to 0. clear x[j] to terminate output string.                                                     
    );   
  puts((*x-77||i%3||s||x[j-1]-42)?"Error":x);                                  //if first character not M or i not divisible by 3 or number of stops not 1 or last character not * print "Error" else print amino acid chain.
}

Keşke bir tane olsaydı O! MGENETICS*Yine de bir test örneği ekledim , çünkü yapabileceğim en tematik kelime: P
Sp3000

6

CJam, 317 121 104 bayt

q3/{{"ACGU"#}%4b"KN T RS IIMI QH P R L ED A G V *Y S *CWC LF"S/{_,4\/*}%s=}%_('M=\)'*=\'*/,1=**\"Error"?

Bu yine de golf edilebilir.

Eşleme mekanizması edc65'in cevabında kullanılan mekanizma ile güncellendi . Ben kendi başıma gelsem de, beni dövdü :)

GÜNCELLEME : İçindeki deseni gözlemleyerek kodon tablosu haritasını kısaltın.

Buradan çevrimiçi deneyin


Girdi boş dize ise bu kesilir.
Peter Taylor

@PeterTaylor Yanıt gönderildikten sonra önerinize eklenen bir kural;). Kodu yakında güncelleyeceğim.
Optimizer

1
Eklenen bir kural değildi, kurallar tarafından örtük olarak gerekli olan bir test durumuydu.
Peter Taylor

3

GolfScript (103 bayt)

{)7&2/}%3/{4base'GGEDAAVVRSKNTTMIRRQHPPLLWC*YSSLF'{..'MW'?'I*'@),+=}%=}%''+.'*'/(1<'M'=*['']=*'Error'or

Çevrimiçi demo (NB, en büyük iki test durumunu içermez, çünkü 15 saniye içinde çalışması gerekir).

teşrih

Steve Verrill'in sanal alanda işaret ettiği gibi, arama tablosu 32 öğeye ve iki özel duruma azaltılabilir. Özel durumların her ikisinin de sadece bir kez oluşan karakterleri ( Mve Wsırasıyla) içerdiği ve karakterlerin 4 basamağa doğru eşleştirilmesiyle, yinelenerek 32 öğeden tam 64 elemanlı arama tablosunun oluşturulması mümkündür. -ve- tr:

'GGEDAAVVRSKNTTMIRRQHPPLLWC*YSSLF'  # 32-element lookup table
{                                   # Map over the 32 elements...
  .                                 #   Duplicate the element
  .'MW'?'I*'@),+=                   #   Apply tr/MW/I*/ to the duplicate
}%

Sonra kodu çözdükten sonra, doğrulama birçok yaklaşıma izin verir. Bulduğum en kısa şey

.'*'/       # Duplicate and split the copy around '*' retaining empty strings
(1<'M'=*    # Pull out the first string from the split (guarantee to exist even if input is
            # the empty string); if it starts with 'M' leave the rest of the split intact;
            # otherwise reduce it to the empty array
['']=       # Check whether we have ['']. If so, the split produced [prefix ''] where
            # prefix begins with 'M'. Otherwise we want an error.
*           # If we have an error case, reduce the original decoded string to ''
'Error'or   # Standard fallback mechanism

1 bayt. Meydan okuma kabul edildi!
Doktor

@Optimizer, CJam'a doğrudan bir çeviri, çok sayıda ilgili yerleşik olduğu için birkaç bayt kazandıracaktır.
Peter Taylor

Benim hash fonksiyonu 57 bayt uzunluğunda, seninki 52 iken. Bu yüzden sadece en fazla 5 bayt tasarruf görebiliyorum ...
Optimizer

Kum havuzundaki yorumumun yararlı olduğuna sevindim. MGeçerli bir başlangıç ​​testi yapmak için özel durumlardan biri olmanın mümkün olabileceğini umuyordum , ancak bu şekilde işe yaramadı. Bu dizede hala 8 çift özdeş harf var. Acaba küçük harfler olarak sıkıştırılıp sıkıştırılamayacaklarını merak ediyorum: g-->GG a-->AAvb. 8 karakterin altında dekompresyon sağlanabilirse bu işe yarayacaktır.
Level River St

1

Python, 473 bayt

t={'U(A[AG]|GA)':'*','GC.':'A','UG[UC]':'C','GA[UC]':'D','GA[AG]':'E','UU[UC]':'F','GG.':'G','CA[UC]':'H','AU[UCA]':'I','AA[AG]':'K','(UU[AG]|CU.)':'L','AUG':'M','AA[UC]':'N','CC.':'P','CA[AG]':'Q','(CG.|AG[AG])':'R','(UC.|AG[UC])':'S','AC.':'T','GU.':'V','UGG':'W','UA[UC]':'Y'}
import re
i=raw_input()
a=''
for x in[i[y:y+3]for y in range(0,len(i),3)]:
 a+=[t[u]for u in t.keys()if re.match(u, x)][0]
print["Error",a][all((a[0]+a[-1]=="M*",len(i)%3==0,not"*"in a[1:-1]))]

1

Python 2, 370 358 354 bayt

Bu, sıkıştırma olmadan çok basit bir ileri yaklaşımdır, sadece bilgileri oldukça yoğun bir şekilde paketlemeye çalışır:

s=lambda x:x and[x[:3]]+s(x[3:])or[]
def f(I):O=''.join(d*any(0==x.find(p)for p in e)for x in s(I)for d,e in zip('*ACDEFGHIKLMNPQRSTVWY',map(s,'UAAUAGUGA,GC,UGUUGC,GAUGAC,GAAGAG,UUUUUC,GG,CAUCAC,AUUAUCAUA,AAAAAG,UUAUUGCU,AUG,AAUAAC,CC,CAACAG,AGAAGGCG,AGUAGCUC,AC,GU,UGG,UAUUAC'.split(','))));return['Error',O][len(I)%3==0==len(O)-O.find('*')-(O[0]=='M')]

Düzenleme: xnor'ın önerisi üzerine birkaç karakter traş edildi.


Ben sözyineli olarak daha kısa yazabilirsiniz inanıyorum s=lambda x:x and[x[:3]]+s(x[3:]).
xnor

@xnor Harika, bunu düşünmedim. Bu tam olarak çalışmaz, çünkü özyinelemenin sonunda boş bir liste değil, boş bir dize çıkarır. Ama dört karakter daha çalıştırabilirim. Teşekkürler!
Emil

1

Scala (317 karakter)

def g(c:Char)="ACGU"indexOf c;def h(s:String,i:Int)=g(s(i))*16+g(s(i+1))*4+g(s(i+2));def p(a:Int)=a!=48&&a!=50&&a!=56;def f(s:String)=if(s.length%3!=0||h(s,0)!=14||p(h(s,s.length-3)))"Error"else{var r="";for(i<-0 to s.length-3 by 3)r+="KNKNTTTTRSRSIIMIQHQHPPPPRRRRLLLLEDEDAAAAGGGGVVVV*Y*YSSSS*CWCLFLF"charAt h(s,i);r}

Ana işlevi f. Tabii ki, daha iyi bir seçim bir dönmek olacaktır Option[String].


0

JavaScript (ES6), 143 bayt

s=>/^M\w*\*$/.test(s=s.replace(/.../g,c=>"PVLVLHDVLGRGRAPGR*KYNVL*KTSTSGRTSILIFYNMLR*SCTSRWEQDHIFEQPAPASC.A"[parseInt(c,36)%128%65]))?s:'Error'

Çevrimiçi deneyin!

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.