diff --git a/config.json b/config.json index a97f994..3725d5f 100644 --- a/config.json +++ b/config.json @@ -110,6 +110,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "nucleotide-count", + "name": "Nucleotide Count", + "uuid": "9a2d0b74-0cba-464d-a960-8f7469be50a1", + "practices": [], + "prerequisites": [], + "difficulty": 2 } ] }, diff --git a/exercises/practice/nucleotide-count/.busted b/exercises/practice/nucleotide-count/.busted new file mode 100644 index 0000000..86b84e7 --- /dev/null +++ b/exercises/practice/nucleotide-count/.busted @@ -0,0 +1,5 @@ +return { + default = { + ROOT = { '.' } + } +} diff --git a/exercises/practice/nucleotide-count/.docs/instructions.md b/exercises/practice/nucleotide-count/.docs/instructions.md new file mode 100644 index 0000000..548d9ba --- /dev/null +++ b/exercises/practice/nucleotide-count/.docs/instructions.md @@ -0,0 +1,23 @@ +# Instructions + +Each of us inherits from our biological parents a set of chemical instructions known as DNA that influence how our bodies are constructed. +All known life depends on DNA! + +> Note: You do not need to understand anything about nucleotides or DNA to complete this exercise. + +DNA is a long chain of other chemicals and the most important are the four nucleotides, adenine, cytosine, guanine and thymine. +A single DNA chain can contain billions of these four nucleotides and the order in which they occur is important! +We call the order of these nucleotides in a bit of DNA a "DNA sequence". + +We represent a DNA sequence as an ordered collection of these four nucleotides and a common way to do that is with a string of characters such as "ATTACG" for a DNA sequence of 6 nucleotides. +'A' for adenine, 'C' for cytosine, 'G' for guanine, and 'T' for thymine. + +Given a string representing a DNA sequence, count how many of each nucleotide is present. +If the string contains characters that aren't A, C, G, or T then it is invalid and you should signal an error. + +For example: + +```text +"GATTACA" -> 'A': 3, 'C': 1, 'G': 1, 'T': 2 +"INVALID" -> error +``` diff --git a/exercises/practice/nucleotide-count/.meta/config.json b/exercises/practice/nucleotide-count/.meta/config.json new file mode 100644 index 0000000..a89d28f --- /dev/null +++ b/exercises/practice/nucleotide-count/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "glennj" + ], + "files": { + "solution": [ + "nucleotide_count.moon" + ], + "test": [ + "nucleotide_count_spec.moon" + ], + "example": [ + ".meta/example.moon" + ] + }, + "blurb": "Given a DNA string, compute how many times each nucleotide occurs in the string.", + "source": "The Calculating DNA Nucleotides_problem at Rosalind", + "source_url": "https://rosalind.info/problems/dna/" +} diff --git a/exercises/practice/nucleotide-count/.meta/example.moon b/exercises/practice/nucleotide-count/.meta/example.moon new file mode 100644 index 0000000..8122409 --- /dev/null +++ b/exercises/practice/nucleotide-count/.meta/example.moon @@ -0,0 +1,8 @@ +return (strand) -> + counts = A: 0, C: 0, G: 0, T: 0 + + for char in strand\gmatch(".") + error 'Invalid nucleotide in strand' unless counts[char] + counts[char] += 1 + + counts diff --git a/exercises/practice/nucleotide-count/.meta/spec_generator.moon b/exercises/practice/nucleotide-count/.meta/spec_generator.moon new file mode 100644 index 0000000..db3ecd1 --- /dev/null +++ b/exercises/practice/nucleotide-count/.meta/spec_generator.moon @@ -0,0 +1,20 @@ +{ + module_name: 'nucleotide_count', + + generate_test: (case, level) -> + local lines + if case.expected.error + lines = { + "f = -> nucleotide_count '#{case.input.strand}'", + "assert.has.errors f, '#{case.expected.error}'" + } + else + -- use "same", not "equal", to compare tables + lines = { + "expected = A: #{case.expected.A}, C: #{case.expected.C}, G: #{case.expected.G}, T: #{case.expected.T}" + "result = nucleotide_count '#{case.input.strand}'", + "assert.are.same expected, result" + } + + table.concat [indent line, level for line in *lines], '\n' +} diff --git a/exercises/practice/nucleotide-count/.meta/tests.toml b/exercises/practice/nucleotide-count/.meta/tests.toml new file mode 100644 index 0000000..7c55e53 --- /dev/null +++ b/exercises/practice/nucleotide-count/.meta/tests.toml @@ -0,0 +1,25 @@ +# 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. + +[3e5c30a8-87e2-4845-a815-a49671ade970] +description = "empty strand" + +[a0ea42a6-06d9-4ac6-828c-7ccaccf98fec] +description = "can count one nucleotide in single-character input" + +[eca0d565-ed8c-43e7-9033-6cefbf5115b5] +description = "strand with repeated nucleotide" + +[40a45eac-c83f-4740-901a-20b22d15a39f] +description = "strand with multiple nucleotides" + +[b4c47851-ee9e-4b0a-be70-a86e343bd851] +description = "strand with invalid nucleotides" diff --git a/exercises/practice/nucleotide-count/nucleotide_count.moon b/exercises/practice/nucleotide-count/nucleotide_count.moon new file mode 100644 index 0000000..911f666 --- /dev/null +++ b/exercises/practice/nucleotide-count/nucleotide_count.moon @@ -0,0 +1,4 @@ +counter = (strand) -> + error 'Implement me' + +return counter diff --git a/exercises/practice/nucleotide-count/nucleotide_count_spec.moon b/exercises/practice/nucleotide-count/nucleotide_count_spec.moon new file mode 100644 index 0000000..cc18d9c --- /dev/null +++ b/exercises/practice/nucleotide-count/nucleotide_count_spec.moon @@ -0,0 +1,26 @@ +nucleotide_count = require 'nucleotide_count' + +describe 'nucleotide-count', -> + it 'empty strand', -> + expected = A: 0, C: 0, G: 0, T: 0 + result = nucleotide_count '' + assert.are.same expected, result + + pending 'can count one nucleotide in single-character input', -> + expected = A: 0, C: 0, G: 1, T: 0 + result = nucleotide_count 'G' + assert.are.same expected, result + + pending 'strand with repeated nucleotide', -> + expected = A: 0, C: 0, G: 7, T: 0 + result = nucleotide_count 'GGGGGGG' + assert.are.same expected, result + + pending 'strand with multiple nucleotides', -> + expected = A: 20, C: 12, G: 17, T: 21 + result = nucleotide_count 'AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC' + assert.are.same expected, result + + pending 'strand with invalid nucleotides', -> + f = -> nucleotide_count 'AGXXACT' + assert.has.errors f, 'Invalid nucleotide in strand'