РНК до білкового перекладу


18

РНК , як і ДНК - це молекула, що знаходиться в клітинах, що кодують генетичну інформацію. Він складається з нуклеотидів , які представлені основами аденіну (A), цитозину (C), гуаніну (G) та урацилу (U). * Кодон - це послідовність трьох нуклеотидів.

Білки - це великі молекули, які виконують широкий спектр функцій, наприклад кератин, який міститься у волоссі та нігтях, і гемоглобін, який несе кисень у клітинах крові. Вони складаються з амінокислот , які кодуються як кодони в молекулах РНК. Іноді різні кодони можуть кодувати одну і ту ж амінокислоту. Кожна амінокислота зазвичай представлена ​​однією буквою, наприклад H означає гістидин.

Враховуючи послідовність ACGU, чи можете ви перекласти її у відповідну білкову рядок?

* ДНК складається з АКТГТ, де Т - тимін. Під час транскрипції ДНК до РНК тимін замінюється урацилом.


Вхідні дані

Введенням буде одна рядок, що складається лише з символів ACGUу верхньому регістрі. Ви можете написати або функцію, або повну програму для цього завдання.

Вихідні дані

Ви можете вибрати для друку або повернення рядка (останній вибір доступний лише у випадку функції).

Переклад слід починати на старті - кодоне ( AUG, представлена в вигляді M) і наприкінці в стопі - кодоне (один з UAA, UAGабо UGA, представлений в вигляді *). Є чотири випадки, коли введення даних може бути недійсним:

  • Введення не починається зі стартового кодона
  • Вхід не закінчується стоп-кодоном
  • Довжина вводу не кратна 3
  • Вхід містить стоп-кодон десь інший, ніж в кінці

У всіх цих випадках Errorслід виводити. Зауважте, що на відміну від стоп-кодонів, стартові кодони можуть з'являтися після початку рядка.

В іншому випадку слід перетворити кожен кодон у його відповідну амінокислоту за допомогою наступної таблиці кодонів РНК :

* 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!
канадіанер

@canadianer Ahaha Так, я спочатку вважав це, але не хотів ускладнювати це питання, відкриваючи відкриті кадри читання (або навіть перекладаючи декілька білків з однієї струни) :)
Sp3000

Порожній рядок був би корисним тестовим випадком, оскільки він порушить деякі підходи до тестування, з яких декодована послідовність починається Mі закінчується *.
Пітер Тейлор

@PeterTaylor Додано разом із ще декількома короткими тестовими справами :)
Sp3000

1
Якщо ви хотіли бути справжнім болем, ви могли б використовувати ДНК замість РНК, тому у вас є і кадри зчитування назад.
user137

Відповіді:


6

CJam ( 97 93 92 91 байт)

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

Це порт мого рішення GolfScript із злегка налаштованою хеш-функцією, тому що, на мій подив, одна річ, яку CJam не запозичив у GolfScript, трактує рядки як масиви цілих чисел.

6 байтів збережено завдяки пропозиціям оптимізатора (включаючи два байти з чогось, що я думав, що я спробував і не працював - так).


1
q"GACU"f#3/{4b"GGEDAAVVRSKNTTMIRRQHPPLLWC*YSSLF"{_s"MW""I*"er}%=}%s_'*/(1<"M"=*Q="Error"@?- 90
Оптимізатор

@Optimizer, деякі з них, схоже, є вдосконаленням. Однак це дає помилку під час виконання, а порівняння, Qа не [Q]просто неправильне.
Пітер Тейлор

1. ви неправильно скопіювали код, коли код простягається у кількох рядках у коментарях, він набуває дивного символу unicode при розриві рядка. Потім вам доведеться ввести код urself вручну. 2. Див логіки, вона була змінена , щоб працювати правильно, таким чином , [Q]щоб Qзміни правильно.
Оптимізатор

@Optimizer, спробуйте тестовий випадокAUGUAGUGA
Пітер Тейлор

1
Ага гаразд. Все-таки [Q]->Qa
Оптимізатор

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 символами. Щоб отримати рядок, почніть з карти Кодона:

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, і з коду амінокислотної таблиці. Функція заміни розділить вхідний рядок на 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*

Хороша ідея! Просто думав зробити це. Ти побив мене до цього!
Оптимізатор

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

199 194 байт (програма)

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 , ми бачимо, що впорядковані таким чином букви, як правило, останній біт можна ігнорувати. Потрібна лише таблиця пошуку 32 символів, за винятком двох спеціальних випадків.

Дивіться нижче перші дві літери та відповідні амінокислоти (де 3-я літера - це G / A, а 3-я літера - U / C). Виправлення для двох спеціальних випадків, які не відповідають таблиці 32 символів, є жорстким кодом.

     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. Хоча я придумав це самостійно, він побив мене до цього :)

ОНОВЛЕННЯ : Скорочуйте карту таблиці кодона, спостерігаючи за цим шаблоном.

Спробуйте його онлайн тут


Це порушується, якщо вхід - порожній рядок.
Пітер Тейлор

@PeterTaylor Правило, яке було додано на вашу пропозицію після публікації відповіді;). Я скоро оновлю код.
Оптимізатор

1
Це не було додане правило, це був тестовий випадок, який вже явно вимагали правила.
Пітер Тейлор

3

GolfScript (103 байти)

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

Демонстрація в Інтернеті (NB не містить двох найбільших тестових випадків, оскільки її потрібно запустити за 15 секунд).

Розсічення

Як зазначив Стів Веррілл у пісочниці, таблицю пошуку можна зменшити до 32 елементів плюс два особливих випадки. Виявляється, що в спеціальних випадках задіяні символи ( Mі Wвідповідно), які трапляються лише один раз, і при правильному відображенні символів на основі 4 цифр можна створити повну 64-елементну таблицю пошуку з 32 елементів, виконавши дублікат -і- 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 дозволить заощадити декілька гарних байтів, оскільки він має багато відповідних вбудованих модулів.
Пітер Тейлор

Моя функція хешування - 57 байт, а ваша - 52. Тож я бачу лише 5 байтів, що зберігаються ...
Оптимізатор

Я радий, що мій коментар у пісочниці був корисним. Я сподівався, що можливо вдасться використати той факт, що Mбув одним із особливих випадків для перевірки на дійсний старт, але це не вийшло. У цьому рядку є ще 8 пар однакових букв. Цікаво, чи можна їх стиснути як малі літери: g-->GG a-->AAі т. Д. Якщо декомпресію можна домогтися менше ніж у 8 символів, варто.
Рівень Св. Св.

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

@xnor Чудово, я про це не думав. Це не зовсім так працює, тому що в кінці рекурсії він видасть порожній рядок, а не порожній список. Але, маючи ще чотирьох персонажів, я можу змусити його працювати. Спасибі!
Еміль

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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.