Dịch RNA thành protein


18

RNA , giống như DNA, là một phân tử được tìm thấy trong các tế bào mã hóa thông tin di truyền. Nó bao gồm các nucleotide , được đại diện bởi các cơ sở adenine (A), cytosine (C), guanine (G) và uracil (U). * Một codon là một chuỗi gồm ba nucleotide.

Protein là các phân tử lớn thực hiện một loạt các chức năng, chẳng hạn như keratin được tìm thấy trong tóc và móng tay và hemoglobin mang oxy trong các tế bào máu. Chúng được tạo thành từ các axit amin , được mã hóa dưới dạng codon trong các phân tử RNA. Đôi khi các codon khác nhau có thể mã hóa cho cùng một axit amin. Mỗi axit amin thường được đại diện bởi một chữ cái, ví dụ H là viết tắt của histidine.

Đưa ra một chuỗi ACGU, bạn có thể dịch nó thành chuỗi protein tương ứng không?

* DNA bao gồm ACGT, trong đó T là thymine. Trong quá trình phiên mã DNA thành RNA, thymine được thay thế bằng uracil.


Đầu vào

Đầu vào sẽ là một chuỗi duy nhất chỉ bao gồm các ký tự ACGUin hoa. Bạn có thể viết một chức năng hoặc một chương trình đầy đủ cho thử thách này.

Đầu ra

Bạn có thể chọn xuất qua in hoặc trả về một chuỗi (lựa chọn sau chỉ khả dụng trong trường hợp hàm).

Dịch nên bắt đầu tại một codon bắt đầu ( AUG, được biểu thị dưới dạng M) và kết thúc tại một codon dừng (một trong UAA, UAGhoặc UGA, được biểu thị là *). Có bốn trường hợp đầu vào có thể không hợp lệ:

  • Đầu vào không bắt đầu bằng một codon bắt đầu
  • Đầu vào không kết thúc với một codon dừng
  • Độ dài của đầu vào không phải là bội số của 3
  • Đầu vào chứa một codon dừng ở một nơi khác ngoài cuối

Trong tất cả các trường hợp này, Errornên được xuất ra. Lưu ý rằng, không giống như các codon dừng, các codon bắt đầu có thể xuất hiện sau khi bắt đầu chuỗi.

Mặt khác, bạn nên chuyển đổi từng codon thành axit amin tương ứng thông qua bảng codon RNA sau :

* 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

... và xuất chuỗi dịch.

Ví dụ

Các trường hợp không hợp lệ:

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

Các trường hợp hợp lệ:

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

Chỉnh sửa: Đã thêm nhiều trường hợp kiểm tra

Chấm điểm

Đây là mã golf, vì vậy mã trong ít byte nhất sẽ thắng.

Lưu ý: Tôi không phải là chuyên gia về sinh học phân tử, vì vậy hãy sửa tôi nếu tôi nói sai bất cứ điều gì :)


1
Một dịch giả thích hợp sẽ có thể tìm thấy khung đọc mở trong bất kỳ chuỗi nào, không chỉ các khung bắt đầu bằng AUG!
Canada

@canadianer Ahaha yeah Ban đầu tôi đã xem xét điều đó, nhưng tôi không muốn làm cho câu hỏi trở nên quá phức tạp bằng cách đưa vào các khung đọc mở (hoặc thậm chí dịch nhiều protein từ một chuỗi) :)
Sp3000

Chuỗi rỗng sẽ là một trường hợp thử nghiệm hữu ích, bởi vì nó sẽ phá vỡ một số cách tiếp cận để kiểm tra rằng chuỗi được giải mã bắt đầu bằng Mvà kết thúc bằng *.
Peter Taylor

@PeterTaylor Đã thêm, cùng với một vài trường hợp thử nghiệm ngắn khác :)
Sp3000

1
Nếu bạn muốn trở thành một nỗi đau thực sự, bạn có thể sử dụng DNA thay vì RNA, do đó bạn cũng có khung đọc ngược.
dùng137

Câu trả lời:


6

CJam ( 97 93 92 91 byte)

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

Đây là một cổng của giải pháp GolfScript của tôi với hàm băm được điều chỉnh một chút bởi vì thật ngạc nhiên, một điều mà CJam đã không mượn từ GolfScript là coi các chuỗi là các mảng số nguyên.

6 byte được lưu nhờ các đề xuất của Trình tối ưu hóa (bao gồm hai byte từ thứ mà tôi nghĩ tôi đã thử và không hoạt động - huh).


1
q"GACU"f#3/{4b"GGEDAAVVRSKNTTMIRRQHPPLLWC*YSSLF"{_s"MW""I*"er}%=}%s_'*/(1<"M"=*Q="Error"@?- 90
Tối ưu hóa

@Optimizer, một số trong đó dường như là một cải tiến. Tuy nhiên, nó đưa ra lỗi thời gian chạy và so sánh Qthay vì [Q]chỉ là không chính xác.
Peter Taylor

1. bạn đã không sao chép mã chính xác, khi mã kéo dài nhiều dòng trong các nhận xét, nó sẽ nhận được một ký tự unicode kỳ lạ khi ngắt dòng. Sau đó, bạn sẽ phải tự nhập mã. 2. Xem logic, nó đã được thay đổi để hoạt động chính xác, do đó [Q]để Qthay đổi là chính xác.
Tối ưu hóa

@Optimizer, hãy thử trường hợp thử nghiệmAUGUAGUGA
Peter Taylor

1
À được rồi. Tuy nhiên [Q]->Qa
Trình tối ưu hóa

10

JavaScript (ES6) 167 177 ký tự được mã hóa trong UTF8 là 167 177 byte

... Vì vậy tôi hy vọng mọi người đều hạnh phúc.

Chỉnh sửa Trong thực tế, không cần một trường hợp đặc biệt cho khối cuối cùng quá ngắn. Nếu 2 (hoặc 1) ký tự cuối cùng không được ánh xạ, chuỗi kết quả sẽ không kết thúc bằng '*' và điều đó sẽ gây ra lỗi.

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'

Giải thích

Mỗi char trong một bộ ba có thể có 4 giá trị, do đó, có chính xác 4 ^ 3 == 64 bộ ba. Hàm C ánh xạ mỗi bộ ba thành một số trong khoảng từ 0 đến 63. Không cần kiểm tra lỗi vì các ký tự đầu vào chỉ là ACGU.

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

Mỗi bộ ba ánh xạ tới một aminoacid được xác định bởi một char. Chúng ta có thể mã hóa điều này trong một chuỗi 64 ký tự. Để có được chuỗi, bắt đầu với Bản đồ Codon:

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

... có được "KNKNTTTTRSRSIIMIQHQHPPPPRRRRLLLLEDEDAAAAGGGGVVVV * Y * YSSSS * CWCLFLF"

Vì vậy, chúng ta có thể quét chuỗi đầu vào và sử dụng cùng logic của hàm C để lấy mã 0..63 và từ mã aminoacid char. Hàm thay thế sẽ chia chuỗi đầu vào thành 3 khối ký tự, cuối cùng để lại 1 hoặc 2 ký tự không được quản lý (sẽ cho chuỗi kết quả không hợp lệ, không kết thúc bằng '*').

Cuối cùng, hãy kiểm tra xem chuỗi được mã hóa có hợp lệ hay không bằng cách sử dụng biểu thức chính quy: nó phải bắt đầu bằng 'M', không được chứa '*' và phải kết thúc bằng '*'

Kiểm tra trong bảng điều khiển FireBug / FireFox

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

Đầu ra

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

Ý kiến ​​hay! Chỉ nghĩ về việc này. Bạn đánh bại tôi vào nó!
Tối ưu hóa

8

C, 190 byte (hàm)

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 byte (chương trình)

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

Đã lưu một vài byte bằng cách cải thiện công thức băm.

Đây là một trường hợp thử nghiệm thú vị:

AUGUAUCAUGAGCUCCUUCAGUGGCAAAGACUUGACUGA --> MYHELLQWQRLD* 

Giải trình

Bộ ba chữ cái được chuyển đổi thành một số cơ sở 4. Mỗi chữ cái được băm như sau.

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

Điều này cho một số trong phạm vi 0..63. Ý tưởng bây giờ là sử dụng bảng tra cứu tương tự như bảng được sử dụng bởi edc65 và Trình tối ưu hóa. Tuy nhiên, hàm băm được thiết kế sao cho G và A nằm cạnh nhau và U và C nằm cạnh nhau.

Nhìn vào bảng tại https://en.wikipedia.org/wiki/Genetic_code#RNA_codon_table , chúng ta thấy rằng với các chữ cái được sắp xếp theo cách này, nói chung có thể bỏ qua bit cuối cùng. Chỉ cần một bảng tra cứu 32 ký tự, ngoại trừ trong hai trường hợp đặc biệt.

Xem hai chữ cái đầu tiên bên dưới và các axit amin tương ứng (trong đó chữ cái thứ 3 là G / A và chữ cái thứ 3 là U / C). Sửa chữa cho hai trường hợp đặc biệt không phù hợp với bảng 32 ký tự được mã hóa cứng.

     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

Mã nhận xét

Trong phiên bản golf, i%3mã nằm ở vị trí tăng của forkhung, nhưng nó được chuyển sang vị trí dễ đọc hơn trong mã nhận xét.

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.
}

Giá như có một O! MGENETICS*Mặc dù vậy, tôi đã thêm một trường hợp thử nghiệm vì đó là từ theo chủ đề nhất mà tôi có thể tạo ra: P
Sp3000

6

CJam, 317 121 104 byte

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"?

Điều này vẫn có thể được chơi golf hơn nữa.

Đã cập nhật cơ chế ánh xạ thành cơ chế được sử dụng trong câu trả lời của edc65. Mặc dù tôi đã tự mình nghĩ ra điều này, anh ấy đã đánh bại tôi :)

CẬP NHẬT : Rút ngắn bản đồ bảng mã bằng cách quan sát mẫu trong đó.

Dùng thử trực tuyến tại đây


Điều này phá vỡ nếu đầu vào là chuỗi trống.
Peter Taylor

@PeterTaylor Một quy tắc đã được thêm vào đề xuất của bạn sau khi câu trả lời được đăng;). Tôi sẽ cập nhật mã sớm.
Tối ưu hóa

1
Đó không phải là một quy tắc đã được thêm vào, đó là một trường hợp thử nghiệm đã được quy tắc ngầm định yêu cầu.
Peter Taylor

3

GolfScript (103 byte)

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

Bản demo trực tuyến (NB không bao gồm hai trường hợp thử nghiệm lớn nhất vì nó cần chạy trong 15 giây).

Mổ xẻ

Như Steve Verrill đã chỉ ra trong hộp cát, bảng tra cứu có thể giảm xuống còn 32 yếu tố cộng với hai trường hợp đặc biệt. Hóa ra các trường hợp đặc biệt đều liên quan đến các ký tự ( MWtương ứng) chỉ xảy ra một lần và với ánh xạ đúng của các ký tự thành 4 chữ số, có thể xây dựng bảng tra cứu 64 phần tử đầy đủ từ 32 phần tử bằng cách thực hiện trùng lặp -and- tr:

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

Sau đó, khi chúng tôi thực hiện giải mã, xác thực cho phép nhiều cách tiếp cận. Thời gian ngắn nhất tôi tìm thấy là

.'*'/       # 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 byte. Thử thách được chấp nhận!
Tối ưu hóa

@Optimizer, một bản dịch thẳng sang CJam sẽ tiết kiệm được một vài byte tốt vì nó có rất nhiều tích hợp có liên quan.
Peter Taylor

Hàm băm của tôi dài 57 byte, trong khi của bạn là 52. Vì vậy, tôi chỉ có thể thấy tối đa 5 byte tiết kiệm ...
Trình tối ưu hóa

Tôi rất vui vì nhận xét của tôi trong hộp cát là hữu ích. Tôi hy vọng có thể sử dụng thực tế Mlà một trong những trường hợp đặc biệt để kiểm tra sự khởi đầu hợp lệ, nhưng nó đã không diễn ra theo cách đó. Vẫn còn 8 cặp chữ cái giống nhau trong chuỗi đó. Tôi tự hỏi nếu chúng có thể được nén dưới dạng chữ cái viết thường: g-->GG a-->AAvv Nếu giải nén có thể đạt được dưới 8 ký tự thì sẽ rất đáng giá.
Cấp sông St

1

Python, 473 byte

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 byte

Đây là một cách tiếp cận rất thẳng về phía trước, không sử dụng nén, chỉ cố gắng đóng gói thông tin khá dày đặc:

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

Chỉnh sửa: Tắt một vài ký tự theo đề xuất của xnor.


Tôi tin rằng bạn có thể viết sđệ quy ngắn hơn như s=lambda x:x and[x[:3]]+s(x[3:]).
xnor

@xnor Tuyệt vời, tôi đã không nghĩ về điều đó. Nó không hoàn toàn hoạt động như vậy, vì vào cuối đệ quy, nó sẽ xuất ra một chuỗi trống không phải là một danh sách trống. Nhưng với bốn nhân vật nữa tôi có thể làm cho nó hoạt động. Cảm ơn!
Emil

1

Scala (317 ký tự)

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}

Chức năng chính là f. Tất nhiên, một lựa chọn tốt hơn sẽ là trả lại một Option[String].


0

JavaScript (ES6), 143 byte

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

Hãy thử trực tuyến!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.