Skip to content

Instantly share code, notes, and snippets.

@Fiona-J-W
Last active August 29, 2015 14:10
Show Gist options
  • Save Fiona-J-W/b2a0c12c1d917dd42eba to your computer and use it in GitHub Desktop.
Save Fiona-J-W/b2a0c12c1d917dd42eba to your computer and use it in GitHub Desktop.
#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