Last active
August 29, 2015 14:10
-
-
Save Fiona-J-W/b2a0c12c1d917dd42eba to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <array> | |
#include <cassert> | |
#include <string> | |
#include <algorithm> | |
#include <iterator> | |
#include <map> | |
#include <ostream> | |
#include <iostream> | |
#include <vector> | |
enum class base : char { | |
A = 'A', | |
U = 'U', | |
G = 'G', | |
C = 'C' | |
}; | |
const auto valid_bases = std::array<char, 4>{{'A', 'U', 'C', 'G'}}; | |
base to_base(char c) { | |
if (!std::any_of(valid_bases.begin(), valid_bases.end(), [=](char arg){return c == arg;})) { | |
throw std::invalid_argument{"invalid base"}; | |
} | |
return static_cast<base>(c); | |
} | |
struct codon { | |
codon(base b1, base b2, base b3): bases{{b1, b2, b3}} {} | |
std::array<base, 3> bases; | |
}; | |
bool operator==(codon lhs, codon rhs) {return lhs.bases == rhs.bases;} | |
bool operator!=(codon lhs, codon rhs) {return !(lhs == rhs);} | |
bool operator<(codon lhs, codon rhs) {return lhs.bases < rhs.bases;} | |
template<typename Iterator> | |
codon read_codon(Iterator it, Iterator last) { | |
assert(std::distance(it, last) == 3); | |
return codon { | |
to_base(*it), | |
to_base(*(it+1)), | |
to_base(*(it+2)) | |
}; | |
} | |
struct amino_acid { | |
char encoding; | |
}; | |
std::ostream& operator<<(std::ostream& stream, amino_acid acid) { | |
return stream << acid.encoding; | |
} | |
amino_acid translate_codon(codon arg) { | |
const auto A = base::A; | |
const auto U = base::U; | |
const auto C = base::C; | |
const auto G = base::G; | |
static const auto mappings = std::map<codon, amino_acid>{ | |
{{G, C, U}, {'A'}}, | |
{{C, A, U}, {'H'}}, | |
{{A, A, U}, {'I'}}, | |
{{C, C, U}, {'P'}}, | |
{{G, A, U}, {'D'}}, | |
//{{A, A, U}, {'N'}}, // this occurs twice | |
{{G, A, A}, {'E'}}, | |
{{U, C, U}, {'S'}}, | |
{{U, G, U}, {'S'}}, | |
{{U, G, A}, {0}}, | |
}; | |
return mappings.at(arg); | |
} | |
bool is_terminator(amino_acid arg) { | |
return arg.encoding == '\0'; | |
} | |
std::vector<amino_acid> translation(const std::string& mRNA) { | |
const auto start_codon = std::string{"AUG"}; | |
const auto start = std::search(mRNA.begin(), mRNA.end(), start_codon.begin(), start_codon.end()); | |
if(start == mRNA.end()) { | |
return {}; // ? | |
} | |
const auto code_start = start + 3; | |
auto amino_acids = std::vector<amino_acid>{}; | |
for (auto it = code_start; it + 2 < mRNA.end(); it+=3) { | |
const auto acid = translate_codon(read_codon(it, it + 3)); | |
if(is_terminator(acid)) { | |
return amino_acids; | |
} | |
amino_acids.push_back(acid); | |
} | |
return {}; | |
} | |
int main() { | |
const auto mRNA = std::string{"AAAAUUUGGCCCAAUAUGAAUAAUGAUUGAG"}; | |
const auto translated = translation(mRNA); | |
std::copy(translated.begin(), translated.end(), std::ostream_iterator<amino_acid>{std::cout}); | |
std::cout << '\n'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment