trackler 2.2.1.179 → 2.2.1.180

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/yacht/description.md +14 -13
  4. data/tracks/ballerina/config.json +1 -0
  5. data/tracks/coffeescript/config.json +138 -41
  6. data/tracks/coffeescript/docs/ABOUT.md +3 -7
  7. data/tracks/coq/config.json +1 -0
  8. data/tracks/d/config.json +1 -0
  9. data/tracks/dart/config.json +1 -0
  10. data/tracks/elixir/config.json +17 -16
  11. data/tracks/elixir/docs/ABOUT.md +10 -2
  12. data/tracks/fortran/config.json +1 -0
  13. data/tracks/gnu-apl/config.json +1 -0
  14. data/tracks/go/config.json +13 -0
  15. data/tracks/go/exercises/list-ops/README.md +27 -0
  16. data/tracks/go/exercises/list-ops/example.go +99 -0
  17. data/tracks/go/exercises/list-ops/listops_test.go +291 -0
  18. data/tracks/groovy/config.json +1 -0
  19. data/tracks/haxe/config.json +1 -0
  20. data/tracks/perl5/exercises/leap/.meta/exercise-data.yaml +3 -5
  21. data/tracks/perl5/exercises/leap/.meta/solutions/Leap.pm +2 -4
  22. data/tracks/perl5/exercises/leap/Leap.pm +1 -1
  23. data/tracks/perl5/exercises/leap/leap.t +2 -2
  24. data/tracks/php/config.json +1 -0
  25. data/tracks/plsql/config.json +1 -0
  26. data/tracks/pony/config.json +1 -0
  27. data/tracks/purescript/config.json +1 -0
  28. data/tracks/reasonml/config/exercise_readme.go.tmpl +18 -2
  29. data/tracks/reasonml/exercises/anagram/README.md +15 -4
  30. data/tracks/reasonml/exercises/armstrong-numbers/README.md +3 -4
  31. data/tracks/reasonml/exercises/binary-search/README.md +14 -7
  32. data/tracks/reasonml/exercises/bob/README.md +14 -6
  33. data/tracks/reasonml/exercises/change/README.md +2 -4
  34. data/tracks/reasonml/exercises/hello-world/README.md +2 -3
  35. data/tracks/reasonml/exercises/isogram/README.md +4 -6
  36. data/tracks/reasonml/exercises/leap/README.md +14 -4
  37. data/tracks/reasonml/exercises/pangram/README.md +13 -3
  38. data/tracks/reasonml/exercises/phone-number/README.md +15 -7
  39. data/tracks/reasonml/exercises/raindrops/README.md +14 -7
  40. data/tracks/reasonml/exercises/rna-transcription/README.md +13 -3
  41. data/tracks/reasonml/exercises/roman-numerals/README.md +4 -8
  42. data/tracks/reasonml/exercises/run-length-encoding/README.md +14 -7
  43. data/tracks/reasonml/exercises/space-age/README.md +13 -3
  44. data/tracks/reasonml/exercises/word-count/README.md +18 -8
  45. data/tracks/rust/.travis.yml +1 -0
  46. data/tracks/rust/_test/check-exercises-for-authors.sh +10 -0
  47. data/tracks/rust/bin/format_exercises +2 -0
  48. data/tracks/rust/exercises/accumulate/Cargo.toml +0 -1
  49. data/tracks/rust/exercises/accumulate/example.rs +4 -1
  50. data/tracks/rust/exercises/acronym/example.rs +6 -5
  51. data/tracks/rust/exercises/acronym/tests/acronym.rs +1 -1
  52. data/tracks/rust/exercises/all-your-base/example.rs +8 -2
  53. data/tracks/rust/exercises/allergies/example.rs +28 -6
  54. data/tracks/rust/exercises/alphametics/example.rs +18 -10
  55. data/tracks/rust/exercises/anagram/example.rs +8 -4
  56. data/tracks/rust/exercises/atbash-cipher/example.rs +15 -15
  57. data/tracks/rust/exercises/beer-song/example.rs +18 -12
  58. data/tracks/rust/exercises/binary-search/Cargo.toml +0 -1
  59. data/tracks/rust/exercises/binary-search/example.rs +3 -4
  60. data/tracks/rust/exercises/bob/example.rs +11 -5
  61. data/tracks/rust/exercises/book-store/Cargo-example.toml +0 -1
  62. data/tracks/rust/exercises/book-store/Cargo.toml +0 -1
  63. data/tracks/rust/exercises/book-store/example.rs +15 -19
  64. data/tracks/rust/exercises/bowling/example.rs +3 -1
  65. data/tracks/rust/exercises/bracket-push/example.rs +7 -2
  66. data/tracks/rust/exercises/circular-buffer/example.rs +1 -1
  67. data/tracks/rust/exercises/clock/.meta/ALLOWED_TO_NOT_COMPILE +3 -0
  68. data/tracks/rust/exercises/clock/Cargo.toml +0 -1
  69. data/tracks/rust/exercises/clock/example.rs +5 -3
  70. data/tracks/rust/exercises/clock/src/lib.rs +14 -0
  71. data/tracks/rust/exercises/collatz-conjecture/example.rs +2 -2
  72. data/tracks/rust/exercises/crypto-square/Cargo-example.toml +0 -1
  73. data/tracks/rust/exercises/crypto-square/Cargo.toml +0 -1
  74. data/tracks/rust/exercises/custom-set/example.rs +17 -15
  75. data/tracks/rust/exercises/decimal/Cargo-example.toml +0 -1
  76. data/tracks/rust/exercises/decimal/Cargo.toml +0 -1
  77. data/tracks/rust/exercises/decimal/example.rs +5 -5
  78. data/tracks/rust/exercises/diamond/Cargo.toml +0 -1
  79. data/tracks/rust/exercises/difference-of-squares/example.rs +1 -1
  80. data/tracks/rust/exercises/dominoes/example.rs +20 -19
  81. data/tracks/rust/exercises/etl/example.rs +4 -3
  82. data/tracks/rust/exercises/forth/example.rs +29 -45
  83. data/tracks/rust/exercises/grade-school/example.rs +4 -2
  84. data/tracks/rust/exercises/hexadecimal/example.rs +2 -4
  85. data/tracks/rust/exercises/isbn-verifier/example.rs +5 -6
  86. data/tracks/rust/exercises/isbn-verifier/tests/isbn-verifier.rs +12 -0
  87. data/tracks/rust/exercises/isogram/example.rs +9 -3
  88. data/tracks/rust/exercises/largest-series-product/example.rs +2 -1
  89. data/tracks/rust/exercises/luhn-from/example.rs +3 -1
  90. data/tracks/rust/exercises/luhn/example.rs +5 -3
  91. data/tracks/rust/exercises/macros/Cargo.toml +0 -1
  92. data/tracks/rust/exercises/nth-prime/Cargo.toml +0 -1
  93. data/tracks/rust/exercises/nth-prime/example.rs +6 -6
  94. data/tracks/rust/exercises/nucleotide-codons/Cargo.toml +0 -1
  95. data/tracks/rust/exercises/nucleotide-codons/example.rs +23 -17
  96. data/tracks/rust/exercises/nucleotide-count/example.rs +15 -5
  97. data/tracks/rust/exercises/nucleotide-count/src/lib.rs +15 -0
  98. data/tracks/rust/exercises/nucleotide-count/tests/nucleotide-count.rs +3 -3
  99. data/tracks/rust/exercises/palindrome-products/Cargo.toml +0 -1
  100. data/tracks/rust/exercises/pangram/example.rs +6 -6
  101. data/tracks/rust/exercises/parallel-letter-frequency/example.rs +7 -4
  102. data/tracks/rust/exercises/pascals-triangle/example.rs +6 -2
  103. data/tracks/rust/exercises/perfect-numbers/example.rs +2 -2
  104. data/tracks/rust/exercises/phone-number/example.rs +11 -15
  105. data/tracks/rust/exercises/pig-latin/Cargo-example.toml +0 -1
  106. data/tracks/rust/exercises/pig-latin/Cargo.toml +0 -1
  107. data/tracks/rust/exercises/pig-latin/example.rs +6 -2
  108. data/tracks/rust/exercises/poker/Cargo-example.toml +0 -1
  109. data/tracks/rust/exercises/poker/Cargo.toml +0 -1
  110. data/tracks/rust/exercises/poker/example.rs +9 -8
  111. data/tracks/rust/exercises/prime-factors/Cargo.toml +0 -1
  112. data/tracks/rust/exercises/prime-factors/example.rs +1 -1
  113. data/tracks/rust/exercises/protein-translation/Cargo.toml +0 -1
  114. data/tracks/rust/exercises/protein-translation/example.rs +6 -5
  115. data/tracks/rust/exercises/proverb/Cargo.toml +0 -1
  116. data/tracks/rust/exercises/proverb/example.rs +0 -1
  117. data/tracks/rust/exercises/pythagorean-triplet/Cargo.toml +0 -1
  118. data/tracks/rust/exercises/pythagorean-triplet/example.rs +3 -3
  119. data/tracks/rust/exercises/queen-attack/example.rs +3 -3
  120. data/tracks/rust/exercises/react/example.rs +61 -29
  121. data/tracks/rust/exercises/reverse-string/Cargo.toml +0 -1
  122. data/tracks/rust/exercises/rna-transcription/example.rs +17 -9
  123. data/tracks/rust/exercises/robot-name/example.rs +4 -3
  124. data/tracks/rust/exercises/robot-simulator/example.rs +5 -2
  125. data/tracks/rust/exercises/roman-numerals/example.rs +15 -14
  126. data/tracks/rust/exercises/rotational-cipher/Cargo.toml +0 -1
  127. data/tracks/rust/exercises/rotational-cipher/example.rs +10 -14
  128. data/tracks/rust/exercises/rotational-cipher/src/lib.rs +7 -1
  129. data/tracks/rust/exercises/run-length-encoding/Cargo.toml +0 -1
  130. data/tracks/rust/exercises/run-length-encoding/example.rs +34 -29
  131. data/tracks/rust/exercises/saddle-points/example.rs +0 -1
  132. data/tracks/rust/exercises/say/Cargo.toml +0 -1
  133. data/tracks/rust/exercises/say/example.rs +34 -8
  134. data/tracks/rust/exercises/series/example.rs +6 -8
  135. data/tracks/rust/exercises/simple-linked-list/example.rs +0 -2
  136. data/tracks/rust/exercises/spiral-matrix/example.rs +0 -1
  137. data/tracks/rust/exercises/tournament/example.rs +33 -20
  138. data/tracks/rust/exercises/triangle/example.rs +1 -1
  139. data/tracks/rust/exercises/two-bucket/example.rs +2 -6
  140. data/tracks/rust/exercises/two-fer/example.rs +3 -3
  141. data/tracks/rust/exercises/variable-length-quantity/example.rs +2 -3
  142. data/tracks/rust/exercises/word-count/example.rs +4 -1
  143. data/tracks/rust/exercises/wordy/example.rs +10 -4
  144. metadata +7 -2
@@ -1,7 +1,8 @@
1
1
  use std::collections::BTreeMap;
2
2
 
3
3
  pub fn transform(input: &BTreeMap<i32, Vec<char>>) -> BTreeMap<char, i32> {
4
- input.iter().flat_map(|(&n, vec)| {
5
- vec.iter().map(move |c| (c.to_ascii_lowercase(), n))
6
- }).collect()
4
+ input
5
+ .iter()
6
+ .flat_map(|(&n, vec)| vec.iter().map(move |c| (c.to_ascii_lowercase(), n)))
7
+ .collect()
7
8
  }
@@ -41,10 +41,9 @@ impl FromStr for Term {
41
41
  match s {
42
42
  ":" => Ok(StartDefinition),
43
43
  ";" => Ok(EndDefinition),
44
- _ => Err(())
45
- }
46
- .or_else(|_| Value::from_str(s).map(Number))
47
- .or_else(|_| Ok(Word(s.to_ascii_lowercase())))
44
+ _ => Err(()),
45
+ }.or_else(|_| Value::from_str(s).map(Number))
46
+ .or_else(|_| Ok(Word(s.to_ascii_lowercase())))
48
47
  }
49
48
  }
50
49
 
@@ -77,15 +76,16 @@ impl Forth {
77
76
 
78
77
  fn step_term(&mut self, term: Term) -> ForthResult {
79
78
  match term {
80
- Number(value) => self.push(value),
81
- Word(word) => self.step_word(word),
79
+ Number(value) => self.push(value),
80
+ Word(word) => self.step_word(word),
82
81
  StartDefinition => self.store_definition(),
83
- EndDefinition => Err(Error::InvalidWord),
82
+ EndDefinition => Err(Error::InvalidWord),
84
83
  }
85
84
  }
86
85
 
87
86
  fn step_word(&mut self, word: String) -> ForthResult {
88
- self.defs.get(&word)
87
+ self.defs
88
+ .get(&word)
89
89
  .ok_or(Error::UnknownWord)
90
90
  .map(Clone::clone)
91
91
  .map(|mut code| self.code.append(&mut code))
@@ -94,32 +94,17 @@ impl Forth {
94
94
 
95
95
  fn step_built_in(&mut self, word: &String) -> ForthResult {
96
96
  match word.as_ref() {
97
- "+" =>
98
- self.bin_op(|(a, b)| Ok(a + b)),
99
- "-" =>
100
- self.bin_op(|(a, b)| Ok(a - b)),
101
- "*" =>
102
- self.bin_op(|(a, b)| Ok(a * b)),
103
- "/" =>
104
- self.bin_op(|(a, b)| {
105
- a.checked_div(b).ok_or(Error::DivisionByZero)
106
- }),
107
- "dup" =>
108
- self.pop().and_then(|a| {
109
- self.push(a).and(self.push(a))
110
- }),
111
- "drop" =>
112
- self.pop().and(Forth::ok()),
113
- "swap" =>
114
- self.pop_two().and_then(|(a, b)| {
115
- self.push(b).and(self.push(a))
116
- }),
117
- "over" =>
118
- self.pop_two().and_then(|(a, b)| {
119
- self.push(a).and(self.push(b)).and(self.push(a))
120
- }),
121
- _ =>
122
- Err(Error::UnknownWord)
97
+ "+" => self.bin_op(|(a, b)| Ok(a + b)),
98
+ "-" => self.bin_op(|(a, b)| Ok(a - b)),
99
+ "*" => self.bin_op(|(a, b)| Ok(a * b)),
100
+ "/" => self.bin_op(|(a, b)| a.checked_div(b).ok_or(Error::DivisionByZero)),
101
+ "dup" => self.pop().and_then(|a| self.push(a).and(self.push(a))),
102
+ "drop" => self.pop().and(Forth::ok()),
103
+ "swap" => self.pop_two()
104
+ .and_then(|(a, b)| self.push(b).and(self.push(a))),
105
+ "over" => self.pop_two()
106
+ .and_then(|(a, b)| self.push(a).and(self.push(b)).and(self.push(a))),
107
+ _ => Err(Error::UnknownWord),
123
108
  }
124
109
  }
125
110
 
@@ -129,8 +114,8 @@ impl Forth {
129
114
  loop {
130
115
  match self.code.pop_front() {
131
116
  Some(EndDefinition) => break,
132
- Some(term) => def.push_back(term),
133
- None => return Err(Error::InvalidWord),
117
+ Some(term) => def.push_back(term),
118
+ None => return Err(Error::InvalidWord),
134
119
  }
135
120
  }
136
121
 
@@ -147,20 +132,17 @@ impl Forth {
147
132
  }
148
133
 
149
134
  fn pop(&mut self) -> StackResult<Value> {
150
- self.stack.pop_back()
151
- .ok_or(Error::StackUnderflow)
135
+ self.stack.pop_back().ok_or(Error::StackUnderflow)
152
136
  }
153
137
 
154
138
  fn pop_two(&mut self) -> StackResult<(Value, Value)> {
155
- self.pop()
156
- .and_then(|b| {
157
- self.pop()
158
- .and_then(|a| Ok((a, b)))
159
- })
139
+ self.pop().and_then(|b| self.pop().and_then(|a| Ok((a, b))))
160
140
  }
161
141
 
162
142
  fn bin_op<F>(&mut self, op: F) -> ForthResult
163
- where F: FnOnce((Value, Value)) -> StackResult<Value> {
143
+ where
144
+ F: FnOnce((Value, Value)) -> StackResult<Value>,
145
+ {
164
146
  self.pop_two()
165
147
  .and_then(op)
166
148
  .and_then(|value| self.push(value))
@@ -180,5 +162,7 @@ impl Forth {
180
162
  .collect()
181
163
  }
182
164
 
183
- fn ok() -> ForthResult { Ok(()) }
165
+ fn ok() -> ForthResult {
166
+ Ok(())
167
+ }
184
168
  }
@@ -1,12 +1,14 @@
1
1
  use std::collections::HashMap;
2
2
 
3
3
  pub struct School {
4
- grades: HashMap<u32, Vec<String>>
4
+ grades: HashMap<u32, Vec<String>>,
5
5
  }
6
6
 
7
7
  impl School {
8
8
  pub fn new() -> School {
9
- School { grades: HashMap::new() }
9
+ School {
10
+ grades: HashMap::new(),
11
+ }
10
12
  }
11
13
 
12
14
  pub fn add(&mut self, grade: u32, student: &str) {
@@ -16,7 +16,7 @@ fn parse_hex_digit(c: char) -> Option<i64> {
16
16
  'd' => Some(13),
17
17
  'e' => Some(14),
18
18
  'f' => Some(15),
19
- _ => None,
19
+ _ => None,
20
20
  }
21
21
  }
22
22
 
@@ -28,8 +28,6 @@ pub fn hex_to_int(string: &str) -> Option<i64> {
28
28
  .rev()
29
29
  .enumerate()
30
30
  .fold(Some(0), |acc, (pos, c)| {
31
- parse_hex_digit(c).and_then(|n| {
32
- acc.map(|acc| acc + n * base.pow(pos as u32))
33
- })
31
+ parse_hex_digit(c).and_then(|n| acc.map(|acc| acc + n * base.pow(pos as u32)))
34
32
  })
35
33
  }
@@ -8,14 +8,13 @@ enum IsbnType {
8
8
  /// Checks if an 'X' is valid at the given position for the given ISBN type
9
9
  #[allow(non_snake_case)]
10
10
  fn is_X_valid(position: &usize, isbn_type: &IsbnType) -> bool {
11
- (isbn_type == &IsbnType::Isbn10 && position == &9 ) ||
12
- (isbn_type == &IsbnType::Isbn13 && position == &12)
11
+ (isbn_type == &IsbnType::Isbn10 && position == &9)
12
+ || (isbn_type == &IsbnType::Isbn13 && position == &12)
13
13
  }
14
14
 
15
15
  /// Checks if a '-' is valid at the given position for the given ISBN type
16
16
  fn is_dash_valid(position: &usize, isbn_type: &IsbnType) -> bool {
17
- isbn_type == &IsbnType::Isbn13 &&
18
- (position == &1 || position == &5 || position == &11)
17
+ isbn_type == &IsbnType::Isbn13 && (position == &1 || position == &5 || position == &11)
19
18
  }
20
19
 
21
20
  /// Determines whether the supplied string is a valid ISBN number
@@ -30,10 +29,10 @@ pub fn is_valid_isbn(isbn: &str) -> bool {
30
29
  let mut coefficient = 10;
31
30
  for (position, c) in isbn.char_indices() {
32
31
  let digit_value = match c {
33
- '0' ... '9' => c.to_digit(10).unwrap(),
32
+ '0'...'9' => c.to_digit(10).unwrap(),
34
33
  'X' if is_X_valid(&position, &isbn_type) => 10,
35
34
  '-' if is_dash_valid(&position, &isbn_type) => continue,
36
- _ => return false,
35
+ _ => return false,
37
36
  };
38
37
 
39
38
  checksum += coefficient * digit_value;
@@ -75,6 +75,18 @@ fn test_invalid_isbn_too_long() {
75
75
  assert!(!is_valid_isbn("3-598-21507-XX"));
76
76
  }
77
77
 
78
+ #[test]
79
+ #[ignore]
80
+ fn test_valid_digits_invalid_length() {
81
+ assert!(!is_valid_isbn("35982150881"));
82
+ }
83
+
84
+ #[test]
85
+ #[ignore]
86
+ fn test_special_characters() {
87
+ assert!(!is_valid_isbn("!@#%!@"));
88
+ }
89
+
78
90
  #[test]
79
91
  #[ignore]
80
92
  #[allow(non_snake_case)]
@@ -1,12 +1,18 @@
1
1
  pub fn check(word: &str) -> bool {
2
-
3
2
  // Filter all non-Alphabetic character out and collect them in a new String
4
- let normalized_string: String = word.to_lowercase().chars().filter(|c| c.is_alphabetic()).collect();
3
+ let normalized_string: String = word.to_lowercase()
4
+ .chars()
5
+ .filter(|c| c.is_alphabetic())
6
+ .collect();
5
7
 
6
8
  /* Find the char element from back and front and compare the index.
7
9
  If it is the same unique char the index will be the same.*/
8
10
  let is_unique = |x: char, word: &str| word.find(x).unwrap() == word.rfind(x).unwrap();
9
11
 
10
12
  // Length should be the same if it is a isogram
11
- normalized_string.len() == normalized_string.chars().filter(|&x| is_unique(x, normalized_string.as_str())).count()
13
+ normalized_string.len()
14
+ == normalized_string
15
+ .chars()
16
+ .filter(|&x| is_unique(x, normalized_string.as_str()))
17
+ .count()
12
18
  }
@@ -13,7 +13,8 @@ pub fn lsp(string_digits: &str, span: usize) -> Result<u64, Error> {
13
13
  return Err(Error::InvalidDigit(invalid));
14
14
  }
15
15
 
16
- let products: Vec<u64> = string_digits.chars()
16
+ let products: Vec<u64> = string_digits
17
+ .chars()
17
18
  .map(|c| c.to_digit(10).unwrap() as u64)
18
19
  .collect::<Vec<u64>>()
19
20
  .windows(span)
@@ -21,7 +21,9 @@ impl Luhn {
21
21
 
22
22
  impl From<String> for Luhn {
23
23
  fn from(s: String) -> Self {
24
- Luhn { digits: s.chars().collect() }
24
+ Luhn {
25
+ digits: s.chars().collect(),
26
+ }
25
27
  }
26
28
  }
27
29
 
@@ -1,10 +1,12 @@
1
1
  pub fn is_valid(candidate: &str) -> bool {
2
- if candidate.chars().filter(|c| c.is_digit(10)).take(2).count() <= 1 ||
3
- candidate.chars().any(|c| !c.is_digit(10) && c != ' ') {
2
+ if candidate.chars().filter(|c| c.is_digit(10)).take(2).count() <= 1
3
+ || candidate.chars().any(|c| !c.is_digit(10) && c != ' ')
4
+ {
4
5
  return false;
5
6
  }
6
7
 
7
- candidate.chars()
8
+ candidate
9
+ .chars()
8
10
  .filter_map(|c| c.to_digit(10))
9
11
  .rev()
10
12
  .enumerate()
@@ -1,6 +1,5 @@
1
1
  [package]
2
2
  name = "macros"
3
3
  version = "0.1.0"
4
- authors = ["Peter Goodspeed-Niklaus <peter.r.goodspeedniklaus@gmail.com>"]
5
4
 
6
5
  [dependencies]
@@ -1,6 +1,5 @@
1
1
  [package]
2
2
  name = "nth_prime"
3
3
  version = "1.0.0"
4
- authors = ["sacherjj <sacherjj@gmail.com>"]
5
4
 
6
5
  [dependencies]
@@ -1,12 +1,12 @@
1
1
  fn is_prime(n: u32) -> bool {
2
2
  let mut i: u32 = 3;
3
3
  while (i * i) < (n + 1) {
4
- if n % i == 0 {
5
- return false;
6
- }
7
- i += 1;
8
- }
9
- return true;
4
+ if n % i == 0 {
5
+ return false;
6
+ }
7
+ i += 1;
8
+ }
9
+ return true;
10
10
  }
11
11
 
12
12
  pub fn nth(n: u32) -> Option<u32> {
@@ -1,4 +1,3 @@
1
1
  [package]
2
2
  name = "nucleotide_codons"
3
3
  version = "0.1.0"
4
- authors = ["Peter Minten <peter@pminten.nl>"]
@@ -1,36 +1,42 @@
1
1
  use std::collections::HashMap;
2
2
 
3
3
  pub struct CodonInfo<'a> {
4
- actual_codons: HashMap<&'a str, &'a str>
4
+ actual_codons: HashMap<&'a str, &'a str>,
5
5
  }
6
6
 
7
7
  pub fn parse<'a>(pairs: Vec<(&'a str, &'a str)>) -> CodonInfo<'a> {
8
- CodonInfo{
9
- actual_codons: pairs.into_iter().collect()
8
+ CodonInfo {
9
+ actual_codons: pairs.into_iter().collect(),
10
10
  }
11
11
  }
12
12
 
13
13
  impl<'a> CodonInfo<'a> {
14
14
  pub fn name_for(&self, codon: &str) -> Result<&'a str, &'static str> {
15
15
  if codon.len() != 3 {
16
- return Err("invalid length")
16
+ return Err("invalid length");
17
17
  }
18
18
 
19
19
  let mut valid = true;
20
- let lookup: String = codon.chars().map(|l| {
21
- // Get an example of a "letter" represented by the possibly encoded letter.
22
- // Since every codon represented by the compressed notation has to be of
23
- // the desired amino acid just picking one at random will do.
24
- match l {
25
- 'A' | 'W' | 'M' | 'R' | 'D' | 'H' | 'V' | 'N' => 'A',
26
- 'C' | 'S' | 'Y' | 'B' => 'C',
27
- 'G' | 'K' => 'G',
28
- 'T' => 'T',
29
- _ => { valid = false; ' ' }
30
- }
31
- }).collect();
20
+ let lookup: String = codon
21
+ .chars()
22
+ .map(|l| {
23
+ // Get an example of a "letter" represented by the possibly encoded letter.
24
+ // Since every codon represented by the compressed notation has to be of
25
+ // the desired amino acid just picking one at random will do.
26
+ match l {
27
+ 'A' | 'W' | 'M' | 'R' | 'D' | 'H' | 'V' | 'N' => 'A',
28
+ 'C' | 'S' | 'Y' | 'B' => 'C',
29
+ 'G' | 'K' => 'G',
30
+ 'T' => 'T',
31
+ _ => {
32
+ valid = false;
33
+ ' '
34
+ }
35
+ }
36
+ })
37
+ .collect();
32
38
  if !valid {
33
- return Err("invalid char")
39
+ return Err("invalid char");
34
40
  }
35
41
 
36
42
  // If the input table is correct (which it is) every valid codon is in it
@@ -2,13 +2,23 @@ use std::collections::HashMap;
2
2
 
3
3
  static VALID_NUCLEOTIDES: &'static str = "ACGT";
4
4
 
5
- pub fn count(nucleotide: char, input: &str) -> Result<usize, char> {
6
- let valid = |x: char| { VALID_NUCLEOTIDES.contains(x) };
7
- if valid(nucleotide) && input.chars().all(valid) {
8
- Ok(input.chars().filter(|&c| c == nucleotide).count())
5
+ fn valid(c: char) -> Result<char, char> {
6
+ if VALID_NUCLEOTIDES.contains(c) {
7
+ Ok(c)
9
8
  } else {
10
- Err(nucleotide)
9
+ Err(c)
10
+ }
11
+ }
12
+
13
+ pub fn count(nucleotide: char, input: &str) -> Result<usize, char> {
14
+ valid(nucleotide)?;
15
+ let mut count = 0;
16
+ for c in input.chars() {
17
+ if valid(c)? == nucleotide {
18
+ count += 1;
19
+ }
11
20
  }
21
+ Ok(count)
12
22
  }
13
23
 
14
24
  pub fn nucleotide_counts(input: &str) -> Result<HashMap<char, usize>, char> {
@@ -1 +1,16 @@
1
+ use std::collections::HashMap;
1
2
 
3
+ pub fn count(nucleotide: char, dna: &str) -> Result<usize, char> {
4
+ unimplemented!(
5
+ "How much of nucleotide type '{}' is contained inside DNA string '{}'?",
6
+ nucleotide,
7
+ dna
8
+ );
9
+ }
10
+
11
+ pub fn nucleotide_counts(dna: &str) -> Result<HashMap<char, usize>, char> {
12
+ unimplemented!(
13
+ "How much of every nucleotide type is contained inside DNA string '{}'?",
14
+ dna
15
+ );
16
+ }
@@ -29,13 +29,13 @@ fn test_count_empty() {
29
29
  #[test]
30
30
  #[ignore]
31
31
  fn count_invalid_nucleotide() {
32
- assert!(dna::count('X', "A").is_err());
32
+ assert_eq!(dna::count('X', "A"), Err('X'));
33
33
  }
34
34
 
35
35
  #[test]
36
36
  #[ignore]
37
37
  fn count_invalid_dna() {
38
- assert!(dna::count('A', "AX").is_err());
38
+ assert_eq!(dna::count('A', "AX"), Err('X'));
39
39
  }
40
40
 
41
41
  #[test]
@@ -81,5 +81,5 @@ fn test_nucleotide_count_counts_all() {
81
81
  #[test]
82
82
  #[ignore]
83
83
  fn counts_invalid_nucleotide_results_in_err() {
84
- assert!(dna::nucleotide_counts("GGXXX").is_err());
84
+ assert_eq!(dna::nucleotide_counts("GGXXX"), Err('X'));
85
85
  }