diff --git a/config.json b/config.json index 161cd9f..14a95ab 100644 --- a/config.json +++ b/config.json @@ -182,6 +182,14 @@ "prerequisites": [], "difficulty": 1 }, + { + "slug": "protein-translation", + "name": "Protein Translation", + "uuid": "73d301f2-9a3e-4d67-8138-dee878094539", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "atbash-cipher", "name": "Atbash Cipher", diff --git a/exercises/practice/protein-translation/.docs/instructions.md b/exercises/practice/protein-translation/.docs/instructions.md new file mode 100644 index 0000000..35c953b --- /dev/null +++ b/exercises/practice/protein-translation/.docs/instructions.md @@ -0,0 +1,38 @@ +# Instructions + +Your job is to translate RNA sequences into proteins. + +RNA strands are made up of three-nucleotide sequences called **codons**. +Each codon translates to an **amino acid**. +When joined together, those amino acids make a protein. + +In the real world, there are 64 codons, which in turn correspond to 20 amino acids. +However, for this exercise, you’ll only use a few of the possible 64. +They are listed below: + +| Codon | Amino Acid | +| ------------------ | ------------- | +| AUG | Methionine | +| UUU, UUC | Phenylalanine | +| UUA, UUG | Leucine | +| UCU, UCC, UCA, UCG | Serine | +| UAU, UAC | Tyrosine | +| UGU, UGC | Cysteine | +| UGG | Tryptophan | +| UAA, UAG, UGA | STOP | + +For example, the RNA string “AUGUUUUCU” has three codons: “AUG”, “UUU” and “UCU”. +These map to Methionine, Phenylalanine, and Serine. + +## “STOP” Codons + +You’ll note from the table above that there are three **“STOP” codons**. +If you encounter any of these codons, ignore the rest of the sequence — the protein is complete. + +For example, “AUGUUUUCUUAAAUG” contains a STOP codon (“UAA”). +Once we reach that point, we stop processing. +We therefore only consider the part before it (i.e. “AUGUUUUCU”), not any further codons after it (i.e. “AUG”). + +Learn more about [protein translation on Wikipedia][protein-translation]. + +[protein-translation]: https://en.wikipedia.org/wiki/Translation_(biology) diff --git a/exercises/practice/protein-translation/.meta/config.json b/exercises/practice/protein-translation/.meta/config.json new file mode 100644 index 0000000..cd05d8c --- /dev/null +++ b/exercises/practice/protein-translation/.meta/config.json @@ -0,0 +1,18 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "zcl_protein_translation.clas.abap" + ], + "test": [ + "zcl_protein_translation.clas.testclasses.abap" + ], + "example": [ + ".meta/zcl_protein_translation.clas.abap" + ] + }, + "blurb": "Translate RNA sequences into proteins.", + "source": "Tyler Long" +} diff --git a/exercises/practice/protein-translation/.meta/tests.toml b/exercises/practice/protein-translation/.meta/tests.toml new file mode 100644 index 0000000..de680e3 --- /dev/null +++ b/exercises/practice/protein-translation/.meta/tests.toml @@ -0,0 +1,105 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[2c44f7bf-ba20-43f7-a3bf-f2219c0c3f98] +description = "Empty RNA sequence results in no proteins" + +[96d3d44f-34a2-4db4-84cd-fff523e069be] +description = "Methionine RNA sequence" + +[1b4c56d8-d69f-44eb-be0e-7b17546143d9] +description = "Phenylalanine RNA sequence 1" + +[81b53646-bd57-4732-b2cb-6b1880e36d11] +description = "Phenylalanine RNA sequence 2" + +[42f69d4f-19d2-4d2c-a8b0-f0ae9ee1b6b4] +description = "Leucine RNA sequence 1" + +[ac5edadd-08ed-40a3-b2b9-d82bb50424c4] +description = "Leucine RNA sequence 2" + +[8bc36e22-f984-44c3-9f6b-ee5d4e73f120] +description = "Serine RNA sequence 1" + +[5c3fa5da-4268-44e5-9f4b-f016ccf90131] +description = "Serine RNA sequence 2" + +[00579891-b594-42b4-96dc-7ff8bf519606] +description = "Serine RNA sequence 3" + +[08c61c3b-fa34-4950-8c4a-133945570ef6] +description = "Serine RNA sequence 4" + +[54e1e7d8-63c0-456d-91d2-062c72f8eef5] +description = "Tyrosine RNA sequence 1" + +[47bcfba2-9d72-46ad-bbce-22f7666b7eb1] +description = "Tyrosine RNA sequence 2" + +[3a691829-fe72-43a7-8c8e-1bd083163f72] +description = "Cysteine RNA sequence 1" + +[1b6f8a26-ca2f-43b8-8262-3ee446021767] +description = "Cysteine RNA sequence 2" + +[1e91c1eb-02c0-48a0-9e35-168ad0cb5f39] +description = "Tryptophan RNA sequence" + +[e547af0b-aeab-49c7-9f13-801773a73557] +description = "STOP codon RNA sequence 1" + +[67640947-ff02-4f23-a2ef-816f8a2ba72e] +description = "STOP codon RNA sequence 2" + +[9c2ad527-ebc9-4ace-808b-2b6447cb54cb] +description = "STOP codon RNA sequence 3" + +[f4d9d8ee-00a8-47bf-a1e3-1641d4428e54] +description = "Sequence of two protein codons translates into proteins" + +[dd22eef3-b4f1-4ad6-bb0b-27093c090a9d] +description = "Sequence of two different protein codons translates into proteins" + +[d0f295df-fb70-425c-946c-ec2ec185388e] +description = "Translate RNA strand into correct protein list" + +[e30e8505-97ec-4e5f-a73e-5726a1faa1f4] +description = "Translation stops if STOP codon at beginning of sequence" + +[5358a20b-6f4c-4893-bce4-f929001710f3] +description = "Translation stops if STOP codon at end of two-codon sequence" + +[ba16703a-1a55-482f-bb07-b21eef5093a3] +description = "Translation stops if STOP codon at end of three-codon sequence" + +[4089bb5a-d5b4-4e71-b79e-b8d1f14a2911] +description = "Translation stops if STOP codon in middle of three-codon sequence" + +[2c2a2a60-401f-4a80-b977-e0715b23b93d] +description = "Translation stops if STOP codon in middle of six-codon sequence" + +[f6f92714-769f-4187-9524-e353e8a41a80] +description = "Sequence of two non-STOP codons does not translate to a STOP codon" + +[1e75ea2a-f907-4994-ae5c-118632a1cb0f] +description = "Non-existing codon can't translate" +include = false + +[9eac93f3-627a-4c90-8653-6d0a0595bc6f] +description = "Unknown amino acids, not part of a codon, can't translate" +reimplements = "1e75ea2a-f907-4994-ae5c-118632a1cb0f" + +[9d73899f-e68e-4291-b1e2-7bf87c00f024] +description = "Incomplete RNA sequence can't translate" + +[43945cf7-9968-402d-ab9f-b8a28750b050] +description = "Incomplete RNA sequence can translate if valid until a STOP codon" diff --git a/exercises/practice/protein-translation/.meta/zcl_protein_translation.clas.abap b/exercises/practice/protein-translation/.meta/zcl_protein_translation.clas.abap new file mode 100644 index 0000000..acc8dba --- /dev/null +++ b/exercises/practice/protein-translation/.meta/zcl_protein_translation.clas.abap @@ -0,0 +1,75 @@ +CLASS zcl_protein_translation DEFINITION + PUBLIC + FINAL + CREATE PUBLIC. + + PUBLIC SECTION. + METHODS proteins + IMPORTING + strand TYPE string + RETURNING + VALUE(result) TYPE string_table + RAISING + cx_parameter_invalid. + PROTECTED SECTION. + PRIVATE SECTION. + METHODS get_protein + IMPORTING + codon TYPE string + RETURNING + VALUE(result) TYPE string + RAISING + cx_parameter_invalid. +ENDCLASS. + +CLASS zcl_protein_translation IMPLEMENTATION. + METHOD proteins. + DATA(offset) = 0. + DATA(length) = strlen( strand ). + + WHILE offset < length. + " If we are at the end of the string but don't have enough characters for a full codon + IF offset + 3 > length. + RAISE EXCEPTION TYPE cx_parameter_invalid. + ENDIF. + + DATA(codon) = substring( val = strand + off = offset + len = 3 ). + DATA(protein) = get_protein( codon ). + + IF protein = 'STOP'. + RETURN. + ENDIF. + + IF protein IS NOT INITIAL. + APPEND protein TO result. + ENDIF. + + offset = offset + 3. + ENDWHILE. + ENDMETHOD. + + METHOD get_protein. + CASE codon. + WHEN 'AUG'. + result = 'Methionine'. + WHEN 'UUU' OR 'UUC'. + result = 'Phenylalanine'. + WHEN 'UUA' OR 'UUG'. + result = 'Leucine'. + WHEN 'UCU' OR 'UCC' OR 'UCA' OR 'UCG'. + result = 'Serine'. + WHEN 'UAU' OR 'UAC'. + result = 'Tyrosine'. + WHEN 'UGU' OR 'UGC'. + result = 'Cysteine'. + WHEN 'UGG'. + result = 'Tryptophan'. + WHEN 'UAA' OR 'UAG' OR 'UGA'. + result = 'STOP'. + WHEN OTHERS. + RAISE EXCEPTION TYPE cx_parameter_invalid. + ENDCASE. + ENDMETHOD. +ENDCLASS. diff --git a/exercises/practice/protein-translation/package.devc.xml b/exercises/practice/protein-translation/package.devc.xml new file mode 100644 index 0000000..19fdddf --- /dev/null +++ b/exercises/practice/protein-translation/package.devc.xml @@ -0,0 +1,10 @@ + + + + + + Exercism: Protein Translation + + + + diff --git a/exercises/practice/protein-translation/zcl_protein_translation.clas.abap b/exercises/practice/protein-translation/zcl_protein_translation.clas.abap new file mode 100644 index 0000000..f5e3770 --- /dev/null +++ b/exercises/practice/protein-translation/zcl_protein_translation.clas.abap @@ -0,0 +1,23 @@ +CLASS zcl_protein_translation DEFINITION + PUBLIC + FINAL + CREATE PUBLIC. + + PUBLIC SECTION. + METHODS proteins + IMPORTING + strand TYPE string + RETURNING + VALUE(result) TYPE string_table + RAISING + cx_parameter_invalid. + PROTECTED SECTION. + PRIVATE SECTION. + +ENDCLASS. + +CLASS zcl_protein_translation IMPLEMENTATION. + METHOD proteins. + "Implement solution + ENDMETHOD. +ENDCLASS. diff --git a/exercises/practice/protein-translation/zcl_protein_translation.clas.testclasses.abap b/exercises/practice/protein-translation/zcl_protein_translation.clas.testclasses.abap new file mode 100644 index 0000000..f66c860 --- /dev/null +++ b/exercises/practice/protein-translation/zcl_protein_translation.clas.testclasses.abap @@ -0,0 +1,298 @@ +*"* use this source file for your ABAP unit test classes +CLASS ltcl_protein_translation DEFINITION FINAL FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS. + + PRIVATE SECTION. + DATA cut TYPE REF TO zcl_protein_translation. + + METHODS setup. + METHODS empty_rna FOR TESTING. + METHODS methionine FOR TESTING. + METHODS phenylalanine_1 FOR TESTING. + METHODS phenylalanine_2 FOR TESTING. + METHODS leucine_1 FOR TESTING. + METHODS leucine_2 FOR TESTING. + METHODS serine_1 FOR TESTING. + METHODS serine_2 FOR TESTING. + METHODS serine_3 FOR TESTING. + METHODS serine_4 FOR TESTING. + METHODS tyrosine_1 FOR TESTING. + METHODS tyrosine_2 FOR TESTING. + METHODS cysteine_1 FOR TESTING. + METHODS cysteine_2 FOR TESTING. + METHODS tryptophan FOR TESTING. + METHODS stop_codon_1 FOR TESTING. + METHODS stop_codon_2 FOR TESTING. + METHODS stop_codon_3 FOR TESTING. + METHODS two_protein_codons FOR TESTING. + METHODS two_diff_protein_codons FOR TESTING. + METHODS translate_rna_strand FOR TESTING. + METHODS stops_at_beginning FOR TESTING. + METHODS stops_at_end_of_two FOR TESTING. + METHODS stops_at_end_of_three FOR TESTING. + METHODS stops_in_middle_of_three FOR TESTING. + METHODS stops_in_middle_of_six FOR TESTING. + METHODS two_non_stop_codons FOR TESTING. + METHODS non_existing_codon FOR TESTING. + METHODS unknown_amino_acids FOR TESTING. + METHODS incomplete_rna_sequence FOR TESTING. + METHODS incomplete_but_valid_rna FOR TESTING. + +ENDCLASS. + +CLASS ltcl_protein_translation IMPLEMENTATION. + + METHOD setup. + cut = NEW zcl_protein_translation( ). + ENDMETHOD. + + METHOD empty_rna. + DATA(expected_values) = VALUE string_table( ). + DATA(result) = cut->proteins( '' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD methionine. + DATA(expected_values) = VALUE string_table( ( |Methionine| ) ). + DATA(result) = cut->proteins( 'AUG' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD phenylalanine_1. + DATA(expected_values) = VALUE string_table( ( |Phenylalanine| ) ). + DATA(result) = cut->proteins( 'UUU' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD phenylalanine_2. + DATA(expected_values) = VALUE string_table( ( |Phenylalanine| ) ). + DATA(result) = cut->proteins( 'UUC' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD leucine_1. + DATA(expected_values) = VALUE string_table( ( |Leucine| ) ). + DATA(result) = cut->proteins( 'UUA' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD leucine_2. + DATA(expected_values) = VALUE string_table( ( |Leucine| ) ). + DATA(result) = cut->proteins( 'UUG' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD serine_1. + DATA(expected_values) = VALUE string_table( ( |Serine| ) ). + DATA(result) = cut->proteins( 'UCU' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD serine_2. + DATA(expected_values) = VALUE string_table( ( |Serine| ) ). + DATA(result) = cut->proteins( 'UCC' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD serine_3. + DATA(expected_values) = VALUE string_table( ( |Serine| ) ). + DATA(result) = cut->proteins( 'UCA' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD serine_4. + DATA(expected_values) = VALUE string_table( ( |Serine| ) ). + DATA(result) = cut->proteins( 'UCG' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD tyrosine_1. + DATA(expected_values) = VALUE string_table( ( |Tyrosine| ) ). + DATA(result) = cut->proteins( 'UAU' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD tyrosine_2. + DATA(expected_values) = VALUE string_table( ( |Tyrosine| ) ). + DATA(result) = cut->proteins( 'UAC' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD cysteine_1. + DATA(expected_values) = VALUE string_table( ( |Cysteine| ) ). + DATA(result) = cut->proteins( 'UGU' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD cysteine_2. + DATA(expected_values) = VALUE string_table( ( |Cysteine| ) ). + DATA(result) = cut->proteins( 'UGC' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD tryptophan. + DATA(expected_values) = VALUE string_table( ( |Tryptophan| ) ). + DATA(result) = cut->proteins( 'UGG' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD stop_codon_1. + DATA(expected_values) = VALUE string_table( ). + DATA(result) = cut->proteins( 'UAA' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD stop_codon_2. + DATA(expected_values) = VALUE string_table( ). + DATA(result) = cut->proteins( 'UAG' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD stop_codon_3. + DATA(expected_values) = VALUE string_table( ). + DATA(result) = cut->proteins( 'UGA' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD two_protein_codons. + DATA(expected_values) = VALUE string_table( ( |Phenylalanine| ) ( |Phenylalanine| ) ). + DATA(result) = cut->proteins( 'UUUUUU' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD two_diff_protein_codons. + DATA(expected_values) = VALUE string_table( ( |Leucine| ) ( |Leucine| ) ). + DATA(result) = cut->proteins( 'UUAUUG' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD translate_rna_strand. + DATA(expected_values) = VALUE string_table( ( |Methionine| ) ( |Phenylalanine| ) ( |Tryptophan| ) ). + DATA(result) = cut->proteins( 'AUGUUUUGG' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD stops_at_beginning. + DATA(expected_values) = VALUE string_table( ). + DATA(result) = cut->proteins( 'UAGUGG' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD stops_at_end_of_two. + DATA(expected_values) = VALUE string_table( ( |Tryptophan| ) ). + DATA(result) = cut->proteins( 'UGGUAG' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD stops_at_end_of_three. + DATA(expected_values) = VALUE string_table( ( |Methionine| ) ( |Phenylalanine| ) ). + DATA(result) = cut->proteins( 'AUGUUUUAA' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD stops_in_middle_of_three. + DATA(expected_values) = VALUE string_table( ( |Tryptophan| ) ). + DATA(result) = cut->proteins( 'UGGUAGUGG' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD stops_in_middle_of_six. + DATA(expected_values) = VALUE string_table( ( |Tryptophan| ) ( |Cysteine| ) ( |Tyrosine| ) ). + DATA(result) = cut->proteins( 'UGGUGUUAUUAAUGGUUU' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD two_non_stop_codons. + DATA(expected_values) = VALUE string_table( ( |Methionine| ) ( |Methionine| ) ). + DATA(result) = cut->proteins( 'AUGAUG' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + + METHOD non_existing_codon. + TRY. + cut->proteins( 'AAA' ). + cl_abap_unit_assert=>fail( 'Should have raised cx_parameter_invalid' ). + CATCH cx_parameter_invalid. + ENDTRY. + ENDMETHOD. + + METHOD unknown_amino_acids. + TRY. + cut->proteins( 'XYZ' ). + cl_abap_unit_assert=>fail( 'Should have raised cx_parameter_invalid' ). + CATCH cx_parameter_invalid. + ENDTRY. + ENDMETHOD. + + METHOD incomplete_rna_sequence. + TRY. + cut->proteins( 'AUGU' ). + cl_abap_unit_assert=>fail( 'Should have raised cx_parameter_invalid' ). + CATCH cx_parameter_invalid. + ENDTRY. + ENDMETHOD. + + METHOD incomplete_but_valid_rna. + DATA(expected_values) = VALUE string_table( ( |Phenylalanine| ) ( |Phenylalanine| ) ). + DATA(result) = cut->proteins( 'UUCUUCUAAUGGU' ). + cl_abap_unit_assert=>assert_equals( + act = result + exp = expected_values ). + ENDMETHOD. + +ENDCLASS. diff --git a/exercises/practice/protein-translation/zcl_protein_translation.clas.xml b/exercises/practice/protein-translation/zcl_protein_translation.clas.xml new file mode 100644 index 0000000..381f6c1 --- /dev/null +++ b/exercises/practice/protein-translation/zcl_protein_translation.clas.xml @@ -0,0 +1,17 @@ + + + + + + ZCL_PROTEIN_TRANSLATION + E + Exercism: Protein Translation + 1 + X + X + X + X + + + +