RNAからタンパク質への翻訳


18

RNAはDNAと同様に、遺伝情報をコードする細胞に見られる分子です。これはヌクレオチドで構成され、アデニン(A)、シトシン(C)、グアニン(G)およびウラシル(U)の塩基で表されます。* コドンは3つのヌクレオチドのシーケンスです。

タンパク質は、毛や爪に見られるケラチンや血球に酸素を運ぶヘモグロビンなど、膨大な機能を果たす大きな分子です。それらは、RNA分子のコドンとしてコード化されるアミノ酸で構成されています。異なるコドンが同じアミノ酸をエンコードする場合があります。通常、各アミノ酸は1文字で表されます。たとえば、Hはヒスチジンを表します。

のシーケンスが与えられた場合ACGU、対応するタンパク質文字列に変換できますか?

* DNAはACGTで構成され、Tはチミンです。DNAからRNAへの転写中、チミンはウラシルに置き換えられます。


入力

入力はACGU、大文字の文字のみで構成される単一の文字列になります。このチャレンジのために、関数または完全なプログラムを作成できます。

出力

文字列を印刷または返すことで出力することを選択できます(後者の選択は、関数の場合にのみ使用可能です)。

翻訳は、開始コドン(AUGで表されるM)で始まり、停止コドン(UAAUAGまたはのいずれかUGAで表される*)で終了する必要があります。入力が無効である可能性がある4つのケースがあります。

  • 入力が開始コドンで始まっていない
  • 入力が終止コドンで終わらない
  • 入力の長さが3の倍数ではありません
  • 入力には、終了以外の場所に停止コドンが含まれています

これらのすべての場合に、Error出力する必要があります。停止コドンとは異なり、開始コドンは文字列の開始後に表示される場合があることに注意してください。

それ以外の場合は、次のRNAコドンテーブルを使用して、各コドンをそれぞれのアミノ酸に変換する必要があります

* 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

...そして翻訳された文字列を出力します。

無効なケース:

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

有効なケース:

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

編集:テストケースを追加しました

得点

これはコードゴルフであるため、最小バイトのコードが勝ちます。

注:私は分子生物学の専門家ではないので、何かを間違えた場合はお気軽に修正してください:)


1
適切な翻訳者は、AUGで始まるものだけでなく、任意の文字列でオープンリーディングフレームを見つけることができるはずです!
カナダ人14

AHAHA @canadianerええ、私は当初、と考えたが、私はあまりにもオープンリーディングフレーム内に持ち込む(または単一の文字列から複数のタンパク質を翻訳する)によって複雑に質問をしたいしませんでした:)
SP3000

空の文字列は、デコードされたシーケンスがで始まり、Mで終わることをテストするためのいくつかのアプローチを破るので、有用なテストケースになります*
ピーターテイラー14

@PeterTaylorが追加され、さらにいくつかの短いテストケースが追加されました:)
Sp3000 14

1
本当の痛みになりたい場合は、RNAの代わりにDNAを使用できます。そのため、逆読みフレームもあります。
user137 14

回答:


6

CJam(97 93 92 91バイト)

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

驚いたことに、CJamがGolfScriptから借用していないことの1つは、文字列を整数の配列として扱うためです。

オプティマイザーによる提案のおかげで6バイト節約されました(私が試したがうまくいかなかったと思ったものからの2バイトを含む-ハァッ)。


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

@Optimizer、その一部は改善されているようです。ただし、実行時エラーが発生し、単に間違っているのではQなく比較が行われ[Q]ます。
ピーターテイラー14

1.コードがコメント内の複数行にまたがる場合、コードを正しくコピーしていないため、改行で奇妙なユニコード文字が表示されます。その後、手動でコードを手動で入力する必要があります。2.ロジックを参照してください。正しく動作するよう[Q]Q変更されているため、変更は正しいです。
オプティマイザー14

@Optimizer、テストケースを試すAUGUAGUGA
Peter Taylor 14

1
うん、いいよ。それでも[Q]->Qa
オプティマイザー14

10

JavaScriptの(ES6)167 177としてUTF8でエンコードされた文字167の177バイト

...だから、みんなが幸せになることを願っています。

編集実際、最後のブロックが短すぎるという特別なケースは必要ありません。最後の2文字(または1文字)がマップされていない場合、結果の文字列は「*」で終了せず、それでもエラーが発生します。

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'

説明した

トリプレットの各文字は4つの値を持つことができるため、正確に4 ^ 3 == 64のトリプレットがあります。C関数は、各トリプレットを0〜63の数値にマップします。入力文字はACGUのみであるため、エラーチェックは不要です。

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

各トリプレットは、単一の文字で識別されるアミノ酸にマッピングされます。これを64文字の文字列にエンコードできます。文字列を取得するには、Codon Mapから始めます。

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」を取得

したがって、入力文字列をスキャンし、C関数と同じロジックを使用してコード0..63を取得し、コードからアミノ酸charを取得できます。置換関数は、入力文字列を3文字のブロックに分割し、最終的に1文字または2文字を管理しません(「*」で終わらない無効な結果文字列を返します)。

最後に、エンコードされた文字列が正規表現を使用して有効かどうかを確認します。「M」で始まり、「*」を含まず、「*」で終わる必要があります。

FireBug / FireFoxコンソールでテストする

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

出力

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

良いアイデア!これをやろうと思っていました。あなたは私を打ち負かしました!
オプティマイザー14年

8

C、190バイト(関数)

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

199194バイト(プログラム)

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

ハッシュ式を改善して数バイトを節約しました。

楽しいテストケースを次に示します。

AUGUAUCAUGAGCUCCUUCAGUGGCAAAGACUUGACUGA --> MYHELLQWQRLD* 

説明

文字のトリプレットは、基数4の数値に変換されます。各文字は次のようにハッシュされます。

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

これにより、範囲内の数値が得られます0..63。現在の考えは、edc65およびOptimizerで使用されるものと同様のルックアップテーブルを使用することです。ただし、ハッシュは、GとAが隣接し、UとCが隣接するように設計されています。

https://en.wikipedia.org/wiki/Genetic_code#RNA_codon_tableの表を見ると、このように文字が並べられているため、通常最後のビットは無視できることがわかります。2つの特別な場合を除き、32文字のルックアップテーブルのみが必要です。

以下の最初の2文字と対応するアミノ酸を参照してください(3文字目はG / A、3文字目はU / C)。32文字のテーブルに収まらない2つの特殊なケースの修正は、ハードコーディングされています。

     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

コメント付きコード

ゴルフバージョンでは、i%3コードはforブラケットの増分位置にありますが、コメント付きコードではより読みやすい位置に移動します。

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

もしあればO!私はのためのテストケースを追加したMGENETICS*P:それは私が作ることができる最もテーマ別単語だから、しかし
SP3000

6

CJam、317の121 104バイト

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

これはまださらにゴルフすることができます。

edc65の回答で使用されているものにマッピングメカニズムを更新しました。私は自分でこれを思いついたのに、彼は私にそれを打ちました:)

更新:コドンテーブルマップのパターンを観察することにより、短縮しました。

こちらからオンラインでお試しください


入力が空の文字列の場合、これは壊れます。
ピーターテイラー14

@PeterTaylor回答が投稿された後に提案に追加されたルール;)。私はすぐにコードを更新します。
オプティマイザー14

1
追加されたルールではなく、ルールによってすでに暗黙的に要求されているテストケースでした。
ピーターテイラー14

3

GolfScript(103バイト)

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

オンラインデモ(NBには15秒で実行する必要があるため、2つの最大のテストケースは含まれていません)。

解剖

Steve Verrillがサンドボックスで指摘したように、ルックアップテーブルは32個の要素と2つの特別なケースに縮小できます。特殊なケースには両方とも一度しか発生しない文字(MおよびWそれぞれ)が含まれており、文字をベース4桁に正しくマッピングすると、複製を行うことで32要素から完全な64要素のルックアップテーブルを構築できることがわかります-と- tr

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

その後、デコードが完了すると、検証により多くのアプローチが可能になります。私が見つけた最短は

.'*'/       # 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バイト。勝負を受けて立つ!
オプティマイザー

@ Optimizer、CJamへの直接変換は、多くの関連ビルトインを持っているため、かなりの数バイトを節約します。
ピーターテイラー14

私のハッシュ関数は57バイトですが、あなたのハッシュ関数は52バイトです。
オプティマイザ

サンドボックス内のコメントが役に立ちました。M有効なスタートをテストするために特別なケースの1つであるという事実を使用できるかもしれないと期待していましたが、それはうまくいきませんでした。その文字列には、同じ文字のペアがまだ8つあります。小文字として圧縮できるかどうかg-->GG a-->AAなど:8文字未満で圧縮解除できる場合は価値があります。
レベルリバーセント14

1

Python、473バイト

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バイト

これは、圧縮を使用しない非常に単純なアプローチで、情報を非常に密にパックしようとします。

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

編集: xnorの提案に従って、数文字を削り落としました。


sとして再帰的に短く書くことができると信じていますs=lambda x:x and[x[:3]]+s(x[3:])
xnor 14年

@xnor素晴らしい、私はそれを考えていませんでした。再帰の最後に空のリストではなく空の文字列を出力するため、そのようには動作しません。しかし、さらに4つのキャラクターを使用すれば、機能させることができます。ありがとう!
エミル14年

1

Scala(317文字)

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}

主な機能はfです。もちろん、より良い選択はを返すことOption[String]です。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.