From b0e94d2d85932fae37e05912f82e420ac921e3dc Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Sun, 26 May 2024 13:08:23 +0200 Subject: [PATCH 1/5] Add `nucleotide-count` exercise --- config.json | 8 +++++ .../nucleotide-count/.docs/instructions.md | 23 +++++++++++++++ .../nucleotide-count/.meta/config.json | 19 ++++++++++++ .../nucleotide-count/.meta/src/example.art | 10 +++++++ .../nucleotide-count/.meta/tests.toml | 25 ++++++++++++++++ .../nucleotide-count/src/nucleotide-count.art | 3 ++ .../practice/nucleotide-count/tester.art | 3 ++ .../tests/test-nucleotide-count.art | 29 +++++++++++++++++++ 8 files changed, 120 insertions(+) create mode 100644 exercises/practice/nucleotide-count/.docs/instructions.md create mode 100644 exercises/practice/nucleotide-count/.meta/config.json create mode 100644 exercises/practice/nucleotide-count/.meta/src/example.art create mode 100644 exercises/practice/nucleotide-count/.meta/tests.toml create mode 100644 exercises/practice/nucleotide-count/src/nucleotide-count.art create mode 100644 exercises/practice/nucleotide-count/tester.art create mode 100644 exercises/practice/nucleotide-count/tests/test-nucleotide-count.art diff --git a/config.json b/config.json index 5839c1c..d6fc8c8 100644 --- a/config.json +++ b/config.json @@ -100,6 +100,14 @@ "prerequisites": [], "difficulty": 2 }, + { + "slug": "nucleotide-count", + "name": "Nucleotide Count", + "uuid": "6fc1e4ab-157d-4237-b5dd-9686d3b03feb", + "practices": [], + "prerequisites": [], + "difficulty": 3 + }, { "slug": "sum-of-multiples", "name": "Sum of Multiples", 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..4c5d329 --- /dev/null +++ b/exercises/practice/nucleotide-count/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "erikschierboom" + ], + "files": { + "solution": [ + "src/nucleotide-count.art" + ], + "test": [ + "tests/test-nucleotide-count.art" + ], + "example": [ + ".meta/src/example.art" + ] + }, + "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/src/example.art b/exercises/practice/nucleotide-count/.meta/src/example.art new file mode 100644 index 0000000..ff8206f --- /dev/null +++ b/exercises/practice/nucleotide-count/.meta/src/example.art @@ -0,0 +1,10 @@ +nucleotideCounts: function [strand][ + fold strand .seed:#[A: 0, C: 0, G: 0, T: 0] [dict, nucleotide][ + try? [ + dict\[nucleotide]: inc dict\[nucleotide] + dict + ] else [ + return null + ] + ] +] 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/src/nucleotide-count.art b/exercises/practice/nucleotide-count/src/nucleotide-count.art new file mode 100644 index 0000000..0a3bfd0 --- /dev/null +++ b/exercises/practice/nucleotide-count/src/nucleotide-count.art @@ -0,0 +1,3 @@ +nucleotideCounts: function [strand][ + panic "Please implement the nucleotideCounts function" +] diff --git a/exercises/practice/nucleotide-count/tester.art b/exercises/practice/nucleotide-count/tester.art new file mode 100644 index 0000000..80f4a8f --- /dev/null +++ b/exercises/practice/nucleotide-count/tester.art @@ -0,0 +1,3 @@ +import {unitt}! + +runTests.failFast findTests "tests" diff --git a/exercises/practice/nucleotide-count/tests/test-nucleotide-count.art b/exercises/practice/nucleotide-count/tests/test-nucleotide-count.art new file mode 100644 index 0000000..9953b05 --- /dev/null +++ b/exercises/practice/nucleotide-count/tests/test-nucleotide-count.art @@ -0,0 +1,29 @@ +import {unitt}! +import {src/nucleotide-count}! + +suite "Nucleotide Count" [ + test "empty strand" [ + result: nucleotideCounts "" + assert -> #[A: 0, C: 0, G: 0, T: 0] = result + ] + + test.skip "can count one nucleotide in single-character input" [ + result: nucleotideCounts "G" + assert -> #[A: 0, C: 0, G: 1, T: 0] = result + ] + + test.skip "strand with repeated nucleotide" [ + result: nucleotideCounts "GGGGGGG" + assert -> #[A: 0, C: 0, G: 7, T: 0] = result + ] + + test.skip "strand with multiple nucleotides" [ + result: nucleotideCounts "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC" + assert -> #[A: 20, C: 12, G: 17, T: 21] = result + ] + + test.skip "strand with invalid nucleotides" [ + result: nucleotideCounts "AGXXACT" + assert -> null = result + ] +] From a741933f92194c671b518eec4a6dc088d051f026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Sun, 26 May 2024 11:29:16 -0700 Subject: [PATCH 2/5] Rewrite example --- .../nucleotide-count/.meta/src/example.art | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/exercises/practice/nucleotide-count/.meta/src/example.art b/exercises/practice/nucleotide-count/.meta/src/example.art index ff8206f..31cbe29 100644 --- a/exercises/practice/nucleotide-count/.meta/src/example.art +++ b/exercises/practice/nucleotide-count/.meta/src/example.art @@ -1,10 +1,8 @@ -nucleotideCounts: function [strand][ - fold strand .seed:#[A: 0, C: 0, G: 0, T: 0] [dict, nucleotide][ - try? [ - dict\[nucleotide]: inc dict\[nucleotide] - dict - ] else [ - return null - ] - ] -] +nucleotideCounts: function [strand][ + fold.seed:#[A: 0 C: 0 G: 0 T: 0] strand [acc, nucleotide][ + switch not? contains? keys acc to :string nucleotide + -> return null + -> acc\[nucleotide]: inc acc\[nucleotide] + acc + ] +] From 4814b607dd920e30ae16037796c260636d4be4dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Mon, 27 May 2024 13:45:16 -0700 Subject: [PATCH 3/5] Change fold to loop in example --- .../nucleotide-count/.meta/src/example.art | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/exercises/practice/nucleotide-count/.meta/src/example.art b/exercises/practice/nucleotide-count/.meta/src/example.art index 31cbe29..cb2661c 100644 --- a/exercises/practice/nucleotide-count/.meta/src/example.art +++ b/exercises/practice/nucleotide-count/.meta/src/example.art @@ -1,8 +1,10 @@ -nucleotideCounts: function [strand][ - fold.seed:#[A: 0 C: 0 G: 0 T: 0] strand [acc, nucleotide][ - switch not? contains? keys acc to :string nucleotide - -> return null - -> acc\[nucleotide]: inc acc\[nucleotide] - acc - ] -] +nucleotideCounts: function [strand][ + counts: #[A: 0 C: 0 G: 0 T: 0] + loop strand 'nucleotide [ + switch not? contains? keys counts to :string nucleotide + -> return null + -> counts\[nucleotide]: inc counts\[nucleotide] + ] + + counts +] \ No newline at end of file From 1e9c61f762cfd99ea26e773066290c3b71c78185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Mon, 27 May 2024 13:45:47 -0700 Subject: [PATCH 4/5] Pre-calculate dictionaries --- .../tests/test-nucleotide-count.art | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/exercises/practice/nucleotide-count/tests/test-nucleotide-count.art b/exercises/practice/nucleotide-count/tests/test-nucleotide-count.art index 9953b05..876e224 100644 --- a/exercises/practice/nucleotide-count/tests/test-nucleotide-count.art +++ b/exercises/practice/nucleotide-count/tests/test-nucleotide-count.art @@ -2,27 +2,31 @@ import {unitt}! import {src/nucleotide-count}! suite "Nucleotide Count" [ - test "empty strand" [ + test "an empty strand does not increment the counts" [ result: nucleotideCounts "" - assert -> #[A: 0, C: 0, G: 0, T: 0] = result + expected: #[A: 0 C: 0 G: 0 T: 0] + assert -> expected = result ] - test.skip "can count one nucleotide in single-character input" [ + test.skip "a strand with one nucleotide increments that nucleotide's count" [ result: nucleotideCounts "G" - assert -> #[A: 0, C: 0, G: 1, T: 0] = result + expected: #[A: 0 C: 0 G: 1 T: 0] + assert -> expected = result ] - test.skip "strand with repeated nucleotide" [ + test.skip "a strand with a repeated nucleotide increments that nucleotide's count" [ result: nucleotideCounts "GGGGGGG" - assert -> #[A: 0, C: 0, G: 7, T: 0] = result + expected: #[A: 0 C: 0 G: 7 T: 0] + assert -> expected = result ] - test.skip "strand with multiple nucleotides" [ + test.skip "a strand with multiple nucleotides increments the respective nucleotide counts" [ result: nucleotideCounts "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC" - assert -> #[A: 20, C: 12, G: 17, T: 21] = result + expected: #[A: 20 C: 12 G: 17 T: 21] + assert -> expected = result ] - test.skip "strand with invalid nucleotides" [ + test.skip "a strand with invalid nucleotides returns null instead" [ result: nucleotideCounts "AGXXACT" assert -> null = result ] From 8bb2527d9f79d0b29c5e05f31531a07e4c901c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Mon, 27 May 2024 13:45:57 -0700 Subject: [PATCH 5/5] Add self as contributor --- exercises/practice/nucleotide-count/.meta/config.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/exercises/practice/nucleotide-count/.meta/config.json b/exercises/practice/nucleotide-count/.meta/config.json index 4c5d329..1859b48 100644 --- a/exercises/practice/nucleotide-count/.meta/config.json +++ b/exercises/practice/nucleotide-count/.meta/config.json @@ -2,6 +2,9 @@ "authors": [ "erikschierboom" ], + "contributors": [ + "BNAndras" + ], "files": { "solution": [ "src/nucleotide-count.art"