diff --git a/src/game/genetics/translate.hpp b/src/game/genetics/translate.hpp new file mode 100644 index 0000000..44987a9 --- /dev/null +++ b/src/game/genetics/translate.hpp @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2020 Christopher J. Howard + * + * This file is part of Antkeeper source code. + * + * Antkeeper source code is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Antkeeper source code is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Antkeeper source code. If not, see . + */ + +#ifndef ANTKEEPER_TRANSLATE_HPP +#define ANTKEEPER_TRANSLATE_HPP + +#include +#include +#include + +namespace dna +{ + +constexpr char* standard_code = + "FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG" // Amino acid + "---M------**--*----M---------------M----------------------------" // Start/stop + "TTTTTTTTTTTTTTTTCCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAGGGGGGGGGGGGGGGG" // Base 1 + "TTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGGTTTTCCCCAAAAGGGG" // Base 2 + "TCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAGTCAG"; // Base 3 + +/** + * Translates codons into amino acids until a stop codon is read or the end of the sequence is reached. + * + * @param first,last Range of codons to translate. + * @param t_first Beginning of the translation table. + * @param d_first Beginning of the destination range. + * @return Output iterator to the amino acid in the destination range, one past the last amino acid translated. + */ +template +OutputIt translate(InputIt1 first, InputIt1 last, InputIt2 t_first, OutputIt d_first) +{ + InputIt1 second = first; + ++second; + InputIt1 third = second; + ++third; + + InputIt2 base1_first = t_first; + std::advance(base1_first, 128); + InputIt2 base2_first = base1_first; + std::advance(base2_first, 64); + InputIt2 base3_first = base2_first; + std::advance(base3_first, 64); + + while (first != last && second != last && third != last) + { + InputIt2 aa = t_first; + InputIt2 base1 = base1_first; + InputIt2 base2 = base2_first; + InputIt2 base3 = base3_first; + + for (std::uint_fast8_t i = 0; i < 64; ++i) + { + if (*first == *base1 && *second == *base2 && *third == *base3) + { + if (*aa == '*') + return d_first; + + *(d_first++) = *aa; + break; + } + + ++aa; + ++base1; + ++base2; + ++base3; + } + + first = ++third; + second = ++third; + ++third; + } + + return d_first; +} + +} // namespace dna + +#endif // ANTKEEPER_TRANSLATE_HPP