trackler 2.2.1.3 → 2.2.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/java/exercises/sum-of-multiples/src/example/java/SumOfMultiples.java +6 -16
  4. data/tracks/ruby/config.json +13 -0
  5. data/tracks/ruby/exercises/change/.meta/.version +1 -0
  6. data/tracks/ruby/exercises/change/.meta/generator/change_case.rb +9 -0
  7. data/tracks/ruby/exercises/change/.meta/solutions/change.rb +58 -0
  8. data/tracks/ruby/exercises/change/change_test.rb +77 -0
  9. data/tracks/rust/config.json +20 -0
  10. data/tracks/rust/exercises/prime-factors/Cargo.lock +4 -0
  11. data/tracks/rust/exercises/prime-factors/Cargo.toml +6 -0
  12. data/tracks/rust/exercises/prime-factors/README.md +68 -0
  13. data/tracks/rust/exercises/prime-factors/example.rs +13 -0
  14. data/tracks/rust/exercises/prime-factors/src/lib.rs +0 -0
  15. data/tracks/rust/exercises/prime-factors/tests/prime-factors.rs +44 -0
  16. data/tracks/rust/exercises/proverb/Cargo.lock +4 -0
  17. data/tracks/rust/exercises/proverb/Cargo.toml +6 -0
  18. data/tracks/rust/exercises/proverb/README.md +50 -0
  19. data/tracks/rust/exercises/proverb/example.rs +17 -0
  20. data/tracks/rust/exercises/proverb/src/lib.rs +0 -0
  21. data/tracks/rust/exercises/proverb/tests/proverb.rs +52 -0
  22. data/tracks/scala/exercises/pascals-triangle/example.scala +1 -1
  23. data/tracks/scala/exercises/pascals-triangle/src/test/scala/PascalsTriangleTest.scala +17 -20
  24. data/tracks/scala/exercises/run-length-encoding/src/main/scala/.keep +0 -0
  25. data/tracks/scala/exercises/run-length-encoding/src/test/scala/RunLengthEncodingTests.scala +38 -21
  26. data/tracks/scala/testgen/src/main/scala/PascalsTriangleTestGenerator.scala +51 -0
  27. data/tracks/scala/testgen/src/main/scala/RunLengthEncodingTestGenerator.scala +34 -0
  28. data/tracks/scala/testgen/src/main/scala/testgen/TestSuiteBuilder.scala +19 -0
  29. metadata +21 -3
  30. data/tracks/scala/exercises/run-length-encoding/src/main/scala/RunLengthEncoding.scala +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f2d3bdebe9f23b4e4bd76015bdf93718291556cd
4
- data.tar.gz: 663c332d00958e9c5e98dbbf5a39b8b1860bea20
3
+ metadata.gz: 97638638dc6720c36ddae0926221e2947f683e95
4
+ data.tar.gz: caf86db5732ca7d826613d9b8cb4dbfa00702339
5
5
  SHA512:
6
- metadata.gz: 98a6ee04e6e779216a3d1edb522674cde1a6d6b537cbff42a48fd4ec09ea78fe155dbdb346dbea5f9e39caaa35300648ac851d0c193e940593c967f4ca2ec247
7
- data.tar.gz: f19ff52e7647ce38e231d8145703fe95d51ca3c664bc82e562d1b54342cad092e3fe51eb81b50b2e5ea1c45c78f95de7f10c8feab32fe2e2047943fafe3aeb08
6
+ metadata.gz: 48d697aabfd7dd44f0247c4c9e0b44bf945016206525280fe09e513cfbab292ea5b1d644e82072c6f27a25ae927cc6710c813a4ae0a860f7a070a57f84f99ee0
7
+ data.tar.gz: 661a015ebfc069b4f9c00be5dc44b2ab2c91813f97b407bb3fa9205d9393c8eb653a22593f63070458678f540c98cf59475e7cf19e5e40311f1ceaa2732cc354
@@ -1,3 +1,3 @@
1
1
  module Trackler
2
- VERSION = "2.2.1.3"
2
+ VERSION = "2.2.1.4"
3
3
  end
@@ -1,3 +1,6 @@
1
+ import java.util.Arrays;
2
+ import java.util.stream.IntStream;
3
+
1
4
  public class SumOfMultiples {
2
5
  private final int sum;
3
6
 
@@ -11,22 +14,9 @@ public class SumOfMultiples {
11
14
 
12
15
  private int calculateSum(int number, int[] set) {
13
16
 
14
- int sum = 0;
15
- int count = 0;
16
-
17
- for (int i = 1; i < number; i++) {
18
-
19
- for (int j = 0; j < set.length; j++) {
20
- if (i % set[j] == 0) {
21
- count++;
22
- }
23
- }
24
-
25
- if (count > 0) {
26
- sum = sum + i;
27
- count = 0;
28
- }
29
- }
17
+ int sum = IntStream.range(1,number)
18
+ .filter(i -> Arrays.stream(set).filter(j -> i % j == 0).count() > 0)
19
+ .sum();
30
20
 
31
21
  return sum;
32
22
  }
@@ -872,6 +872,19 @@
872
872
  "Strings"
873
873
  ]
874
874
  },
875
+ {
876
+ "uuid": "dc6c3e44-1027-4d53-9653-ba06824f8bcf",
877
+ "slug": "change",
878
+ "core": false,
879
+ "unlocked_by": null,
880
+ "difficulty": 5,
881
+ "topics": [
882
+ "Algorithms",
883
+ "Control-flow (conditionals)",
884
+ "Control-flow (loops)",
885
+ "Logic"
886
+ ]
887
+ },
875
888
  {
876
889
  "uuid": "cae4e000-3aac-41f7-b727-f9cce12d058d",
877
890
  "slug": "octal",
@@ -0,0 +1,9 @@
1
+ require 'generator/exercise_case'
2
+
3
+ class ChangeCase < Generator::ExerciseCase
4
+
5
+ def workload
6
+ assert_equal { "Change.generate(#{coins}, #{target})" }
7
+ end
8
+
9
+ end
@@ -0,0 +1,58 @@
1
+ module BookKeeping
2
+ VERSION = 1
3
+ end
4
+
5
+ class Change
6
+ attr_reader :coins, :target
7
+
8
+ def initialize(coins, target)
9
+ @coins = coins.sort.reverse
10
+ @target = target
11
+ @total_change = []
12
+ end
13
+
14
+ def generate
15
+ return [] if target.zero?
16
+
17
+ calculate_change(coins, [], target)
18
+
19
+ total_change.any? ? total_change.sort : -1
20
+ end
21
+
22
+ def self.generate(coins, target)
23
+ new(coins, target).generate
24
+ end
25
+
26
+ private
27
+
28
+ attr_accessor :total_change
29
+
30
+ def calculate_change(current_coins, current_change, current_value)
31
+ available_coins = current_coins.reject {|d| d > current_value }
32
+
33
+ save_change(current_change) if current_value.zero?
34
+
35
+ return if has_more_coins?(current_change)
36
+
37
+ each_group(available_coins) do |coin, group|
38
+ calculate_change(group, current_change + [coin], current_value - coin)
39
+ end
40
+ end
41
+
42
+ def save_change(contents)
43
+ return if has_more_coins?(contents)
44
+
45
+ self.total_change = contents
46
+ end
47
+
48
+ def has_more_coins?(contents)
49
+ total_change.any? && (total_change.length < contents.length)
50
+ end
51
+
52
+ def each_group(array)
53
+ array.length.times do |n|
54
+ yield(array[n], array[n..-1])
55
+ end
56
+ end
57
+
58
+ end
@@ -0,0 +1,77 @@
1
+ require 'minitest/autorun'
2
+ require_relative 'change'
3
+
4
+ # Common test data version: 1.0.0 3d8b5b3
5
+ class ChangeTest < Minitest::Test
6
+ def test_single_coin_change
7
+ # skip
8
+ assert_equal [25], Change.generate([1, 5, 10, 25, 100], 25)
9
+ end
10
+
11
+ def test_multiple_coin_change
12
+ skip
13
+ assert_equal [5, 10], Change.generate([1, 5, 10, 25, 100], 15)
14
+ end
15
+
16
+ def test_change_with_lilliputian_coins
17
+ skip
18
+ assert_equal [4, 4, 15], Change.generate([1, 4, 15, 20, 50], 23)
19
+ end
20
+
21
+ def test_change_with_lower_elbonia_coins
22
+ skip
23
+ assert_equal [21, 21, 21], Change.generate([1, 5, 10, 21, 25], 63)
24
+ end
25
+
26
+ def test_large_target_values
27
+ skip
28
+ assert_equal [2, 2, 5, 20, 20, 50, 100, 100, 100, 100, 100, 100, 100, 100, 100], Change.generate([1, 2, 5, 10, 20, 50, 100], 999)
29
+ end
30
+
31
+ def test_possible_change_without_unit_coins_available
32
+ skip
33
+ assert_equal [2, 2, 2, 5, 10], Change.generate([2, 5, 10, 20, 50], 21)
34
+ end
35
+
36
+ def test_no_coins_make_0_change
37
+ skip
38
+ assert_equal [], Change.generate([1, 5, 10, 21, 25], 0)
39
+ end
40
+
41
+ def test_error_testing_for_change_smaller_than_the_smallest_of_coins
42
+ skip
43
+ assert_equal -1, Change.generate([5, 10], 3)
44
+ end
45
+
46
+ def test_error_if_no_combination_can_add_up_to_target
47
+ skip
48
+ assert_equal -1, Change.generate([5, 10], 94)
49
+ end
50
+
51
+ def test_cannot_find_negative_change_values
52
+ skip
53
+ assert_equal -1, Change.generate([1, 2, 5], -5)
54
+ end
55
+
56
+ # Problems in exercism evolve over time, as we find better ways to ask
57
+ # questions.
58
+ # The version number refers to the version of the problem you solved,
59
+ # not your solution.
60
+ #
61
+ # Define a constant named VERSION inside of the top level BookKeeping
62
+ # module, which may be placed near the end of your file.
63
+ #
64
+ # In your file, it will look like this:
65
+ #
66
+ # module BookKeeping
67
+ # VERSION = 1 # Where the version number matches the one in the test.
68
+ # end
69
+ #
70
+ # If you are curious, read more about constants on RubyDoc:
71
+ # http://ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/constants.html
72
+
73
+ def test_bookkeeping
74
+ skip
75
+ assert_equal 1, BookKeeping::VERSION
76
+ end
77
+ end
@@ -70,6 +70,16 @@
70
70
  "loop"
71
71
  ]
72
72
  },
73
+ {
74
+ "uuid": "504f9033-6433-4508-aebb-60ee77b800b9",
75
+ "slug": "proverb",
76
+ "core": false,
77
+ "unlocked_by": null,
78
+ "difficulty": 1,
79
+ "topics": [
80
+ "format"
81
+ ]
82
+ },
73
83
  {
74
84
  "uuid": "aee49878-f727-400b-8fb5-eaf83447cf87",
75
85
  "slug": "difference-of-squares",
@@ -103,6 +113,16 @@
103
113
  "panic"
104
114
  ]
105
115
  },
116
+ {
117
+ "uuid": "9f649818-0c82-4b79-b912-4d65b9f60e10",
118
+ "slug": "prime-factors",
119
+ "core": false,
120
+ "unlocked_by": null,
121
+ "difficulty": 1,
122
+ "topics": [
123
+ "math"
124
+ ]
125
+ },
106
126
  {
107
127
  "uuid": "4ba35adb-230b-49a6-adc9-2d3cd9a4c538",
108
128
  "slug": "say",
@@ -0,0 +1,4 @@
1
+ [root]
2
+ name = "prime_factors"
3
+ version = "1.0.0"
4
+
@@ -0,0 +1,6 @@
1
+ [package]
2
+ name = "prime_factors"
3
+ version = "1.0.0"
4
+ authors = ["sacherjj <sacherjj@gmail.com>"]
5
+
6
+ [dependencies]
@@ -0,0 +1,68 @@
1
+ # Prime Factors
2
+
3
+ Compute the prime factors of a given natural number.
4
+
5
+ A prime number is only evenly divisible by itself and 1.
6
+
7
+ Note that 1 is not a prime number.
8
+
9
+ ## Example
10
+
11
+ What are the prime factors of 60?
12
+
13
+ - Our first divisor is 2. 2 goes into 60, leaving 30.
14
+ - 2 goes into 30, leaving 15.
15
+ - 2 doesn't go cleanly into 15. So let's move on to our next divisor, 3.
16
+ - 3 goes cleanly into 15, leaving 5.
17
+ - 3 does not go cleanly into 5. The next possible factor is 4.
18
+ - 4 does not go cleanly into 5. The next possible factor is 5.
19
+ - 5 does go cleanly into 5.
20
+ - We're left only with 1, so now, we're done.
21
+
22
+ Our successful divisors in that computation represent the list of prime
23
+ factors of 60: 2, 2, 3, and 5.
24
+
25
+ You can check this yourself:
26
+
27
+ - 2 * 2 * 3 * 5
28
+ - = 4 * 15
29
+ - = 60
30
+ - Success!
31
+
32
+ ## Rust Installation
33
+
34
+ Refer to the [exercism help page][help-page] for Rust installation and learning
35
+ resources.
36
+
37
+ ## Writing the Code
38
+
39
+ Execute the tests with:
40
+
41
+ ```bash
42
+ $ cargo test
43
+ ```
44
+
45
+ All but the first test have been ignored. After you get the first test to
46
+ pass, remove the ignore flag (`#[ignore]`) from the next test and get the tests
47
+ to pass again. The test file is located in the `tests` directory. You can
48
+ also remove the ignore flag from all the tests to get them to run all at once
49
+ if you wish.
50
+
51
+ Make sure to read the [Crates and Modules](https://doc.rust-lang.org/stable/book/crates-and-modules.html) chapter if you
52
+ haven't already, it will help you with organizing your files.
53
+
54
+ ## Feedback, Issues, Pull Requests
55
+
56
+ The [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](https://github.com/orgs/exercism/teams/rust) are happy to help!
57
+
58
+ If 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).
59
+
60
+ [help-page]: http://exercism.io/languages/rust
61
+ [crates-and-modules]: http://doc.rust-lang.org/stable/book/crates-and-modules.html
62
+
63
+ ## Source
64
+
65
+ The Prime Factors Kata by Uncle Bob [http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata](http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata)
66
+
67
+ ## Submitting Incomplete Solutions
68
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,13 @@
1
+ pub fn factors(n: u64) -> Vec<u64> {
2
+ let mut val = n;
3
+ let mut out: Vec<u64> = vec![];
4
+ let mut possible:u64 = 2;
5
+ while val > 1 {
6
+ while val % possible == 0 {
7
+ out.push(possible);
8
+ val /= possible;
9
+ }
10
+ possible += 1;
11
+ }
12
+ out
13
+ }
File without changes
@@ -0,0 +1,44 @@
1
+ extern crate prime_factors;
2
+
3
+ use prime_factors::factors;
4
+
5
+ #[test]
6
+ fn test_no_factors() {
7
+ assert_eq!(factors(1), vec![]);
8
+ }
9
+
10
+ #[test]
11
+ #[ignore]
12
+ fn test_prime_number() {
13
+ assert_eq!(factors(2), vec![2]);
14
+ }
15
+
16
+ #[test]
17
+ #[ignore]
18
+ fn test_square_of_a_prime() {
19
+ assert_eq!(factors(9), vec![3, 3]);
20
+ }
21
+
22
+ #[test]
23
+ #[ignore]
24
+ fn test_cube_of_a_prime() {
25
+ assert_eq!(factors(8), vec![2, 2, 2]);
26
+ }
27
+
28
+ #[test]
29
+ #[ignore]
30
+ fn test_product_of_primes_and_non_primes() {
31
+ assert_eq!(factors(12), vec![2, 2, 3]);
32
+ }
33
+
34
+ #[test]
35
+ #[ignore]
36
+ fn test_product_of_primes() {
37
+ assert_eq!(factors(901255), vec![5, 17, 23, 461]);
38
+ }
39
+
40
+ #[test]
41
+ #[ignore]
42
+ fn test_factors_include_large_prime() {
43
+ assert_eq!(factors(93819012551), vec![11, 9539, 894119]);
44
+ }
@@ -0,0 +1,4 @@
1
+ [root]
2
+ name = "proverb"
3
+ version = "0.0.0"
4
+
@@ -0,0 +1,6 @@
1
+ [package]
2
+ name = "proverb"
3
+ version = "0.0.0"
4
+ authors = ["sacherjj <sacherjj@gmail.com>"]
5
+
6
+ [dependencies]
@@ -0,0 +1,50 @@
1
+ # Proverb
2
+
3
+ For want of a horseshoe nail, a kingdom was lost, or so the saying goes. Output
4
+ the full text of this proverbial rhyme:
5
+
6
+ > For want of a nail the shoe was lost.
7
+ > For want of a shoe the horse was lost.
8
+ > For want of a horse the rider was lost.
9
+ > For want of a rider the message was lost.
10
+ > For want of a message the battle was lost.
11
+ > For want of a battle the kingdom was lost.
12
+ > And all for the want of a horseshoe nail.
13
+
14
+ ## Rust Installation
15
+
16
+ Refer to the [exercism help page][help-page] for Rust installation and learning
17
+ resources.
18
+
19
+ ## Writing the Code
20
+
21
+ Execute the tests with:
22
+
23
+ ```bash
24
+ $ cargo test
25
+ ```
26
+
27
+ All but the first test have been ignored. After you get the first test to
28
+ pass, remove the ignore flag (`#[ignore]`) from the next test and get the tests
29
+ to pass again. The test file is located in the `tests` directory. You can
30
+ also remove the ignore flag from all the tests to get them to run all at once
31
+ if you wish.
32
+
33
+ Make sure to read the [Crates and Modules](https://doc.rust-lang.org/stable/book/crates-and-modules.html) chapter if you
34
+ haven't already, it will help you with organizing your files.
35
+
36
+ ## Feedback, Issues, Pull Requests
37
+
38
+ The [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](https://github.com/orgs/exercism/teams/rust) are happy to help!
39
+
40
+ If 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).
41
+
42
+ [help-page]: http://exercism.io/languages/rust
43
+ [crates-and-modules]: http://doc.rust-lang.org/stable/book/crates-and-modules.html
44
+
45
+ ## Source
46
+
47
+ Wikipedia [http://en.wikipedia.org/wiki/For_Want_of_a_Nail](http://en.wikipedia.org/wiki/For_Want_of_a_Nail)
48
+
49
+ ## Submitting Incomplete Solutions
50
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,17 @@
1
+ pub fn build_proverb(list: Vec<&str>) -> String {
2
+ if list.len() == 0 {
3
+ return String::new();
4
+ }
5
+ let mut out: Vec<String> = vec![];
6
+ for i in 1..list.len() {
7
+ out.push(format!("For want of a {} the {} was lost.", list[i-1], list[i]));
8
+ }
9
+ let end: String;
10
+ if list.len() > 2 {
11
+ end = format!("{}{} {}", list[2], list[1], list[0]);
12
+ } else {
13
+ end = format!("{}", list[0]);
14
+ }
15
+ out.push(format!("And all for the want of a {}.", end));
16
+ out.join("\n")
17
+ }
File without changes
@@ -0,0 +1,52 @@
1
+ extern crate proverb;
2
+
3
+ use proverb::build_proverb;
4
+
5
+ #[test]
6
+ fn test_two_pieces() {
7
+ let input = vec!["nail", "shoe"];
8
+ let expected = vec!["For want of a nail the shoe was lost.",
9
+ "And all for the want of a nail."].join("\n");
10
+ assert_eq!(build_proverb(input), expected);
11
+ }
12
+
13
+ // Notice the change in the last line at three pieces.
14
+ #[test]
15
+ #[ignore]
16
+ fn test_three_pieces() {
17
+ let input = vec!["nail", "shoe", "horse"];
18
+ let expected = vec!["For want of a nail the shoe was lost.",
19
+ "For want of a shoe the horse was lost.",
20
+ "And all for the want of a horseshoe nail."].join("\n");
21
+ assert_eq!(build_proverb(input), expected);
22
+ }
23
+
24
+ #[test]
25
+ #[ignore]
26
+ fn test_one_piece() {
27
+ let input = vec!["nail"];
28
+ let expected = String::from("And all for the want of a nail.");
29
+ assert_eq!(build_proverb(input), expected);
30
+ }
31
+
32
+ #[test]
33
+ #[ignore]
34
+ fn test_zero_pieces() {
35
+ let input: Vec<&str> = vec![];
36
+ let expected = String::new();
37
+ assert_eq!(build_proverb(input), expected);
38
+ }
39
+
40
+ #[test]
41
+ #[ignore]
42
+ fn test_full() {
43
+ let input = vec!["nail", "shoe", "horse", "rider", "message", "battle", "kingdom"];
44
+ let expected = vec!["For want of a nail the shoe was lost.",
45
+ "For want of a shoe the horse was lost.",
46
+ "For want of a horse the rider was lost.",
47
+ "For want of a rider the message was lost.",
48
+ "For want of a message the battle was lost.",
49
+ "For want of a battle the kingdom was lost.",
50
+ "And all for the want of a horseshoe nail."].join("\n");
51
+ assert_eq!(build_proverb(input), expected);
52
+ }
@@ -1,5 +1,5 @@
1
1
  object PascalsTriangle {
2
- def triangle(n: Int): List[List[Int]] =
2
+ def rows(n: Int): List[List[Int]] =
3
3
  (for (row <- 1 to n) yield triRow(row)).toList
4
4
 
5
5
  private def triRow(row: Int): List[Int] = {
@@ -1,37 +1,34 @@
1
- import org.scalatest.{Matchers, FlatSpec}
1
+ import org.scalatest.{Matchers, FunSuite}
2
2
 
3
- class PascalsTriangleTest extends FlatSpec with Matchers {
4
- it should "handle 1 row" in {
5
- PascalsTriangle.triangle(1) should be (List(List(1)))
3
+ /** @version 1.0.0 */
4
+ class PascalsTriangleTest extends FunSuite with Matchers {
5
+
6
+ test("zero rows") {
7
+ PascalsTriangle.rows(0) should be (List())
6
8
  }
7
9
 
8
- it should "handle 2 rows" in {
10
+ test("single row") {
9
11
  pending
10
- PascalsTriangle.triangle(2) should be (List(List(1), List(1, 1)))
12
+ PascalsTriangle.rows(1) should be (List(List(1)))
11
13
  }
12
14
 
13
- it should "handle 3 rows" in {
15
+ test("two rows") {
14
16
  pending
15
- PascalsTriangle.triangle(3) should be (List(List(1), List(1, 1), List(1, 2, 1)))
17
+ PascalsTriangle.rows(2) should be (List(List(1), List(1, 1)))
16
18
  }
17
19
 
18
- it should "handle 4 rows" in {
20
+ test("three rows") {
19
21
  pending
20
- PascalsTriangle.triangle(4) should be (List(List(1), List(1, 1),
21
- List(1, 2, 1), List(1, 3, 3, 1)))
22
+ PascalsTriangle.rows(3) should be (List(List(1), List(1, 1), List(1, 2, 1)))
22
23
  }
23
24
 
24
- it should "handle 5 rows" in {
25
+ test("four rows") {
25
26
  pending
26
- PascalsTriangle.triangle(5) should be (List(List(1), List(1, 1),
27
- List(1, 2, 1), List(1, 3, 3, 1), List(1, 4, 6, 4, 1)))
27
+ PascalsTriangle.rows(4) should be (List(List(1), List(1, 1), List(1, 2, 1), List(1, 3, 3, 1)))
28
28
  }
29
29
 
30
- it should "handle 20 rows" in {
30
+ test("negative rows") {
31
31
  pending
32
- PascalsTriangle.triangle(20).takeRight(1).head should be (List(1, 19,
33
- 171, 969, 3876, 11628, 27132, 50388, 75582, 92378,
34
- 92378, 75582, 50388, 27132, 11628, 3876, 969, 171,
35
- 19, 1))
32
+ PascalsTriangle.rows(-1) should be (List())
36
33
  }
37
- }
34
+ }
@@ -1,52 +1,69 @@
1
- import org.scalatest.FunSuite
2
- import org.scalatest.Matchers
1
+ import org.scalatest.{Matchers, FunSuite}
3
2
 
4
- class RunLengthEncodingTests extends FunSuite with Matchers {
3
+ /** @version 1.0.0 */
4
+ class RunLengthEncodingTest extends FunSuite with Matchers {
5
5
 
6
- test("encode empty string") {
6
+ test("encode - empty string") {
7
7
  RunLengthEncoding.encode("") should be ("")
8
8
  }
9
9
 
10
- test("encode single characters only") {
10
+ test("encode - single characters only are encoded without count") {
11
11
  pending
12
12
  RunLengthEncoding.encode("XYZ") should be ("XYZ")
13
13
  }
14
14
 
15
- test("decode empty string") {
15
+ test("encode - string with no single characters") {
16
16
  pending
17
- RunLengthEncoding.decode("") should be ("")
17
+ RunLengthEncoding.encode("AABBBCCCC") should be ("2A3B4C")
18
18
  }
19
19
 
20
- test("decode single characters only") {
20
+ test("encode - single characters mixed with repeated characters") {
21
21
  pending
22
- RunLengthEncoding.decode("XYZ") should be ("XYZ")
22
+ RunLengthEncoding.encode("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB") should be ("12WB12W3B24WB")
23
23
  }
24
24
 
25
- test("encode simple") {
25
+ test("encode - multiple whitespace mixed in string") {
26
26
  pending
27
- RunLengthEncoding.encode("AABBBCCCC") should be ("2A3B4C")
27
+ RunLengthEncoding.encode(" hsqq qww ") should be ("2 hs2q q2w2 ")
28
28
  }
29
29
 
30
- test("decode simple") {
30
+ test("encode - lowercase characters") {
31
31
  pending
32
- RunLengthEncoding.decode("2A3B4C") should be ("AABBBCCCC")
32
+ RunLengthEncoding.encode("aabbbcccc") should be ("2a3b4c")
33
33
  }
34
34
 
35
- test("encode with single values") {
35
+ test("decode - empty string") {
36
36
  pending
37
- RunLengthEncoding.encode("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB") should
38
- be ("12WB12W3B24WB")
37
+ RunLengthEncoding.decode("") should be ("")
38
+ }
39
+
40
+ test("decode - single characters only") {
41
+ pending
42
+ RunLengthEncoding.decode("XYZ") should be ("XYZ")
39
43
  }
40
44
 
41
- test("decode with single values") {
45
+ test("decode - string with no single characters") {
46
+ pending
47
+ RunLengthEncoding.decode("2A3B4C") should be ("AABBBCCCC")
48
+ }
49
+
50
+ test("decode - single characters with repeated characters") {
42
51
  pending
43
52
  RunLengthEncoding.decode("12WB12W3B24WB") should be ("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB")
44
53
  }
45
54
 
46
- test("decode(encode(...)) combination") {
55
+ test("decode - multiple whitespace mixed in string") {
47
56
  pending
48
- RunLengthEncoding.decode(
49
- RunLengthEncoding.encode("zzz ZZ zZ")) should be ("zzz ZZ zZ")
57
+ RunLengthEncoding.decode("2 hs2q q2w2 ") should be (" hsqq qww ")
50
58
  }
51
59
 
52
- }
60
+ test("decode - lower case string") {
61
+ pending
62
+ RunLengthEncoding.decode("2a3b4c") should be ("aabbbcccc")
63
+ }
64
+
65
+ test("consistency - encode followed by decode gives original string") {
66
+ pending
67
+ RunLengthEncoding.decode(RunLengthEncoding.encode("zzz ZZ zZ")) should be ("zzz ZZ zZ")
68
+ }
69
+ }
@@ -0,0 +1,51 @@
1
+ import java.io.File
2
+
3
+ import testgen.TestSuiteBuilder._
4
+ import testgen._
5
+
6
+ object PascalsTriangleTestGenerator {
7
+ def main(args: Array[String]): Unit = {
8
+ val file = new File("src/main/resources/pascals-triangle.json")
9
+
10
+ def toStr(any: Any): String = {
11
+ any match {
12
+ case list: List[_] =>
13
+ val vals = list.map(s => toStr(s)).mkString(", ")
14
+ s"List($vals)"
15
+ case n: Int =>
16
+ if (n == -1)
17
+ "List()"
18
+ else
19
+ n.toString
20
+ case v => throw new IllegalStateException("Unexpected value - " + v)
21
+ }
22
+ }
23
+
24
+ def toString(expected: CanonicalDataParser.Expected): String = {
25
+ expected match {
26
+ case Left(error) => throw new IllegalStateException("Unexpected error - " + error)
27
+ case Right(exp) => toStr(exp)
28
+ }
29
+ }
30
+
31
+ def withLabeledTestOption(argNames: String*): ToOptionTestCaseData =
32
+ withLabeledTestOpt { sut =>
33
+ labeledTest =>
34
+ if (labeledTest.result.valuesIterator.contains(null)) {
35
+ None
36
+ } else {
37
+ val args = sutArgs(labeledTest.result, argNames: _*)
38
+ val property = labeledTest.property
39
+ val sutCall =
40
+ s"""$sut.$property($args)"""
41
+ val expected = toString(labeledTest.expected)
42
+ Some(TestCaseData(labeledTest.description, sutCall, expected))
43
+ }
44
+ }
45
+
46
+ val code = TestSuiteBuilder.buildFromOption(file, withLabeledTestOption("count"))
47
+ println(s"-------------")
48
+ println(code)
49
+ println(s"-------------")
50
+ }
51
+ }
@@ -0,0 +1,34 @@
1
+ import java.io.File
2
+
3
+ import testgen.TestSuiteBuilder.{toString, _}
4
+ import testgen._
5
+
6
+ object RunLengthEncodingTestGenerator {
7
+ private def toString(expected: CanonicalDataParser.Expected): String =
8
+ expected.fold(_ => "", TestSuiteBuilder.toString)
9
+
10
+ def fromLabeledTestAlt(propArgs: (String, Seq[String])*): ToTestCaseData =
11
+ withLabeledTest { sut => labeledTest =>
12
+ val sutFunction = labeledTest.property
13
+ val args = sutArgsAlt(labeledTest.result, propArgs:_*)
14
+ val sutCall =
15
+ if (sutFunction.toString == "consistency")
16
+ s"$sut.decode($sut.encode($args))"
17
+ else
18
+ s"$sut.$sutFunction($args)"
19
+ val expected = toString(labeledTest.expected)
20
+
21
+ TestCaseData(s"$sutFunction - ${labeledTest.description}", sutCall, expected)
22
+ }
23
+
24
+ def main(args: Array[String]): Unit = {
25
+ val file = new File("src/main/resources/run-length-encoding.json")
26
+
27
+ val code = TestSuiteBuilder.build(file,
28
+ fromLabeledTestAlt("encode" -> Seq("input"), "decode" -> Seq("input"),
29
+ "consistency" -> Seq("input")))
30
+ println(s"-------------")
31
+ println(code)
32
+ println(s"-------------")
33
+ }
34
+ }
@@ -10,6 +10,7 @@ object TestSuiteBuilder {
10
10
 
11
11
  type TestSuiteTemplate = Template1[TestSuiteData, Txt]
12
12
  type ToTestCaseData = String => LabeledTestItem => TestCaseData
13
+ type ToOptionTestCaseData = String => LabeledTestItem => Option[TestCaseData]
13
14
 
14
15
  private val DefaultTemplate: TestSuiteTemplate =
15
16
  txt.funSuiteTemplate.asInstanceOf[Template1[TestSuiteData, Txt]]
@@ -29,9 +30,27 @@ object TestSuiteBuilder {
29
30
  template.render(testSuiteData).toString
30
31
  }
31
32
 
33
+ def buildFromOption(file: File, toTestCaseData: ToOptionTestCaseData, imports: Seq[String] = Seq())(
34
+ implicit template: TestSuiteTemplate = DefaultTemplate): String =
35
+ {
36
+ val exercise @ Exercise(name, version, cases, comments) =
37
+ CanonicalDataParser.parse(file)
38
+ val tsName = testSuiteName(name)
39
+ val testCasesAllPending = cases.map(toTestCaseData(sutName(name))).flatten
40
+ val testCases =
41
+ testCasesAllPending updated(0, testCasesAllPending.head.copy(pending = false))
42
+ val testSuiteData =
43
+ TestSuiteData(tsName, version, imports, testCases)
44
+
45
+ template.render(testSuiteData).toString
46
+ }
47
+
32
48
  def withLabeledTest(f: String => LabeledTest => TestCaseData): ToTestCaseData =
33
49
  sut => item => f(sut)(item.asInstanceOf[LabeledTest])
34
50
 
51
+ def withLabeledTestOpt(f: String => LabeledTest => Option[TestCaseData]): ToOptionTestCaseData =
52
+ sut => item => f(sut)(item.asInstanceOf[LabeledTest])
53
+
35
54
  def fromLabeledTest(argNames: String*): ToTestCaseData =
36
55
  withLabeledTest { sut => labeledTest =>
37
56
  val sutFunction = labeledTest.property
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trackler
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.1.3
4
+ version: 2.2.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Katrina Owen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-26 00:00:00.000000000 Z
11
+ date: 2017-07-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyzip
@@ -9342,6 +9342,10 @@ files:
9342
9342
  - tracks/ruby/exercises/bracket-push/.meta/solutions/bracket_push.rb
9343
9343
  - tracks/ruby/exercises/bracket-push/README.md
9344
9344
  - tracks/ruby/exercises/bracket-push/bracket_push_test.rb
9345
+ - tracks/ruby/exercises/change/.meta/.version
9346
+ - tracks/ruby/exercises/change/.meta/generator/change_case.rb
9347
+ - tracks/ruby/exercises/change/.meta/solutions/change.rb
9348
+ - tracks/ruby/exercises/change/change_test.rb
9345
9349
  - tracks/ruby/exercises/circular-buffer/.meta/solutions/circular_buffer.rb
9346
9350
  - tracks/ruby/exercises/circular-buffer/README.md
9347
9351
  - tracks/ruby/exercises/circular-buffer/circular_buffer_test.rb
@@ -9974,6 +9978,12 @@ files:
9974
9978
  - tracks/rust/exercises/pig-latin/example.rs
9975
9979
  - tracks/rust/exercises/pig-latin/src/lib.rs
9976
9980
  - tracks/rust/exercises/pig-latin/tests/pig-latin.rs
9981
+ - tracks/rust/exercises/prime-factors/Cargo.lock
9982
+ - tracks/rust/exercises/prime-factors/Cargo.toml
9983
+ - tracks/rust/exercises/prime-factors/README.md
9984
+ - tracks/rust/exercises/prime-factors/example.rs
9985
+ - tracks/rust/exercises/prime-factors/src/lib.rs
9986
+ - tracks/rust/exercises/prime-factors/tests/prime-factors.rs
9977
9987
  - tracks/rust/exercises/protein-translation/.gitignore
9978
9988
  - tracks/rust/exercises/protein-translation/Cargo.lock
9979
9989
  - tracks/rust/exercises/protein-translation/Cargo.toml
@@ -9981,6 +9991,12 @@ files:
9981
9991
  - tracks/rust/exercises/protein-translation/example.rs
9982
9992
  - tracks/rust/exercises/protein-translation/src/lib.rs
9983
9993
  - tracks/rust/exercises/protein-translation/tests/proteins.rs
9994
+ - tracks/rust/exercises/proverb/Cargo.lock
9995
+ - tracks/rust/exercises/proverb/Cargo.toml
9996
+ - tracks/rust/exercises/proverb/README.md
9997
+ - tracks/rust/exercises/proverb/example.rs
9998
+ - tracks/rust/exercises/proverb/src/lib.rs
9999
+ - tracks/rust/exercises/proverb/tests/proverb.rs
9984
10000
  - tracks/rust/exercises/queen-attack/.gitignore
9985
10001
  - tracks/rust/exercises/queen-attack/Cargo.lock
9986
10002
  - tracks/rust/exercises/queen-attack/Cargo.toml
@@ -10485,7 +10501,7 @@ files:
10485
10501
  - tracks/scala/exercises/run-length-encoding/README.md
10486
10502
  - tracks/scala/exercises/run-length-encoding/build.sbt
10487
10503
  - tracks/scala/exercises/run-length-encoding/example.scala
10488
- - tracks/scala/exercises/run-length-encoding/src/main/scala/RunLengthEncoding.scala
10504
+ - tracks/scala/exercises/run-length-encoding/src/main/scala/.keep
10489
10505
  - tracks/scala/exercises/run-length-encoding/src/test/scala/RunLengthEncodingTests.scala
10490
10506
  - tracks/scala/exercises/saddle-points/README.md
10491
10507
  - tracks/scala/exercises/saddle-points/build.sbt
@@ -10621,12 +10637,14 @@ files:
10621
10637
  - tracks/scala/testgen/src/main/scala/LeapTestGenerator.scala
10622
10638
  - tracks/scala/testgen/src/main/scala/NucleotideCountTestGenerator.scala
10623
10639
  - tracks/scala/testgen/src/main/scala/PangramsTestGenerator.scala
10640
+ - tracks/scala/testgen/src/main/scala/PascalsTriangleTestGenerator.scala
10624
10641
  - tracks/scala/testgen/src/main/scala/PerfectNumbersTestGenerator.scala
10625
10642
  - tracks/scala/testgen/src/main/scala/PhoneNumberTestGenerator.scala
10626
10643
  - tracks/scala/testgen/src/main/scala/PrimeFactorsTestGenerator.scala
10627
10644
  - tracks/scala/testgen/src/main/scala/RailFenceCipherTestGenerator.scala
10628
10645
  - tracks/scala/testgen/src/main/scala/RaindropsTestGenerator.scala
10629
10646
  - tracks/scala/testgen/src/main/scala/RnaTranscriptionTestGenerator.scala
10647
+ - tracks/scala/testgen/src/main/scala/RunLengthEncodingTestGenerator.scala
10630
10648
  - tracks/scala/testgen/src/main/scala/ScrabbleScoreTestGenerator.scala
10631
10649
  - tracks/scala/testgen/src/main/scala/SecretHandshakeTestGenerator.scala
10632
10650
  - tracks/scala/testgen/src/main/scala/SeriesTestGenerator.scala
@@ -1,6 +0,0 @@
1
- object RunLengthEncoding {
2
-
3
- def encode(str: String): String = ???
4
-
5
- def decode(str: String): String = ???
6
- }