diff --git a/config.json b/config.json
index b6b7e4a8..986f1474 100644
--- a/config.json
+++ b/config.json
@@ -352,7 +352,23 @@
"practices": [],
"prerequisites": [],
"difficulty": 3
- }
+ },
+ {
+ "slug": "rna-transcription",
+ "name": "RNA Transcription",
+ "uuid": "bc73c977-cd23-40f5-a890-773e12f71d01",
+ "practices": [],
+ "prerequisites": [],
+ "difficulty": 3
+ },
+ {
+ "slug": "triangle",
+ "name": "Triangle",
+ "uuid": "b916066b-918e-403c-9a9c-be33c4a6250d",
+ "practices": [],
+ "prerequisites": [],
+ "difficulty": 3
+ }
]
},
"concepts": [
diff --git a/exercises/practice/rna-transcription/.docs/instructions.md b/exercises/practice/rna-transcription/.docs/instructions.md
new file mode 100644
index 00000000..36da381f
--- /dev/null
+++ b/exercises/practice/rna-transcription/.docs/instructions.md
@@ -0,0 +1,20 @@
+# Instructions
+
+Your task is determine the RNA complement of a given DNA sequence.
+
+Both DNA and RNA strands are a sequence of nucleotides.
+
+The four nucleotides found in DNA are adenine (**A**), cytosine (**C**), guanine (**G**) and thymine (**T**).
+
+The four nucleotides found in RNA are adenine (**A**), cytosine (**C**), guanine (**G**) and uracil (**U**).
+
+Given a DNA strand, its transcribed RNA strand is formed by replacing each nucleotide with its complement:
+
+- `G` -> `C`
+- `C` -> `G`
+- `T` -> `A`
+- `A` -> `U`
+
+~~~~exercism/note
+If you want to look at how the inputs and outputs are structured, take a look at the examples in the test suite.
+~~~~
diff --git a/exercises/practice/rna-transcription/.docs/introduction.md b/exercises/practice/rna-transcription/.docs/introduction.md
new file mode 100644
index 00000000..6b3f44b5
--- /dev/null
+++ b/exercises/practice/rna-transcription/.docs/introduction.md
@@ -0,0 +1,16 @@
+# Introduction
+
+You work for a bioengineering company that specializes in developing therapeutic solutions.
+
+Your team has just been given a new project to develop a targeted therapy for a rare type of cancer.
+
+~~~~exercism/note
+It's all very complicated, but the basic idea is that sometimes people's bodies produce too much of a given protein.
+That can cause all sorts of havoc.
+
+But if you can create a very specific molecule (called a micro-RNA), it can prevent the protein from being produced.
+
+This technique is called [RNA Interference][rnai].
+
+[rnai]: https://admin.acceleratingscience.com/ask-a-scientist/what-is-rnai/
+~~~~
diff --git a/exercises/practice/rna-transcription/.meta/config.json b/exercises/practice/rna-transcription/.meta/config.json
new file mode 100644
index 00000000..288881e3
--- /dev/null
+++ b/exercises/practice/rna-transcription/.meta/config.json
@@ -0,0 +1,13 @@
+{
+ "blurb": "Given a DNA strand, return its RNA Complement Transcription.",
+ "authors": ["ajborla"],
+ "contributors": [
+ ],
+ "files": {
+ "solution": ["zcl_rna_transcription.clas.abap"],
+ "test": ["zcl_rna_transcription.clas.testclasses.abap"],
+ "example": [".meta/zcl_rna_transcription.clas.abap"]
+ },
+ "source": "Hyperphysics",
+ "source_url": "https://web.archive.org/web/20220408112140/http://hyperphysics.phy-astr.gsu.edu/hbase/Organic/transcription.html"
+}
diff --git a/exercises/practice/rna-transcription/.meta/zcl_rna_transcription.clas.abap b/exercises/practice/rna-transcription/.meta/zcl_rna_transcription.clas.abap
new file mode 100644
index 00000000..b7313a76
--- /dev/null
+++ b/exercises/practice/rna-transcription/.meta/zcl_rna_transcription.clas.abap
@@ -0,0 +1,40 @@
+CLASS zcl_rna_transcription DEFINITION
+ PUBLIC
+ FINAL
+ CREATE PUBLIC.
+
+ PUBLIC SECTION.
+ METHODS
+ transcribe
+ IMPORTING
+ strand TYPE string
+ RETURNING
+ VALUE(result) TYPE string.
+
+ PROTECTED SECTION.
+ PRIVATE SECTION.
+
+ENDCLASS.
+
+
+CLASS zcl_rna_transcription IMPLEMENTATION.
+
+ METHOD transcribe.
+ DATA(offset) = 0.
+ result = ''.
+ DO strlen( strand ) TIMES.
+ CASE strand+offset(1).
+ WHEN 'A'.
+ result = result && 'U'.
+ WHEN 'C'.
+ result = result && 'G'.
+ WHEN 'G'.
+ result = result && 'C'.
+ WHEN 'T'.
+ result = result && 'A'.
+ ENDCASE.
+ offset = offset + 1.
+ ENDDO.
+ ENDMETHOD.
+
+ENDCLASS.
diff --git a/exercises/practice/rna-transcription/package.devc.xml b/exercises/practice/rna-transcription/package.devc.xml
new file mode 100644
index 00000000..1471c7a8
--- /dev/null
+++ b/exercises/practice/rna-transcription/package.devc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+ Exercism: RNA Transcription
+
+
+
+
diff --git a/exercises/practice/rna-transcription/zcl_rna_transcription.clas.abap b/exercises/practice/rna-transcription/zcl_rna_transcription.clas.abap
new file mode 100644
index 00000000..93bddfe5
--- /dev/null
+++ b/exercises/practice/rna-transcription/zcl_rna_transcription.clas.abap
@@ -0,0 +1,26 @@
+CLASS zcl_rna_transcription DEFINITION
+ PUBLIC
+ FINAL
+ CREATE PUBLIC.
+
+ PUBLIC SECTION.
+ METHODS
+ transcribe
+ IMPORTING
+ strand TYPE string
+ RETURNING
+ VALUE(result) TYPE string.
+
+ PROTECTED SECTION.
+ PRIVATE SECTION.
+
+ENDCLASS.
+
+
+CLASS zcl_rna_transcription IMPLEMENTATION.
+
+ METHOD transcribe.
+ "Implement solution
+ ENDMETHOD.
+
+ENDCLASS.
diff --git a/exercises/practice/rna-transcription/zcl_rna_transcription.clas.testclasses.abap b/exercises/practice/rna-transcription/zcl_rna_transcription.clas.testclasses.abap
new file mode 100644
index 00000000..9e445a3f
--- /dev/null
+++ b/exercises/practice/rna-transcription/zcl_rna_transcription.clas.testclasses.abap
@@ -0,0 +1,60 @@
+*"* use this source file for your ABAP unit test classes
+CLASS ltcl_rna_transcription DEFINITION FINAL FOR TESTING
+ DURATION SHORT
+ RISK LEVEL HARMLESS.
+
+ PRIVATE SECTION.
+ DATA cut TYPE REF TO zcl_rna_transcription.
+ METHODS setup.
+ METHODS:
+ empty_rna_sequence FOR TESTING,
+ rna_cmp_of_cytosine_is_guanine FOR TESTING,
+ rna_cmp_of_guanine_is_cytosine FOR TESTING,
+ rna_cmp_of_thymine_is_adenine FOR TESTING,
+ rna_cmp_of_adenine_is_uracil FOR TESTING,
+ rna_complement FOR TESTING.
+ENDCLASS.
+
+
+CLASS ltcl_rna_transcription IMPLEMENTATION.
+ METHOD setup.
+ cut = NEW zcl_rna_transcription( ).
+ ENDMETHOD.
+
+ METHOD empty_rna_sequence.
+ cl_abap_unit_assert=>assert_equals(
+ exp = ''
+ act = cut->transcribe( '' ) ).
+ ENDMETHOD.
+
+ METHOD rna_cmp_of_cytosine_is_guanine.
+ cl_abap_unit_assert=>assert_equals(
+ exp = 'G'
+ act = cut->transcribe( 'C' ) ).
+ ENDMETHOD.
+
+ METHOD rna_cmp_of_guanine_is_cytosine.
+ cl_abap_unit_assert=>assert_equals(
+ exp = 'C'
+ act = cut->transcribe( 'G' ) ).
+ ENDMETHOD.
+
+ METHOD rna_cmp_of_thymine_is_adenine.
+ cl_abap_unit_assert=>assert_equals(
+ exp = 'A'
+ act = cut->transcribe( 'T' ) ).
+ ENDMETHOD.
+
+ METHOD rna_cmp_of_adenine_is_uracil.
+ cl_abap_unit_assert=>assert_equals(
+ exp = 'U'
+ act = cut->transcribe( 'A' ) ).
+ ENDMETHOD.
+
+ METHOD rna_complement.
+ cl_abap_unit_assert=>assert_equals(
+ exp = 'UGCACCAGAAUU'
+ act = cut->transcribe( 'ACGTGGTCTTAA' ) ).
+ ENDMETHOD.
+
+ENDCLASS.
diff --git a/exercises/practice/rna-transcription/zcl_rna_transcription.clas.xml b/exercises/practice/rna-transcription/zcl_rna_transcription.clas.xml
new file mode 100644
index 00000000..ab84cfea
--- /dev/null
+++ b/exercises/practice/rna-transcription/zcl_rna_transcription.clas.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ ZCL_RNA_TRANSCRIPTION
+ E
+ Exercism: RNA Transcription
+ 1
+ X
+ X
+ X
+ X
+
+
+
+
diff --git a/exercises/practice/triangle/.docs/instructions.md b/exercises/practice/triangle/.docs/instructions.md
new file mode 100644
index 00000000..ac390087
--- /dev/null
+++ b/exercises/practice/triangle/.docs/instructions.md
@@ -0,0 +1,29 @@
+# Instructions
+
+Determine if a triangle is equilateral, isosceles, or scalene.
+
+An _equilateral_ triangle has all three sides the same length.
+
+An _isosceles_ triangle has at least two sides the same length.
+(It is sometimes specified as having exactly two sides the same length, but for the purposes of this exercise we'll say at least two.)
+
+A _scalene_ triangle has all sides of different lengths.
+
+## Note
+
+For a shape to be a triangle at all, all sides have to be of length > 0, and the sum of the lengths of any two sides must be greater than or equal to the length of the third side.
+
+In equations:
+
+Let `a`, `b`, and `c` be sides of the triangle.
+Then all three of the following expressions must be true:
+
+```text
+a + b ≥ c
+b + c ≥ a
+a + c ≥ b
+```
+
+See [Triangle Inequality][triangle-inequality]
+
+[triangle-inequality]: https://en.wikipedia.org/wiki/Triangle_inequality
diff --git a/exercises/practice/triangle/.meta/config.json b/exercises/practice/triangle/.meta/config.json
new file mode 100644
index 00000000..111120a8
--- /dev/null
+++ b/exercises/practice/triangle/.meta/config.json
@@ -0,0 +1,13 @@
+{
+ "blurb": "Determine if a triangle is equilateral, isosceles, or scalene.",
+ "authors": ["ajborla"],
+ "contributors": [
+ ],
+ "files": {
+ "solution": ["zcl_triangle.clas.abap"],
+ "test": ["zcl_triangle.clas.testclasses.abap"],
+ "example": [".meta/zcl_triangle.clas.abap"]
+ },
+ "source": "The Ruby Koans triangle project, parts 1 & 2",
+ "source_url": "https://web.archive.org/web/20220831105330/http://rubykoans.com"
+}
diff --git a/exercises/practice/triangle/.meta/zcl_triangle.clas.abap b/exercises/practice/triangle/.meta/zcl_triangle.clas.abap
new file mode 100644
index 00000000..9a7689f4
--- /dev/null
+++ b/exercises/practice/triangle/.meta/zcl_triangle.clas.abap
@@ -0,0 +1,127 @@
+CLASS zcl_triangle DEFINITION
+ PUBLIC
+ FINAL
+ CREATE PUBLIC.
+
+ PUBLIC SECTION.
+ METHODS:
+ is_equilateral
+ IMPORTING
+ side_a TYPE f
+ side_b TYPE f
+ side_c TYPE f
+ RETURNING
+ VALUE(result) TYPE abap_bool
+ RAISING
+ cx_parameter_invalid,
+ is_isosceles
+ IMPORTING
+ side_a TYPE f
+ side_b TYPE f
+ side_c TYPE f
+ RETURNING
+ VALUE(result) TYPE abap_bool
+ RAISING
+ cx_parameter_invalid,
+ is_scalene
+ IMPORTING
+ side_a TYPE f
+ side_b TYPE f
+ side_c TYPE f
+ RETURNING
+ VALUE(result) TYPE abap_bool
+ RAISING
+ cx_parameter_invalid.
+
+ PROTECTED SECTION.
+
+ PRIVATE SECTION.
+ METHODS:
+ has_negative_or_zero_sides
+ IMPORTING
+ side_a TYPE f
+ side_b TYPE f
+ side_c TYPE f
+ RETURNING
+ VALUE(result) TYPE abap_bool,
+ is_degenerate
+ IMPORTING
+ side_a TYPE f
+ side_b TYPE f
+ side_c TYPE f
+ RETURNING
+ VALUE(result) TYPE abap_bool.
+
+ENDCLASS.
+
+
+CLASS zcl_triangle IMPLEMENTATION.
+
+ METHOD is_equilateral.
+ " Eliminate invalid triangles
+ IF has_negative_or_zero_sides( side_a = side_a
+ side_b = side_b
+ side_c = side_c ) OR
+ is_degenerate( side_a = side_a
+ side_b = side_b
+ side_c = side_c ).
+ RAISE EXCEPTION TYPE cx_parameter_invalid.
+ ENDIF.
+ " Assume failure, and perform criteria check for this triangle type
+ result = abap_false.
+ IF side_a = side_b AND side_a = side_c.
+ result = abap_true.
+ ENDIF.
+ ENDMETHOD.
+
+ METHOD is_isosceles.
+ " Eliminate invalid triangles
+ IF has_negative_or_zero_sides( side_a = side_a
+ side_b = side_b
+ side_c = side_c ) OR
+ is_degenerate( side_a = side_a
+ side_b = side_b
+ side_c = side_c ).
+ RAISE EXCEPTION TYPE cx_parameter_invalid.
+ ENDIF.
+ " Assume failure, and perform criteria check for this triangle type
+ result = abap_false.
+ IF side_a = side_b OR side_a = side_c OR side_b = side_c.
+ result = abap_true.
+ ENDIF.
+ ENDMETHOD.
+
+ METHOD is_scalene.
+ " Eliminate invalid triangles
+ IF has_negative_or_zero_sides( side_a = side_a
+ side_b = side_b
+ side_c = side_c ) OR
+ is_degenerate( side_a = side_a
+ side_b = side_b
+ side_c = side_c ).
+ RAISE EXCEPTION TYPE cx_parameter_invalid.
+ ENDIF.
+ " Assume failure, and perform criteria check for this triangle type
+ result = abap_false.
+ IF side_a <> side_b AND side_a <> side_c AND side_b <> side_c.
+ result = abap_true.
+ ENDIF.
+ ENDMETHOD.
+
+ METHOD has_negative_or_zero_sides.
+ result = abap_false.
+ IF side_a <= 0.0 OR side_b <= 0.0 OR side_c <= 0.0.
+ result = abap_true.
+ ENDIF.
+ ENDMETHOD.
+
+ METHOD is_degenerate.
+ result = abap_false.
+ IF side_a + side_b <= side_c OR
+ side_a + side_c <= side_b OR
+ side_b + side_c <= side_a.
+ result = abap_true.
+ ENDIF.
+ ENDMETHOD.
+
+ENDCLASS.
diff --git a/exercises/practice/triangle/package.devc.xml b/exercises/practice/triangle/package.devc.xml
new file mode 100644
index 00000000..0ad23a78
--- /dev/null
+++ b/exercises/practice/triangle/package.devc.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+ Exercism: Triangle
+
+
+
+
diff --git a/exercises/practice/triangle/zcl_triangle.clas.abap b/exercises/practice/triangle/zcl_triangle.clas.abap
new file mode 100644
index 00000000..05d19c57
--- /dev/null
+++ b/exercises/practice/triangle/zcl_triangle.clas.abap
@@ -0,0 +1,56 @@
+CLASS zcl_triangle DEFINITION
+ PUBLIC
+ FINAL
+ CREATE PUBLIC.
+
+ PUBLIC SECTION.
+ METHODS:
+ is_equilateral
+ IMPORTING
+ side_a TYPE f
+ side_b TYPE f
+ side_c TYPE f
+ RETURNING
+ VALUE(result) TYPE abap_bool
+ RAISING
+ cx_parameter_invalid,
+ is_isosceles
+ IMPORTING
+ side_a TYPE f
+ side_b TYPE f
+ side_c TYPE f
+ RETURNING
+ VALUE(result) TYPE abap_bool
+ RAISING
+ cx_parameter_invalid,
+ is_scalene
+ IMPORTING
+ side_a TYPE f
+ side_b TYPE f
+ side_c TYPE f
+ RETURNING
+ VALUE(result) TYPE abap_bool
+ RAISING
+ cx_parameter_invalid.
+
+ PROTECTED SECTION.
+ PRIVATE SECTION.
+
+ENDCLASS.
+
+
+CLASS zcl_triangle IMPLEMENTATION.
+
+ METHOD is_equilateral.
+ "Implement solution
+ ENDMETHOD.
+
+ METHOD is_isosceles.
+ "Implement solution
+ ENDMETHOD.
+
+ METHOD is_scalene.
+ "Implement solution
+ ENDMETHOD.
+
+ENDCLASS.
diff --git a/exercises/practice/triangle/zcl_triangle.clas.testclasses.abap b/exercises/practice/triangle/zcl_triangle.clas.testclasses.abap
new file mode 100644
index 00000000..8d21c2f7
--- /dev/null
+++ b/exercises/practice/triangle/zcl_triangle.clas.testclasses.abap
@@ -0,0 +1,175 @@
+*"* use this source file for your ABAP unit test classes
+CLASS ltcl_triangle DEFINITION FINAL FOR TESTING
+ DURATION SHORT
+ RISK LEVEL HARMLESS.
+
+ PRIVATE SECTION.
+ DATA cut TYPE REF TO zcl_triangle.
+ METHODS setup.
+ METHODS:
+ equi_all_sides_equal FOR TESTING RAISING cx_static_check,
+ equi_any_side_is_unequal FOR TESTING RAISING cx_static_check,
+ equi_no_sides_equal FOR TESTING RAISING cx_static_check,
+ equi_all_zero_sides_not_tri FOR TESTING RAISING cx_static_check,
+ equi_sides_may_be_floats FOR TESTING RAISING cx_static_check,
+ isos_last_two_sides_equal FOR TESTING RAISING cx_static_check,
+ isos_first_two_sides_equal FOR TESTING RAISING cx_static_check,
+ isos_first_last_sides_equal FOR TESTING RAISING cx_static_check,
+ isos_equi_triangles_also_isos FOR TESTING RAISING cx_static_check,
+ isos_no_sides_equal FOR TESTING RAISING cx_static_check,
+ isos_first_tri_ineq_violation FOR TESTING RAISING cx_static_check,
+ isos_second_tri_ineq_violation FOR TESTING RAISING cx_static_check,
+ isos_third_tri_ineq_violation FOR TESTING RAISING cx_static_check,
+ isos_sides_may_be_floats FOR TESTING RAISING cx_static_check,
+ scal_no_sides_equal FOR TESTING RAISING cx_static_check,
+ scal_all_sides_equal FOR TESTING RAISING cx_static_check,
+ scal_first_second_sides_equal FOR TESTING RAISING cx_static_check,
+ scal_first_third_sides_equal FOR TESTING RAISING cx_static_check,
+ scal_second_third_sides_equal FOR TESTING RAISING cx_static_check,
+ scal_may_not_violate_tri_ineq FOR TESTING RAISING cx_static_check,
+ scal_sides_may_be_floats FOR TESTING RAISING cx_static_check.
+ENDCLASS.
+
+
+CLASS ltcl_triangle IMPLEMENTATION.
+ METHOD setup.
+ cut = NEW zcl_triangle( ).
+ ENDMETHOD.
+
+ METHOD equi_all_sides_equal.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_true
+ act = cut->is_equilateral( side_a = '2.0' side_b = '2.0' side_c = '2.0' ) ).
+ ENDMETHOD.
+
+ METHOD equi_any_side_is_unequal.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_false
+ act = cut->is_equilateral( side_a = '4.0' side_b = '4.0' side_c = '6.0' ) ).
+ ENDMETHOD.
+
+ METHOD equi_no_sides_equal.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_false
+ act = cut->is_equilateral( side_a = '4.0' side_b = '5.0' side_c = '6.0' ) ).
+ ENDMETHOD.
+
+ METHOD equi_all_zero_sides_not_tri.
+ TRY.
+ cut->is_equilateral( side_a = '0.0' side_b = '0.0' side_c = '0.0' ).
+ cl_abap_unit_assert=>fail( ).
+ CATCH cx_parameter_invalid.
+ ENDTRY.
+ ENDMETHOD.
+
+ METHOD equi_sides_may_be_floats.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_true
+ act = cut->is_equilateral( side_a = '1.5' side_b = '1.5' side_c = '1.5' ) ).
+ ENDMETHOD.
+
+ METHOD isos_last_two_sides_equal.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_true
+ act = cut->is_isosceles( side_a = '6.0' side_b = '4.0' side_c = '4.0' ) ).
+ ENDMETHOD.
+
+ METHOD isos_first_two_sides_equal.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_true
+ act = cut->is_isosceles( side_a = '4.0' side_b = '4.0' side_c = '6.0' ) ).
+ ENDMETHOD.
+
+ METHOD isos_first_last_sides_equal.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_true
+ act = cut->is_isosceles( side_a = '4.0' side_b = '6.0' side_c = '4.0' ) ).
+ ENDMETHOD.
+
+ METHOD isos_equi_triangles_also_isos.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_true
+ act = cut->is_isosceles( side_a = '4.0' side_b = '4.0' side_c = '4.0' ) ).
+ ENDMETHOD.
+
+ METHOD isos_no_sides_equal.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_false
+ act = cut->is_isosceles( side_a = '4.0' side_b = '5.0' side_c = '6.0' ) ).
+ ENDMETHOD.
+
+ METHOD isos_first_tri_ineq_violation.
+ TRY.
+ cut->is_isosceles( side_a = '1.0' side_b = '1.0' side_c = '3.0' ).
+ cl_abap_unit_assert=>fail( ).
+ CATCH cx_parameter_invalid.
+ ENDTRY.
+ ENDMETHOD.
+
+ METHOD isos_second_tri_ineq_violation.
+ TRY.
+ cut->is_isosceles( side_a = '1.0' side_b = '3.0' side_c = '1.0' ).
+ cl_abap_unit_assert=>fail( ).
+ CATCH cx_parameter_invalid.
+ ENDTRY.
+ ENDMETHOD.
+
+ METHOD isos_third_tri_ineq_violation.
+ TRY.
+ cut->is_isosceles( side_a = '3.0' side_b = '1.0' side_c = '1.0' ).
+ cl_abap_unit_assert=>fail( ).
+ CATCH cx_parameter_invalid.
+ ENDTRY.
+ ENDMETHOD.
+
+ METHOD isos_sides_may_be_floats.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_true
+ act = cut->is_isosceles( side_a = '1.5' side_b = '1.5' side_c = '2.5' ) ).
+ ENDMETHOD.
+
+ METHOD scal_no_sides_equal.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_true
+ act = cut->is_isosceles( side_a = '4.0' side_b = '5.0' side_c = '6.0' ) ).
+ ENDMETHOD.
+
+ METHOD scal_all_sides_equal.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_false
+ act = cut->is_scalene( side_a = '2.0' side_b = '2.0' side_c = '2.0' ) ).
+ ENDMETHOD.
+
+ METHOD scal_first_second_sides_equal.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_false
+ act = cut->is_scalene( side_a = '4.0' side_b = '4.0' side_c = '6.0' ) ).
+ ENDMETHOD.
+
+ METHOD scal_first_third_sides_equal.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_false
+ act = cut->is_scalene( side_a = '4.0' side_b = '6.0' side_c = '4.0' ) ).
+ ENDMETHOD.
+
+ METHOD scal_second_third_sides_equal.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_false
+ act = cut->is_scalene( side_a = '6.0' side_b = '4.0' side_c = '4.0' ) ).
+ ENDMETHOD.
+
+ METHOD scal_may_not_violate_tri_ineq.
+ TRY.
+ cut->is_scalene( side_a = '4.0' side_b = '8.0' side_c = '3.0' ).
+ cl_abap_unit_assert=>fail( ).
+ CATCH cx_parameter_invalid.
+ ENDTRY.
+ ENDMETHOD.
+
+ METHOD scal_sides_may_be_floats.
+ cl_abap_unit_assert=>assert_equals(
+ exp = abap_true
+ act = cut->is_scalene( side_a = '4.5' side_b = '5.5' side_c = '6.5' ) ).
+ ENDMETHOD.
+
+ENDCLASS.
diff --git a/exercises/practice/triangle/zcl_triangle.clas.xml b/exercises/practice/triangle/zcl_triangle.clas.xml
new file mode 100644
index 00000000..51aa5489
--- /dev/null
+++ b/exercises/practice/triangle/zcl_triangle.clas.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+ ZCL_TRIANGLE
+ E
+ Exercism: Triangle
+ 1
+ X
+ X
+ X
+ X
+
+
+
+