Сметки с ДНК
- Краен срок:
- 26.10.2021 17:00
- Точки:
- 20
Срокът за предаване на решения е отминал
Време е за биоинформатика. И под "биоинформатика" имаме предвид броене на char-ове.
Броене
Една нишка ДНК е съставена от комбинация от четири нуклеотидни бази -- цитозин, гуанин, аденин и тимин, които се описват с буквите C, G, A, T. Като за начало, искаме да напишете функция, която приема slice от тези бази и брои колко пъти се срещат:
pub struct NucleotideCounter {
pub a: usize,
pub c: usize,
pub g: usize,
pub t: usize,
}
pub fn counts(dna: &[char]) -> NucleotideCounter {
todo!()
}
Входа ще бъде списък, който изглежда примерно така: ['A', 'C', 'G', 'A', 'T', ...]
. Всеки път като срещнете един от тези четири символа, очакваме да го преброите в съответното поле в този counter и да го върнете накрая.
Hint: Може да минете по елементите на един списък с for-цикъл, има пример още в първата лекция.
В случай, че ви подадем буквичка, която не е една от тези, ще очакваме да panic-нете. Това включва малките букви a
, g
, и т.н. -- само големите букви са валидни, само тези четири. Тъй като още не сме говорили за error handling, ето какво значи "да panic-нете":
panic!("Грешка, грешка, обърках вратата");
Самото съобщение е ваш избор и, технически погледнато, не е нужно да съдържа цитат от песен на Джанго Зе.
Комплементарно ДНК
ДНК-то се състои от две нишки, които са свързани база с база. Всяка база си има конкретно приятелче, с което се връзва:
- Базата
G
се свързва само с базатаC
и обратно - Базата
A
се свързва само с базатаT
и обратно
В следващата функция искаме да ни дадете тази нишка, която се връзва с подадената, база по база:
pub fn dna_complement(dna: &[char]) -> Vec<char> {
todo!()
}
И така, dna_complement(&['A', 'C'])
ще очакваме да ни върне вектор с първи елемент 'T'
и втори елемент 'G'
. Както при първата функция, очакваме ако подадем различна буква от тези четири, да panic-нете.
РНК
ДНК е "шаблона", програмата, от която се започва. Молекулата РНК минава по ДНК-то, копира го и отива да прави протеини. Тя има само една нишка и вместо базата тимин (T
) използва базата урацил (U
), която работи по същия начин -- свързва се с аденозин (A
).
Другото интересно нещо е че нишката се чете наобратно, или поне нещо такова помним бегло и смело ще използваме като оправдание да ви накараме да итерирате наобратно за разнообразие:
pub fn reverse_rna_complement(dna: &[char]) -> Vec<char> {
todo!()
}
Тази функция очакваме да ни даде "complement" на подадената нишка, също както предната функция. За да бъде максимално ясно:
- Входа на функцията е ДНК, комбинация от базите:
G
,C
,A
,T
- Изхода на функцията е РНК, комбинация от базите:
G
,C
,A
,U
Тоест, вместо T
ще очакваме в резултата да присъства базата U
, и нишката трябва да е обърната. Примерно, reverse_rna_complement(&['A', 'C'])
би трябвало да върне вектор с първи елемент 'G'
и втори елемент 'U'
.
Вероятно ще е най-лесно да обърнете резултатния вектор, което звучи като нещо, което може да е описано някъде в документацията на стандартната библиотека.
Пак, очакваме паника при неочакван символ. Входа е ДНК, така че четирите символа за валидация са непроменени, само изхода ще бъде различен.
Бележки
Не се притеснявайте за скорост, примерно спокойно си обръщайте вектори както си искате. В силно вероятния случай да сме объркали терминологията или нещо такова, не забравяйте че не сме биолози :). Следвайте инструкциите на задачката, питайте ако има нещо неясно.
Задължително прочетете (или си припомнете): Указания за предаване на домашни
Погрижете се решението ви да се компилира с базовия тест: