trackler 2.2.1.129 → 2.2.1.130

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/scale-generator/description.md +9 -16
  4. data/tracks/dart/config.json +9 -9
  5. data/tracks/dart/exercises/raindrops/lib/raindrops.dart +1 -1
  6. data/tracks/dart/exercises/raindrops/test/raindrops_test.dart +59 -44
  7. data/tracks/dart/exercises/rna-transcription/test/rna_transcription_test.dart +37 -44
  8. data/tracks/fsharp/exercises/go-counting/Example.fs +24 -20
  9. data/tracks/fsharp/exercises/go-counting/GoCountingTest.fs +110 -51
  10. data/tracks/fsharp/generators/Generators.fs +84 -0
  11. data/tracks/java/config.json +13 -13
  12. data/tracks/purescript/config.json +12 -0
  13. data/tracks/purescript/exercises/phone-number/README.md +36 -0
  14. data/tracks/purescript/exercises/phone-number/bower.json +26 -0
  15. data/tracks/purescript/exercises/phone-number/examples/src/PhoneNumber.purs +30 -0
  16. data/tracks/purescript/exercises/phone-number/src/PhoneNumber.purs +6 -0
  17. data/tracks/purescript/exercises/phone-number/test/Main.purs +50 -0
  18. data/tracks/rust/_test/check-stubs.sh +29 -0
  19. data/tracks/rust/_test/ensure-stubs-compile.sh +24 -5
  20. data/tracks/rust/exercises/all-your-base/src/lib.rs +1 -2
  21. data/tracks/rust/exercises/armstrong-numbers/src/lib.rs +2 -2
  22. data/tracks/rust/exercises/beer-song/src/lib.rs +2 -2
  23. data/tracks/rust/exercises/bob/src/lib.rs +1 -1
  24. data/tracks/rust/exercises/circular-buffer/tests/circular-buffer.rs +96 -101
  25. data/tracks/rust/exercises/collatz-conjecture/src/lib.rs +4 -2
  26. data/tracks/rust/exercises/decimal/.meta/description.md +1 -1
  27. data/tracks/rust/exercises/decimal/README.md +1 -1
  28. data/tracks/rust/exercises/difference-of-squares/src/lib.rs +6 -3
  29. data/tracks/rust/exercises/forth/src/lib.rs +1 -1
  30. data/tracks/rust/exercises/grade-school/src/lib.rs +2 -4
  31. data/tracks/rust/exercises/grains/src/lib.rs +1 -1
  32. data/tracks/rust/exercises/leap/src/lib.rs +1 -1
  33. data/tracks/rust/exercises/macros/.meta/description.md +1 -1
  34. data/tracks/rust/exercises/macros/README.md +1 -1
  35. data/tracks/rust/exercises/ocr-numbers/src/lib.rs +1 -2
  36. data/tracks/rust/exercises/parallel-letter-frequency/.meta/hints.md +1 -1
  37. data/tracks/rust/exercises/parallel-letter-frequency/README.md +1 -1
  38. data/tracks/rust/exercises/pascals-triangle/src/lib.rs +1 -1
  39. data/tracks/rust/exercises/perfect-numbers/src/lib.rs +1 -1
  40. data/tracks/rust/exercises/prime-factors/src/lib.rs +1 -1
  41. data/tracks/rust/exercises/proverb/src/lib.rs +1 -1
  42. data/tracks/rust/exercises/raindrops/src/lib.rs +1 -1
  43. data/tracks/rust/exercises/react/src/lib.rs +11 -9
  44. data/tracks/rust/exercises/robot-simulator/src/lib.rs +6 -4
  45. data/tracks/rust/exercises/saddle-points/src/lib.rs +1 -1
  46. data/tracks/rust/exercises/simple-linked-list/src/lib.rs +5 -5
  47. data/tracks/rust/exercises/space-age/src/lib.rs +6 -3
  48. data/tracks/rust/exercises/sum-of-multiples/src/lib.rs +1 -1
  49. data/tracks/rust/exercises/two-bucket/src/lib.rs +7 -1
  50. data/tracks/rust/exercises/variable-length-quantity/src/lib.rs +2 -2
  51. data/tracks/typescript/exercises/list-ops/list-ops.example.ts +9 -13
  52. data/tracks/typescript/exercises/list-ops/list-ops.test.ts +9 -17
  53. metadata +8 -4
@@ -0,0 +1,29 @@
1
+ #!/bin/bash
2
+
3
+ # This checks every stub which exists, and emits all of their warnings.
4
+ # To get a list of exercises for which there are warnings on compilation,
5
+ # run it like this:
6
+ #
7
+ # $ _test/check-stubs.sh 2>/dev/null | rev | cut -d/ -f1 | rev
8
+
9
+ # run 'cargo check' on every exercise which possesses a stub
10
+ repo=$(cd "$(dirname "$0")/.." && pwd)
11
+
12
+ for stub in $repo/exercises/*/src/lib.rs; do
13
+ exercise=$(dirname $(dirname $stub))
14
+ (
15
+ cd "$exercise"
16
+ # copy the original stub to a backup
17
+ backup=$(dirname $stub)/lib.rs.bak
18
+ cp $stub $backup
19
+ # deny warnings in the stub
20
+ sed -i -e '1i #![deny(warnings)]' $stub
21
+ # quiet so that we only get output when there's an error
22
+ cargo check --quiet
23
+ if [ $? != 0 ]; then
24
+ echo "^- $exercise"
25
+ fi
26
+ # reset
27
+ mv -f $backup $stub
28
+ )
29
+ done
@@ -12,16 +12,35 @@ for dir in $repo/exercises/*/; do
12
12
  if grep -v '^//' $dir/src/lib.rs | grep '\S' > /dev/null; then
13
13
  allowed_file=$dir/.meta/ALLOWED_TO_NOT_COMPILE
14
14
 
15
- # In Travis CI, we may have already compiled using the example solution.
16
- # Touch the src/lib.rs file so that we surely recompile using the stub.
17
- touch $dir/src/lib.rs
18
-
19
15
  if [ -f $allowed_file ]; then
20
16
  echo "$exercise's stub is allowed to not compile"
21
- elif ! (cd $dir && cargo test --quiet --no-run); then
17
+ continue
18
+ fi
19
+
20
+ # Backup tests and stub; this script will modify them.
21
+ cp -r $dir/tests $dir/tests.orig
22
+ cp $dir/src/lib.rs $dir/lib.rs.orig
23
+
24
+ # This sed serves two purposes:
25
+ # First, in Travis CI, we may have already compiled using the example solution.
26
+ # Edit the src/lib.rs file so that we surely recompile using the stub.
27
+ # Second, ensures that the stub compiles without warnings.
28
+ sed -i -e '1i #![deny(warnings)]' "$dir/src/lib.rs"
29
+
30
+ # Deny warnings in the tests that may result from compiling the stubs.
31
+ # This helps avoid, for example, an overflowing literal warning
32
+ # that could be caused by a stub with a type that is too small.
33
+ sed -i -e '1i #![deny(warnings)]' $dir/tests/*.rs
34
+
35
+ if ! (cd $dir && cargo test --quiet --no-run); then
22
36
  echo "$exercise's stub does not compile; please make it compile or remove all non-commented lines"
23
37
  broken="$broken\n$exercise"
24
38
  fi
39
+
40
+ # Restore tests and stub.
41
+ mv $dir/lib.rs.orig $dir/src/lib.rs
42
+ rm -r $dir/tests
43
+ mv $dir/tests.orig $dir/tests
25
44
  fi
26
45
  done
27
46
 
@@ -36,7 +36,6 @@ pub enum Error {
36
36
  /// * Never output leading 0 digits. However, your function must be able to
37
37
  /// process input with leading 0 digits.
38
38
  ///
39
- #[allow(unused_variables)]
40
39
  pub fn convert(number: &[u32], from_base: u32, to_base: u32) -> Result<Vec<u32>, Error> {
41
- unimplemented!()
40
+ unimplemented!("Convert {:?} from base {} to base {}", number, from_base, to_base)
42
41
  }
@@ -1,3 +1,3 @@
1
- pub fn is_armstrong_number(_num: u32) -> bool {
2
- unimplemented!()
1
+ pub fn is_armstrong_number(num: u32) -> bool {
2
+ unimplemented!("true if {} is an armstrong number", num)
3
3
  }
@@ -1,7 +1,7 @@
1
1
  pub fn verse(n: i32) -> String {
2
- unimplemented!()
2
+ unimplemented!("emit verse {}", n)
3
3
  }
4
4
 
5
5
  pub fn sing(start: i32, end: i32) -> String {
6
- unimplemented!()
6
+ unimplemented!("sing verses {} to {}, inclusive", start, end)
7
7
  }
@@ -1,3 +1,3 @@
1
1
  pub fn reply(message: &str) -> &str {
2
- unimplemented!()
2
+ unimplemented!("have Bob reply to the incoming message: {}", message)
3
3
  }
@@ -1,113 +1,108 @@
1
1
  extern crate circular_buffer;
2
+ use circular_buffer::{CircularBuffer, Error};
2
3
 
3
- #[allow(unused_must_use)]
4
- mod tests {
5
-
6
- use circular_buffer::{CircularBuffer, Error};
7
-
8
- #[test]
9
- fn error_on_read_empty_buffer() {
10
- let mut buffer = CircularBuffer::<char>::new(1);
11
- assert_eq!(Err(Error::EmptyBuffer), buffer.read());
12
- }
4
+ #[test]
5
+ fn error_on_read_empty_buffer() {
6
+ let mut buffer = CircularBuffer::<char>::new(1);
7
+ assert_eq!(Err(Error::EmptyBuffer), buffer.read());
8
+ }
13
9
 
14
- #[test]
15
- #[ignore]
16
- fn write_and_read_back_item() {
17
- let mut buffer = CircularBuffer::new(1);
18
- buffer.write('1');
19
- assert_eq!(Ok('1'), buffer.read());
20
- assert_eq!(Err(Error::EmptyBuffer), buffer.read());
21
- }
10
+ #[test]
11
+ #[ignore]
12
+ fn write_and_read_back_item() {
13
+ let mut buffer = CircularBuffer::new(1);
14
+ assert!(buffer.write('1').is_ok());
15
+ assert_eq!(Ok('1'), buffer.read());
16
+ assert_eq!(Err(Error::EmptyBuffer), buffer.read());
17
+ }
22
18
 
23
- #[test]
24
- #[ignore]
25
- fn write_and_read_back_multiple_items() {
26
- let mut buffer = CircularBuffer::new(2);
27
- buffer.write('1');
28
- buffer.write('2');
29
- assert_eq!(Ok('1'), buffer.read());
30
- assert_eq!(Ok('2'), buffer.read());
31
- assert_eq!(Err(Error::EmptyBuffer), buffer.read());
32
- }
19
+ #[test]
20
+ #[ignore]
21
+ fn write_and_read_back_multiple_items() {
22
+ let mut buffer = CircularBuffer::new(2);
23
+ assert!(buffer.write('1').is_ok());
24
+ assert!(buffer.write('2').is_ok());
25
+ assert_eq!(Ok('1'), buffer.read());
26
+ assert_eq!(Ok('2'), buffer.read());
27
+ assert_eq!(Err(Error::EmptyBuffer), buffer.read());
28
+ }
33
29
 
34
- #[test]
35
- #[ignore]
36
- fn alternate_write_and_read() {
37
- let mut buffer = CircularBuffer::new(2);
38
- buffer.write('1');
39
- assert_eq!(Ok('1'), buffer.read());
40
- buffer.write('2');
41
- assert_eq!(Ok('2'), buffer.read());
42
- }
30
+ #[test]
31
+ #[ignore]
32
+ fn alternate_write_and_read() {
33
+ let mut buffer = CircularBuffer::new(2);
34
+ assert!(buffer.write('1').is_ok());
35
+ assert_eq!(Ok('1'), buffer.read());
36
+ assert!(buffer.write('2').is_ok());
37
+ assert_eq!(Ok('2'), buffer.read());
38
+ }
43
39
 
44
- #[test]
45
- #[ignore]
46
- fn clear_buffer() {
47
- let mut buffer = CircularBuffer::new(3);
48
- buffer.write('1');
49
- buffer.write('2');
50
- buffer.write('3');
51
- buffer.clear();
52
- assert_eq!(Err(Error::EmptyBuffer), buffer.read());
53
- buffer.write('1');
54
- buffer.write('2');
55
- assert_eq!(Ok('1'), buffer.read());
56
- buffer.write('3');
57
- assert_eq!(Ok('2'), buffer.read());
58
- }
40
+ #[test]
41
+ #[ignore]
42
+ fn clear_buffer() {
43
+ let mut buffer = CircularBuffer::new(3);
44
+ assert!(buffer.write('1').is_ok());
45
+ assert!(buffer.write('2').is_ok());
46
+ assert!(buffer.write('3').is_ok());
47
+ buffer.clear();
48
+ assert_eq!(Err(Error::EmptyBuffer), buffer.read());
49
+ assert!(buffer.write('1').is_ok());
50
+ assert!(buffer.write('2').is_ok());
51
+ assert_eq!(Ok('1'), buffer.read());
52
+ assert!(buffer.write('3').is_ok());
53
+ assert_eq!(Ok('2'), buffer.read());
54
+ }
59
55
 
60
- #[test]
61
- #[ignore]
62
- fn full_buffer_error() {
63
- let mut buffer = CircularBuffer::new(2);
64
- buffer.write('1');
65
- buffer.write('2');
66
- assert_eq!(Err(Error::FullBuffer), buffer.write('3'));
67
- }
56
+ #[test]
57
+ #[ignore]
58
+ fn full_buffer_error() {
59
+ let mut buffer = CircularBuffer::new(2);
60
+ assert!(buffer.write('1').is_ok());
61
+ assert!(buffer.write('2').is_ok());
62
+ assert_eq!(Err(Error::FullBuffer), buffer.write('3'));
63
+ }
68
64
 
69
- #[test]
70
- #[ignore]
71
- fn overwrite_item_in_non_full_buffer() {
72
- let mut buffer = CircularBuffer::new(2);
73
- buffer.write('1');
74
- buffer.overwrite('2');
75
- assert_eq!(Ok('1'), buffer.read());
76
- assert_eq!(Ok('2'), buffer.read());
77
- assert_eq!(Err(Error::EmptyBuffer), buffer.read());
78
- }
65
+ #[test]
66
+ #[ignore]
67
+ fn overwrite_item_in_non_full_buffer() {
68
+ let mut buffer = CircularBuffer::new(2);
69
+ assert!(buffer.write('1').is_ok());
70
+ buffer.overwrite('2');
71
+ assert_eq!(Ok('1'), buffer.read());
72
+ assert_eq!(Ok('2'), buffer.read());
73
+ assert_eq!(Err(Error::EmptyBuffer), buffer.read());
74
+ }
79
75
 
80
- #[test]
81
- #[ignore]
82
- fn overwrite_item_in_full_buffer() {
83
- let mut buffer = CircularBuffer::new(2);
84
- buffer.write('1');
85
- buffer.write('2');
86
- buffer.overwrite('A');
87
- assert_eq!(Ok('2'), buffer.read());
88
- assert_eq!(Ok('A'), buffer.read());
89
- }
76
+ #[test]
77
+ #[ignore]
78
+ fn overwrite_item_in_full_buffer() {
79
+ let mut buffer = CircularBuffer::new(2);
80
+ assert!(buffer.write('1').is_ok());
81
+ assert!(buffer.write('2').is_ok());
82
+ buffer.overwrite('A');
83
+ assert_eq!(Ok('2'), buffer.read());
84
+ assert_eq!(Ok('A'), buffer.read());
85
+ }
90
86
 
91
- #[test]
92
- #[ignore]
93
- fn integer_buffer() {
94
- let mut buffer = CircularBuffer::new(2);
95
- buffer.write(1);
96
- buffer.write(2);
97
- assert_eq!(Ok(1), buffer.read());
98
- buffer.write(-1);
99
- assert_eq!(Ok(2), buffer.read());
100
- assert_eq!(Ok(-1), buffer.read());
101
- assert_eq!(Err(Error::EmptyBuffer), buffer.read());
102
- }
87
+ #[test]
88
+ #[ignore]
89
+ fn integer_buffer() {
90
+ let mut buffer = CircularBuffer::new(2);
91
+ assert!(buffer.write(1).is_ok());
92
+ assert!(buffer.write(2).is_ok());
93
+ assert_eq!(Ok(1), buffer.read());
94
+ assert!(buffer.write(-1).is_ok());
95
+ assert_eq!(Ok(2), buffer.read());
96
+ assert_eq!(Ok(-1), buffer.read());
97
+ assert_eq!(Err(Error::EmptyBuffer), buffer.read());
98
+ }
103
99
 
104
- #[test]
105
- #[ignore]
106
- fn string_buffer() {
107
- let mut buffer = CircularBuffer::new(2);
108
- buffer.write("".to_string());
109
- buffer.write("Testing".to_string());
110
- assert_eq!(0, buffer.read().unwrap().len());
111
- assert_eq!(Ok("Testing".to_string()), buffer.read());
112
- }
100
+ #[test]
101
+ #[ignore]
102
+ fn string_buffer() {
103
+ let mut buffer = CircularBuffer::new(2);
104
+ buffer.write("".to_string()).unwrap();
105
+ buffer.write("Testing".to_string()).unwrap();
106
+ assert_eq!(0, buffer.read().unwrap().len());
107
+ assert_eq!(Ok("Testing".to_string()), buffer.read());
113
108
  }
@@ -1,4 +1,6 @@
1
- // return Some(x) where x is the number of steps required to reach 1
2
1
  pub fn collatz(n: u64) -> Option<u64> {
3
- unimplemented!()
2
+ unimplemented!(
3
+ "return Some(x) where x is the number of steps required to reach 1 starting with {}",
4
+ n,
5
+ )
4
6
  }
@@ -15,5 +15,5 @@ It would be very easy to implement this exercise by using the [bigdecimal](https
15
15
  # Hints
16
16
 
17
17
  - Instead of implementing arbitrary-precision arithmetic from scratch, consider building your type on top of the [num_bigint](https://crates.io/crates/num-bigint) crate.
18
- - You might be able to [derive](https://doc.rust-lang.org/book/first-edition/traits.html#deriving) some of the required traits.
18
+ - You might be able to [derive](https://doc.rust-lang.org/book/second-edition/appendix-03-derivable-traits.html) some of the required traits.
19
19
  - `Decimal` is assumed to be a signed type. You do not have to create a separate unsigned type, though you may do so as an implementation detail if you so choose.
@@ -17,7 +17,7 @@ It would be very easy to implement this exercise by using the [bigdecimal](https
17
17
  # Hints
18
18
 
19
19
  - Instead of implementing arbitrary-precision arithmetic from scratch, consider building your type on top of the [num_bigint](https://crates.io/crates/num-bigint) crate.
20
- - You might be able to [derive](https://doc.rust-lang.org/book/first-edition/traits.html#deriving) some of the required traits.
20
+ - You might be able to [derive](https://doc.rust-lang.org/book/second-edition/appendix-03-derivable-traits.html) some of the required traits.
21
21
  - `Decimal` is assumed to be a signed type. You do not have to create a separate unsigned type, though you may do so as an implementation detail if you so choose.
22
22
 
23
23
  ## Rust Installation
@@ -1,11 +1,14 @@
1
1
  pub fn square_of_sum(n: usize) -> usize {
2
- unimplemented!()
2
+ unimplemented!("square of sum of 1...{}", n)
3
3
  }
4
4
 
5
5
  pub fn sum_of_squares(n: usize) -> usize {
6
- unimplemented!()
6
+ unimplemented!("sum of squares of 1...{}", n)
7
7
  }
8
8
 
9
9
  pub fn difference(n: usize) -> usize {
10
- unimplemented!()
10
+ unimplemented!(
11
+ "difference between square of sum of 1...{n} and sum of squares of 1...{n}",
12
+ n=n,
13
+ )
11
14
  }
@@ -21,6 +21,6 @@ impl Forth {
21
21
  }
22
22
 
23
23
  pub fn eval(&mut self, input: &str) -> ForthResult {
24
- unimplemented!()
24
+ unimplemented!("result of evaluating '{}'", input)
25
25
  }
26
26
  }
@@ -1,5 +1,3 @@
1
- #[allow(unused_variables)]
2
-
3
1
  pub struct School {
4
2
  }
5
3
 
@@ -9,7 +7,7 @@ impl School {
9
7
  }
10
8
 
11
9
  pub fn add(&mut self, grade: u32, student: &str) {
12
- unimplemented!()
10
+ unimplemented!("Add {} to the roster for {}", student, grade)
13
11
  }
14
12
 
15
13
  pub fn grades(&self) -> Vec<u32> {
@@ -21,6 +19,6 @@ impl School {
21
19
  // By returning an owned vector instead,
22
20
  // the internal implementation is free to use whatever it chooses.
23
21
  pub fn grade(&self, grade: u32) -> Option<Vec<String>> {
24
- unimplemented!()
22
+ unimplemented!("Return the list of students in {}", grade)
25
23
  }
26
24
  }
@@ -1,5 +1,5 @@
1
1
  pub fn square(s: u32) -> u64 {
2
- unimplemented!();
2
+ unimplemented!("grains of rice on square {}", s);
3
3
  }
4
4
 
5
5
  pub fn total() -> u64 {
@@ -1,3 +1,3 @@
1
1
  pub fn is_leap_year(year: i32) -> bool {
2
- unimplemented!()
2
+ unimplemented!("true if {} is a leap year", year)
3
3
  }
@@ -8,7 +8,7 @@ What is a macro? [Wikipedia](https://en.wikipedia.org/wiki/Macro_(computer_scien
8
8
 
9
9
  Illuminating! But to be more concrete, macros are a special syntax which allows you to generate code at compile time. Macros can be used compile-time calculation, but more often they're just another way to abstract your code. For example, you've probably already used `println!()` and `vec![]`. These each take an arbitrary number of arguments, so you can't express them as simple functions. On the other hand, they always expand to some amount of absolutely standard Rust code. If you're interested, you can use the [cargo expand](https://github.com/dtolnay/cargo-expand) subcommand to view the results of macro expansion in your code.
10
10
 
11
- For further information about macros in Rust, The Rust Book has a [good chapter](https://doc.rust-lang.org/book/first-edition/macros.html) on them.
11
+ For further information about macros in Rust, The Rust Book has a [good chapter](https://doc.rust-lang.org/book/second-edition/appendix-04-macros.html) on them.
12
12
 
13
13
  ## Problem Statement
14
14
 
@@ -10,7 +10,7 @@ What is a macro? [Wikipedia](https://en.wikipedia.org/wiki/Macro_(computer_scien
10
10
 
11
11
  Illuminating! But to be more concrete, macros are a special syntax which allows you to generate code at compile time. Macros can be used compile-time calculation, but more often they're just another way to abstract your code. For example, you've probably already used `println!()` and `vec![]`. These each take an arbitrary number of arguments, so you can't express them as simple functions. On the other hand, they always expand to some amount of absolutely standard Rust code. If you're interested, you can use the [cargo expand](https://github.com/dtolnay/cargo-expand) subcommand to view the results of macro expansion in your code.
12
12
 
13
- For further information about macros in Rust, The Rust Book has a [good chapter](https://doc.rust-lang.org/book/first-edition/macros.html) on them.
13
+ For further information about macros in Rust, The Rust Book has a [good chapter](https://doc.rust-lang.org/book/second-edition/appendix-04-macros.html) on them.
14
14
 
15
15
  ## Problem Statement
16
16
 
@@ -7,7 +7,6 @@ pub enum Error {
7
7
  InvalidColumnCount(usize),
8
8
  }
9
9
 
10
- #[allow(unused_variables)]
11
10
  pub fn convert(input: &str) -> Result<String, Error> {
12
- unimplemented!();
11
+ unimplemented!("Convert the input '{}' to a string", input);
13
12
  }
@@ -28,5 +28,5 @@ rustup run nightly cargo bench
28
28
 
29
29
  Learn more about nightly Rust:
30
30
 
31
- - [Nightly Rust](https://doc.rust-lang.org/book/first-edition/release-channels.html)
31
+ - [Nightly Rust](https://doc.rust-lang.org/book/second-edition/ch01-03-how-rust-is-made-and-nightly-rust.html)
32
32
  - [Rustup: Working with nightly](https://github.com/rust-lang-nursery/rustup.rs#working-with-nightly-rust)