Skip to content

Commit

Permalink
Add nucleotide-count
Browse files Browse the repository at this point in the history
  • Loading branch information
BNAndras committed Sep 11, 2024
1 parent ed45779 commit 019ba77
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,14 @@
"prerequisites": [],
"difficulty": 2
},
{
"slug": "nucleotide-count",
"name": "Nucleotide Count",
"uuid": "8380e348-348c-4197-9cd4-34fd9c70c71b",
"practices": [],
"prerequisites": [],
"difficulty": 2
},
{
"slug": "pangram",
"name": "Pangram",
Expand Down
23 changes: 23 additions & 0 deletions exercises/practice/nucleotide-count/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -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
```
22 changes: 22 additions & 0 deletions exercises/practice/nucleotide-count/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"authors": [
"BNAndras"
],
"files": {
"solution": [
"src/lib.cairo"
],
"test": [
"tests/nucleotide_count.cairo"
],
"example": [
".meta/example.cairo"
],
"invalidator": [
"Scarb.toml"
]
},
"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/"
}
30 changes: 30 additions & 0 deletions exercises/practice/nucleotide-count/.meta/example.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#[derive(Debug, Default, Drop, PartialEq)]
pub struct Counter {
pub a: u64,
pub c: u64,
pub g: u64,
pub t: u64
}

pub fn counts(strand: ByteArray) -> Counter {
let mut counter: Counter = Default::default();
let mut i = 0;

while i < strand.len() {
let chr = strand[i];
if chr == 'A' {
counter.a += 1;
} else if chr == 'C' {
counter.c += 1;
} else if chr == 'G' {
counter.g += 1;
} else if chr == 'T' {
counter.t += 1;
} else {
panic!("Invalid nucleotide in strand");
}
i += 1;
};

counter
}
25 changes: 25 additions & 0 deletions exercises/practice/nucleotide-count/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -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"
7 changes: 7 additions & 0 deletions exercises/practice/nucleotide-count/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "nucleotide_count"
version = "0.1.0"
edition = "2024_07"

[dev-dependencies]
cairo_test = "2.7.1"
11 changes: 11 additions & 0 deletions exercises/practice/nucleotide-count/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#[derive(Debug, Drop, PartialEq)]
pub struct Counter {
pub a: u64,
pub c: u64,
pub g: u64,
pub t: u64
}

pub fn counts(strand: ByteArray) -> Counter {
panic!("implement `counts`")
}
43 changes: 43 additions & 0 deletions exercises/practice/nucleotide-count/tests/nucleotide_count.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use nucleotide_count::{counts, Counter};

#[test]
fn empty_strand() {
let strand = "";
let output = counts(strand);
let expected = Counter { a: 0, c: 0, g: 0, t: 0 };
assert_eq!(output, expected);
}

#[test]
#[ignore]
fn can_count_one_nucleotide_in_single_character_input() {
let strand = "G";
let output = counts(strand);
let expected = Counter { a: 0, c: 0, g: 1, t: 0 };
assert_eq!(output, expected);
}

#[test]
#[ignore]
fn strand_with_repeated_nucleotide() {
let strand = "GGGGGGG";
let output = counts(strand);
let expected = Counter { a: 0, c: 0, g: 7, t: 0 };
assert_eq!(output, expected);
}

#[test]
#[ignore]
fn strand_with_multiple_nucleotides() {
let strand = "AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC";
let output = counts(strand);
let expected = Counter { a: 20, c: 12, g: 17, t: 21 };
assert_eq!(output, expected);
}

#[test]
#[ignore]
#[should_panic(expected: ("Invalid nucleotide in strand",))]
fn strand_with_invalid_nucleotides() {
counts("AGXXACT");
}

0 comments on commit 019ba77

Please sign in to comment.