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.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/tracks/java/exercises/sum-of-multiples/src/example/java/SumOfMultiples.java +6 -16
- data/tracks/ruby/config.json +13 -0
- data/tracks/ruby/exercises/change/.meta/.version +1 -0
- data/tracks/ruby/exercises/change/.meta/generator/change_case.rb +9 -0
- data/tracks/ruby/exercises/change/.meta/solutions/change.rb +58 -0
- data/tracks/ruby/exercises/change/change_test.rb +77 -0
- data/tracks/rust/config.json +20 -0
- data/tracks/rust/exercises/prime-factors/Cargo.lock +4 -0
- data/tracks/rust/exercises/prime-factors/Cargo.toml +6 -0
- data/tracks/rust/exercises/prime-factors/README.md +68 -0
- data/tracks/rust/exercises/prime-factors/example.rs +13 -0
- data/tracks/rust/exercises/prime-factors/src/lib.rs +0 -0
- data/tracks/rust/exercises/prime-factors/tests/prime-factors.rs +44 -0
- data/tracks/rust/exercises/proverb/Cargo.lock +4 -0
- data/tracks/rust/exercises/proverb/Cargo.toml +6 -0
- data/tracks/rust/exercises/proverb/README.md +50 -0
- data/tracks/rust/exercises/proverb/example.rs +17 -0
- data/tracks/rust/exercises/proverb/src/lib.rs +0 -0
- data/tracks/rust/exercises/proverb/tests/proverb.rs +52 -0
- data/tracks/scala/exercises/pascals-triangle/example.scala +1 -1
- data/tracks/scala/exercises/pascals-triangle/src/test/scala/PascalsTriangleTest.scala +17 -20
- data/tracks/scala/exercises/run-length-encoding/src/main/scala/.keep +0 -0
- data/tracks/scala/exercises/run-length-encoding/src/test/scala/RunLengthEncodingTests.scala +38 -21
- data/tracks/scala/testgen/src/main/scala/PascalsTriangleTestGenerator.scala +51 -0
- data/tracks/scala/testgen/src/main/scala/RunLengthEncodingTestGenerator.scala +34 -0
- data/tracks/scala/testgen/src/main/scala/testgen/TestSuiteBuilder.scala +19 -0
- metadata +21 -3
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97638638dc6720c36ddae0926221e2947f683e95
|
4
|
+
data.tar.gz: caf86db5732ca7d826613d9b8cb4dbfa00702339
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 48d697aabfd7dd44f0247c4c9e0b44bf945016206525280fe09e513cfbab292ea5b1d644e82072c6f27a25ae927cc6710c813a4ae0a860f7a070a57f84f99ee0
|
7
|
+
data.tar.gz: 661a015ebfc069b4f9c00be5dc44b2ab2c91813f97b407bb3fa9205d9393c8eb653a22593f63070458678f540c98cf59475e7cf19e5e40311f1ceaa2732cc354
|
data/lib/trackler/version.rb
CHANGED
@@ -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 =
|
15
|
-
|
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
|
}
|
data/tracks/ruby/config.json
CHANGED
@@ -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 @@
|
|
1
|
+
1
|
@@ -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
|
data/tracks/rust/config.json
CHANGED
@@ -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,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.
|
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,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,37 +1,34 @@
|
|
1
|
-
import org.scalatest.{Matchers,
|
1
|
+
import org.scalatest.{Matchers, FunSuite}
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
-
|
10
|
+
test("single row") {
|
9
11
|
pending
|
10
|
-
PascalsTriangle.
|
12
|
+
PascalsTriangle.rows(1) should be (List(List(1)))
|
11
13
|
}
|
12
14
|
|
13
|
-
|
15
|
+
test("two rows") {
|
14
16
|
pending
|
15
|
-
PascalsTriangle.
|
17
|
+
PascalsTriangle.rows(2) should be (List(List(1), List(1, 1)))
|
16
18
|
}
|
17
19
|
|
18
|
-
|
20
|
+
test("three rows") {
|
19
21
|
pending
|
20
|
-
PascalsTriangle.
|
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
|
-
|
25
|
+
test("four rows") {
|
25
26
|
pending
|
26
|
-
PascalsTriangle.
|
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
|
-
|
30
|
+
test("negative rows") {
|
31
31
|
pending
|
32
|
-
PascalsTriangle.
|
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
|
+
}
|
File without changes
|
@@ -1,52 +1,69 @@
|
|
1
|
-
import org.scalatest.FunSuite
|
2
|
-
import org.scalatest.Matchers
|
1
|
+
import org.scalatest.{Matchers, FunSuite}
|
3
2
|
|
4
|
-
|
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("
|
15
|
+
test("encode - string with no single characters") {
|
16
16
|
pending
|
17
|
-
RunLengthEncoding.
|
17
|
+
RunLengthEncoding.encode("AABBBCCCC") should be ("2A3B4C")
|
18
18
|
}
|
19
19
|
|
20
|
-
test("
|
20
|
+
test("encode - single characters mixed with repeated characters") {
|
21
21
|
pending
|
22
|
-
RunLengthEncoding.
|
22
|
+
RunLengthEncoding.encode("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB") should be ("12WB12W3B24WB")
|
23
23
|
}
|
24
24
|
|
25
|
-
test("encode
|
25
|
+
test("encode - multiple whitespace mixed in string") {
|
26
26
|
pending
|
27
|
-
RunLengthEncoding.encode("
|
27
|
+
RunLengthEncoding.encode(" hsqq qww ") should be ("2 hs2q q2w2 ")
|
28
28
|
}
|
29
29
|
|
30
|
-
test("
|
30
|
+
test("encode - lowercase characters") {
|
31
31
|
pending
|
32
|
-
RunLengthEncoding.
|
32
|
+
RunLengthEncoding.encode("aabbbcccc") should be ("2a3b4c")
|
33
33
|
}
|
34
34
|
|
35
|
-
test("
|
35
|
+
test("decode - empty string") {
|
36
36
|
pending
|
37
|
-
RunLengthEncoding.
|
38
|
-
|
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
|
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
|
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.
|
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-
|
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
|
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
|