|
| 1 | +#include "protein_translation.h" |
| 2 | +#include <string.h> |
| 3 | + |
| 4 | +#define CODON_SIZE 3 |
| 5 | +#define CODON_INVALID -1 |
| 6 | +#define CODON_STOP -2 |
| 7 | + |
| 8 | +int char_to_index(char c) { |
| 9 | + switch (c) { |
| 10 | + case 'A': return 0; |
| 11 | + case 'C': return 1; |
| 12 | + case 'G': return 2; |
| 13 | + case 'U': return 3; |
| 14 | + default: return -1; |
| 15 | + } |
| 16 | +} |
| 17 | + |
| 18 | +// perfect hash |
| 19 | +int hash(char a, char b) { |
| 20 | + int index_a = char_to_index(a); |
| 21 | + int index_b = char_to_index(b); |
| 22 | + if (index_a == -1 || index_b == -1) |
| 23 | + return -1; |
| 24 | + |
| 25 | + return (index_a<<2) + index_b; |
| 26 | + |
| 27 | +} |
| 28 | + |
| 29 | +int lookup(const char *word) { |
| 30 | + if (word[0] == 'A' && word[1] == 'U' && word[2] == 'G') |
| 31 | + return Methionine; |
| 32 | + |
| 33 | + if (word[0] == 'U') |
| 34 | + switch (hash(word[1], word[2])) { |
| 35 | + /* UAA */ case 0: return CODON_STOP; |
| 36 | + /* UAC */ case 1: return Tyrosine; |
| 37 | + /* UAG */ case 2: return CODON_STOP; |
| 38 | + /* UAU */ case 3: return Tyrosine; |
| 39 | + |
| 40 | + /* UCA */ case 4: return Serine; |
| 41 | + /* UCC */ case 5: return Serine; |
| 42 | + /* UCG */ case 6: return Serine; |
| 43 | + /* UCU */ case 7: return Serine; |
| 44 | + |
| 45 | + /* UGA */ case 8: return CODON_STOP; |
| 46 | + /* UGC */ case 9: return Cysteine; |
| 47 | + /* UGG */ case 10: return Tryptophan; |
| 48 | + /* UGU */ case 11: return Cysteine; |
| 49 | + |
| 50 | + /* UUA */ case 12: return Leucine; |
| 51 | + /* UUC */ case 13: return Phenylalanine; |
| 52 | + /* UUG */ case 14: return Leucine; |
| 53 | + /* UUU */ case 15: return Phenylalanine; |
| 54 | + default: return CODON_INVALID; |
| 55 | + } |
| 56 | + return CODON_INVALID; |
| 57 | +} |
| 58 | + |
| 59 | + |
| 60 | +protein_t protein(const char *rna) { |
| 61 | + protein_t p = { .valid = true, .count = 0 }; |
| 62 | + |
| 63 | + size_t len = strlen(rna); |
| 64 | + |
| 65 | + int amino; |
| 66 | + for (size_t i = 0; i < len; i += CODON_SIZE) { |
| 67 | + amino = lookup(rna+i); |
| 68 | + |
| 69 | + if (amino == CODON_INVALID) { |
| 70 | + p.valid = false; |
| 71 | + break; |
| 72 | + } |
| 73 | + |
| 74 | + if (amino == CODON_STOP) |
| 75 | + break; |
| 76 | + |
| 77 | + p.amino_acids[p.count++] = amino; |
| 78 | + } |
| 79 | + |
| 80 | + return p; |
| 81 | +} |
0 commit comments