diff --git a/config.json b/config.json index ba5d89a..7957b29 100644 --- a/config.json +++ b/config.json @@ -171,6 +171,14 @@ "practices": [], "prerequisites": [], "difficulty": 3 + }, + { + "slug": "hamming", + "name": "Hamming", + "uuid": "8877f43f-ae4b-4946-957f-5eeb6a4e681f", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/hamming/.docs/instructions.md b/exercises/practice/hamming/.docs/instructions.md new file mode 100644 index 0000000..020fdd0 --- /dev/null +++ b/exercises/practice/hamming/.docs/instructions.md @@ -0,0 +1,27 @@ +# Instructions + +Calculate the Hamming Distance between two DNA strands. + +Your body is made up of cells that contain DNA. +Those cells regularly wear out and need replacing, which they achieve by dividing into daughter cells. +In fact, the average human body experiences about 10 quadrillion cell divisions in a lifetime! + +When cells divide, their DNA replicates too. +Sometimes during this process mistakes happen and single pieces of DNA get encoded with the incorrect information. +If we compare two strands of DNA and count the differences between them we can see how many mistakes occurred. +This is known as the "Hamming Distance". + +We read DNA using the letters C,A,G and T. +Two strands might look like this: + + GAGCCTACTAACGGGAT + CATCGTAATGACGGCCT + ^ ^ ^ ^ ^ ^^ + +They have 7 differences, and therefore the Hamming Distance is 7. + +The Hamming Distance is useful for lots of things in science, not just biology, so it's a nice phrase to be familiar with :) + +## Implementation notes + +The Hamming distance is only defined for sequences of equal length, so an attempt to calculate it between sequences of different lengths should not work. diff --git a/exercises/practice/hamming/.meta/config.json b/exercises/practice/hamming/.meta/config.json new file mode 100644 index 0000000..e8dc2cd --- /dev/null +++ b/exercises/practice/hamming/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "erikschierboom" + ], + "files": { + "solution": [ + "src/hamming.art" + ], + "test": [ + "tests/test-hamming.art" + ], + "example": [ + ".meta/src/example.art" + ] + }, + "blurb": "Calculate the Hamming difference between two DNA strands.", + "source": "The Calculating Point Mutations problem at Rosalind", + "source_url": "https://rosalind.info/problems/hamm/" +} diff --git a/exercises/practice/hamming/.meta/src/example.art b/exercises/practice/hamming/.meta/src/example.art new file mode 100644 index 0000000..880d36b --- /dev/null +++ b/exercises/practice/hamming/.meta/src/example.art @@ -0,0 +1,5 @@ +distance: function [strand1 strand2][ + if (size strand1) <> (size strand2) -> return null + + enumerate (couple (to [:char] strand1) (to [:char] strand2)) 'pair -> (first pair) <> (last pair) +] diff --git a/exercises/practice/hamming/.meta/tests.toml b/exercises/practice/hamming/.meta/tests.toml new file mode 100644 index 0000000..5dc17ed --- /dev/null +++ b/exercises/practice/hamming/.meta/tests.toml @@ -0,0 +1,67 @@ +# 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. + +[f6dcb64f-03b0-4b60-81b1-3c9dbf47e887] +description = "empty strands" + +[54681314-eee2-439a-9db0-b0636c656156] +description = "single letter identical strands" + +[294479a3-a4c8-478f-8d63-6209815a827b] +description = "single letter different strands" + +[9aed5f34-5693-4344-9b31-40c692fb5592] +description = "long identical strands" + +[cd2273a5-c576-46c8-a52b-dee251c3e6e5] +description = "long different strands" + +[919f8ef0-b767-4d1b-8516-6379d07fcb28] +description = "disallow first strand longer" +include = false + +[b9228bb1-465f-4141-b40f-1f99812de5a8] +description = "disallow first strand longer" +reimplements = "919f8ef0-b767-4d1b-8516-6379d07fcb28" + +[8a2d4ed0-ead5-4fdd-924d-27c4cf56e60e] +description = "disallow second strand longer" +include = false + +[dab38838-26bb-4fff-acbe-3b0a9bfeba2d] +description = "disallow second strand longer" +reimplements = "8a2d4ed0-ead5-4fdd-924d-27c4cf56e60e" + +[5dce058b-28d4-4ca7-aa64-adfe4e17784c] +description = "disallow left empty strand" +include = false + +[db92e77e-7c72-499d-8fe6-9354d2bfd504] +description = "disallow left empty strand" +include = false +reimplements = "5dce058b-28d4-4ca7-aa64-adfe4e17784c" + +[b764d47c-83ff-4de2-ab10-6cfe4b15c0f3] +description = "disallow empty first strand" +reimplements = "db92e77e-7c72-499d-8fe6-9354d2bfd504" + +[38826d4b-16fb-4639-ac3e-ba027dec8b5f] +description = "disallow right empty strand" +include = false + +[920cd6e3-18f4-4143-b6b8-74270bb8f8a3] +description = "disallow right empty strand" +include = false +reimplements = "38826d4b-16fb-4639-ac3e-ba027dec8b5f" + +[9ab9262f-3521-4191-81f5-0ed184a5aa89] +description = "disallow empty second strand" +reimplements = "920cd6e3-18f4-4143-b6b8-74270bb8f8a3" diff --git a/exercises/practice/hamming/src/hamming.art b/exercises/practice/hamming/src/hamming.art new file mode 100644 index 0000000..8b35788 --- /dev/null +++ b/exercises/practice/hamming/src/hamming.art @@ -0,0 +1,3 @@ +distance: function [strand1 strand2][ + panic "Please implement the hamming function" +] diff --git a/exercises/practice/hamming/tester.art b/exercises/practice/hamming/tester.art new file mode 100644 index 0000000..80f4a8f --- /dev/null +++ b/exercises/practice/hamming/tester.art @@ -0,0 +1,3 @@ +import {unitt}! + +runTests.failFast findTests "tests" diff --git a/exercises/practice/hamming/tests/test-hamming.art b/exercises/practice/hamming/tests/test-hamming.art new file mode 100644 index 0000000..287e443 --- /dev/null +++ b/exercises/practice/hamming/tests/test-hamming.art @@ -0,0 +1,49 @@ +import {unitt}! +import {src/hamming}! + +suite "Hamming" [ + test "empty strands" [ + result: distance "" "" + assert -> 0 = result + ] + + test.skip "single letter identical strands" [ + result: distance "A" "A" + assert -> 0 = result + ] + + test.skip "long indentical strands" [ + result: distance "GGACTGAAATCTG" "GGACTGAAATCTG" + assert -> 0 = result + ] + + test.skip "single letter different strands" [ + result: distance "G" "T" + assert -> 1 = result + ] + + test.skip "long different strands" [ + result: distance "GGACGGATTCTG" "AGGACGGATTCT" + assert -> 9 = result + ] + + test.skip "disallow empty first strand" [ + result: distance "" "G" + assert -> null = result + ] + + test.skip "disallow first strand longer" [ + result: distance "AATG" "AAA" + assert -> null = result + ] + + test.skip "disallow second strand longer" [ + result: distance "ATA" "AGTG" + assert -> null = result + ] + + test.skip "disallow empty second strand" [ + result: distance "G" "" + assert -> null = result + ] +]