aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rust/rna-transcription/.exercism/metadata.json1
-rw-r--r--rust/rna-transcription/.gitignore8
-rw-r--r--rust/rna-transcription/Cargo.toml4
-rw-r--r--rust/rna-transcription/README.md110
-rw-r--r--rust/rna-transcription/src/lib.rs38
-rw-r--r--rust/rna-transcription/tests/rna-transcription.rs79
6 files changed, 240 insertions, 0 deletions
diff --git a/rust/rna-transcription/.exercism/metadata.json b/rust/rna-transcription/.exercism/metadata.json
new file mode 100644
index 0000000..675c014
--- /dev/null
+++ b/rust/rna-transcription/.exercism/metadata.json
@@ -0,0 +1 @@
{"track":"rust","exercise":"rna-transcription","id":"61fd9a0e46f34d86a5a5bb75f4a6a2a8","url":"https://exercism.io/my/solutions/61fd9a0e46f34d86a5a5bb75f4a6a2a8","handle":"dyamon","is_requester":true,"auto_approve":false} \ No newline at end of file
diff --git a/rust/rna-transcription/.gitignore b/rust/rna-transcription/.gitignore
new file mode 100644
index 0000000..db7f315
--- /dev/null
+++ b/rust/rna-transcription/.gitignore
@@ -0,0 +1,8 @@
1# Generated by Cargo
2# will have compiled files and executables
3/target/
4**/*.rs.bk
5
6# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
7# More information here http://doc.crates.io/guide.html#cargotoml-vs-cargolock
8Cargo.lock
diff --git a/rust/rna-transcription/Cargo.toml b/rust/rna-transcription/Cargo.toml
new file mode 100644
index 0000000..00b5540
--- /dev/null
+++ b/rust/rna-transcription/Cargo.toml
@@ -0,0 +1,4 @@
1[package]
2edition = "2018"
3name = "rna-transcription"
4version = "1.0.0"
diff --git a/rust/rna-transcription/README.md b/rust/rna-transcription/README.md
new file mode 100644
index 0000000..f94ecab
--- /dev/null
+++ b/rust/rna-transcription/README.md
@@ -0,0 +1,110 @@
1# RNA Transcription
2
3Given a DNA strand, return its RNA complement (per RNA transcription).
4
5Both DNA and RNA strands are a sequence of nucleotides.
6
7The four nucleotides found in DNA are adenine (**A**), cytosine (**C**),
8guanine (**G**) and thymine (**T**).
9
10The four nucleotides found in RNA are adenine (**A**), cytosine (**C**),
11guanine (**G**) and uracil (**U**).
12
13Given a DNA strand, its transcribed RNA strand is formed by replacing
14each nucleotide with its complement:
15
16* `G` -> `C`
17* `C` -> `G`
18* `T` -> `A`
19* `A` -> `U`
20
21## Notes on Rust implementation
22
23By using private fields in structs with public `new` functions returning
24`Option` or `Result` (as here with `DNA::new` & `RNA::new`), we can guarantee
25that the internal representation of `DNA` is correct. Because every valid DNA
26string has a valid RNA string, we don't need to return a `Result`/`Option` from
27`into_rna`.
28
29This explains the type signatures you will see in the tests.
30
31
32## Rust Installation
33
34Refer to the [exercism help page][help-page] for Rust installation and learning
35resources.
36
37## Writing the Code
38
39Execute the tests with:
40
41```bash
42$ cargo test
43```
44
45All but the first test have been ignored. After you get the first test to
46pass, open the tests source file which is located in the `tests` directory
47and remove the `#[ignore]` flag from the next test and get the tests to pass
48again. Each separate test is a function with `#[test]` flag above it.
49Continue, until you pass every test.
50
51If you wish to run all ignored tests without editing the tests source file, use:
52
53```bash
54$ cargo test -- --ignored
55```
56
57To run a specific test, for example `some_test`, you can use:
58
59```bash
60$ cargo test some_test
61```
62
63If the specific test is ignored use:
64
65```bash
66$ cargo test some_test -- --ignored
67```
68
69To learn more about Rust tests refer to the [online test documentation][rust-tests]
70
71Make sure to read the [Modules][modules] chapter if you
72haven't already, it will help you with organizing your files.
73
74## Further improvements
75
76After you have solved the exercise, please consider using the additional utilities, described in the [installation guide](https://exercism.io/tracks/rust/installation), to further refine your final solution.
77
78To format your solution, inside the solution directory use
79
80```bash
81cargo fmt
82```
83
84To see, if your solution contains some common ineffective use cases, inside the solution directory use
85
86```bash
87cargo clippy --all-targets
88```
89
90## Submitting the solution
91
92Generally you should submit all files in which you implemented your solution (`src/lib.rs` in most cases). If you are using any external crates, please consider submitting the `Cargo.toml` file. This will make the review process faster and clearer.
93
94## Feedback, Issues, Pull Requests
95
96The [exercism/rust](https://github.com/exercism/rust) repository on GitHub is the home for all of the Rust exercises. If you have feedback about an exercise, or want to help implement new exercises, head over there and create an issue. Members of the rust track team are happy to help!
97
98If you want to know more about Exercism, take a look at the [contribution guide](https://github.com/exercism/docs/blob/master/contributing-to-language-tracks/README.md).
99
100[help-page]: https://exercism.io/tracks/rust/learning
101[modules]: https://doc.rust-lang.org/book/ch07-02-defining-modules-to-control-scope-and-privacy.html
102[cargo]: https://doc.rust-lang.org/book/ch14-00-more-about-cargo.html
103[rust-tests]: https://doc.rust-lang.org/book/ch11-02-running-tests.html
104
105## Source
106
107Hyperphysics [http://hyperphysics.phy-astr.gsu.edu/hbase/Organic/transcription.html](http://hyperphysics.phy-astr.gsu.edu/hbase/Organic/transcription.html)
108
109## Submitting Incomplete Solutions
110It's possible to submit an incomplete solution so you can see how others have completed the exercise.
diff --git a/rust/rna-transcription/src/lib.rs b/rust/rna-transcription/src/lib.rs
new file mode 100644
index 0000000..425f406
--- /dev/null
+++ b/rust/rna-transcription/src/lib.rs
@@ -0,0 +1,38 @@
1#[derive(Debug, PartialEq)]
2pub struct Dna(String);
3
4#[derive(Debug, PartialEq)]
5pub struct Rna(String);
6
7impl Dna {
8 pub fn new(dna: &str) -> Result<Dna, usize> {
9 dna.chars()
10 .enumerate()
11 .find(|(_, n)| !"ACGT".contains(*n))
12 .map_or_else(|| Ok(Dna(dna.to_string())), |(i, _)| Err(i))
13 }
14
15 pub fn into_rna(self) -> Rna {
16 Rna(self
17 .0
18 .as_str()
19 .chars()
20 .map(|n| match n {
21 'A' => 'U',
22 'C' => 'G',
23 'G' => 'C',
24 'T' => 'A',
25 a => a,
26 })
27 .collect())
28 }
29}
30
31impl Rna {
32 pub fn new(rna: &str) -> Result<Rna, usize> {
33 rna.chars()
34 .enumerate()
35 .find(|(_, n)| !"ACGU".contains(*n))
36 .map_or_else(|| Ok(Rna(rna.to_string())), |(i, _)| Err(i))
37 }
38}
diff --git a/rust/rna-transcription/tests/rna-transcription.rs b/rust/rna-transcription/tests/rna-transcription.rs
new file mode 100644
index 0000000..bc96a4f
--- /dev/null
+++ b/rust/rna-transcription/tests/rna-transcription.rs
@@ -0,0 +1,79 @@
1use rna_transcription as dna;
2
3#[test]
4fn test_valid_dna_input() {
5 assert!(dna::Dna::new("GCTA").is_ok());
6}
7
8#[test]
9fn test_valid_rna_input() {
10 assert!(dna::Rna::new("CGAU").is_ok());
11}
12
13#[test]
14fn test_invalid_dna_input() {
15 // Invalid character
16 assert_eq!(dna::Dna::new("X").err(), Some(0));
17 // Valid nucleotide, but invalid in context
18 assert_eq!(dna::Dna::new("U").err(), Some(0));
19 // Longer string with contained errors
20 assert_eq!(dna::Dna::new("ACGTUXXCTTAA").err(), Some(4));
21}
22
23#[test]
24fn test_invalid_rna_input() {
25 // Invalid character
26 assert_eq!(dna::Rna::new("X").unwrap_err(), 0);
27 // Valid nucleotide, but invalid in context
28 assert_eq!(dna::Rna::new("T").unwrap_err(), 0);
29 // Longer string with contained errors
30 assert_eq!(dna::Rna::new("ACGUTTXCUUAA").unwrap_err(), 4);
31}
32
33#[test]
34fn test_acid_equals_acid() {
35 assert_eq!(dna::Dna::new("CGA").unwrap(), dna::Dna::new("CGA").unwrap());
36 assert_ne!(dna::Dna::new("CGA").unwrap(), dna::Dna::new("AGC").unwrap());
37 assert_eq!(dna::Rna::new("CGA").unwrap(), dna::Rna::new("CGA").unwrap());
38 assert_ne!(dna::Rna::new("CGA").unwrap(), dna::Rna::new("AGC").unwrap());
39}
40
41#[test]
42fn test_transcribes_cytosine_guanine() {
43 assert_eq!(
44 dna::Rna::new("G").unwrap(),
45 dna::Dna::new("C").unwrap().into_rna()
46 );
47}
48
49#[test]
50fn test_transcribes_guanine_cytosine() {
51 assert_eq!(
52 dna::Rna::new("C").unwrap(),
53 dna::Dna::new("G").unwrap().into_rna()
54 );
55}
56
57#[test]
58fn test_transcribes_adenine_uracil() {
59 assert_eq!(
60 dna::Rna::new("U").unwrap(),
61 dna::Dna::new("A").unwrap().into_rna()
62 );
63}
64
65#[test]
66fn test_transcribes_thymine_to_adenine() {
67 assert_eq!(
68 dna::Rna::new("A").unwrap(),
69 dna::Dna::new("T").unwrap().into_rna()
70 );
71}
72
73#[test]
74fn test_transcribes_all_dna_to_rna() {
75 assert_eq!(
76 dna::Rna::new("UGCACCAGAAUU").unwrap(),
77 dna::Dna::new("ACGTGGTCTTAA").unwrap().into_rna()
78 )
79}