trackler 2.2.1.20 → 2.2.1.21
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/csharp/config.json +11 -0
- data/tracks/csharp/exercises/Exercises.All.sln +15 -1
- data/tracks/csharp/exercises/Exercises.Default.sln +120 -106
- data/tracks/csharp/exercises/complex-numbers/ComplexNumbers.cs +53 -0
- data/tracks/csharp/exercises/complex-numbers/ComplexNumbers.csproj +18 -0
- data/tracks/csharp/exercises/complex-numbers/ComplexNumbersTest.cs +255 -0
- data/tracks/csharp/exercises/complex-numbers/Example.cs +78 -0
- data/tracks/csharp/exercises/grains/Example.cs +8 -1
- data/tracks/csharp/exercises/grains/GrainsTest.cs +38 -17
- data/tracks/csharp/generators/Exercises/ComplexNumbers.cs +119 -0
- data/tracks/csharp/generators/Exercises/Grains.cs +29 -0
- data/tracks/csharp/generators/Output/ValueFormatter.cs +2 -0
- data/tracks/delphi/exercises/two-fer/utwoferExample.pas +2 -5
- data/tracks/ecmascript/exercises/queen-attack/example.js +28 -23
- data/tracks/ecmascript/exercises/queen-attack/queen-attack.spec.js +10 -15
- data/tracks/java/config.json +1 -0
- data/tracks/r/exercises/perfect-numbers/example.R +1 -1
- data/tracks/r/exercises/perfect-numbers/perfect-numbers.R +1 -1
- data/tracks/r/exercises/perfect-numbers/test_perfect-numbers.R +13 -13
- data/tracks/ruby/docs/24pullrequests.md +1 -1
- data/tracks/ruby/exercises/hello-world/.meta/generator/test_template.erb +1 -1
- data/tracks/ruby/exercises/hello-world/hello_world_test.rb +1 -1
- data/tracks/ruby/test/generator/command_line/generator_optparser_test.rb +1 -1
- data/tracks/ruby/test/generator/command_line_test.rb +1 -1
- data/tracks/ruby/test/generator/files/metadata_files_test.rb +1 -1
- data/tracks/rust/exercises/accumulate/README.md +0 -3
- data/tracks/rust/exercises/beer-song/src/lib.rs +7 -0
- data/tracks/rust/exercises/bob/src/lib.rs +3 -0
- data/tracks/rust/exercises/bowling/example.rs +1 -1
- data/tracks/rust/exercises/difference-of-squares/src/lib.rs +11 -0
- data/tracks/rust/exercises/grade-school/example.rs +1 -1
- data/tracks/rust/exercises/leap/src/lib.rs +3 -0
- data/tracks/rust/exercises/proverb/src/lib.rs +3 -0
- data/tracks/rust/exercises/raindrops/src/lib.rs +3 -0
- data/tracks/rust/exercises/sum-of-multiples/src/lib.rs +3 -0
- data/tracks/scala/exercises/space-age/example.scala +26 -20
- data/tracks/scala/exercises/space-age/src/main/scala/.keep +0 -0
- data/tracks/scala/exercises/space-age/src/test/scala/SpaceAgeTest.scala +19 -38
- data/tracks/scala/exercises/sublist/src/test/scala/SublistTest.scala +36 -44
- data/tracks/scala/testgen/src/main/scala/SpaceAgeTestGenerator.scala +39 -0
- data/tracks/scala/testgen/src/main/scala/SublistTestGenerator.scala +38 -0
- metadata +11 -3
- data/tracks/scala/exercises/space-age/src/main/scala/SpaceAge.scala +0 -10
@@ -0,0 +1,119 @@
|
|
1
|
+
using System;
|
2
|
+
using System.Collections.Generic;
|
3
|
+
using System.Linq;
|
4
|
+
using Generators.Input;
|
5
|
+
using Generators.Output;
|
6
|
+
using Newtonsoft.Json.Linq;
|
7
|
+
|
8
|
+
namespace Generators.Exercises
|
9
|
+
{
|
10
|
+
public class ComplexNumbers : Exercise
|
11
|
+
{
|
12
|
+
protected override void UpdateCanonicalData(CanonicalData canonicalData)
|
13
|
+
{
|
14
|
+
canonicalData.Exercise = "complex-number";
|
15
|
+
|
16
|
+
// Ensure the Real and Imaginary methods are tested first as they're used later to assert equality between complex numbers
|
17
|
+
canonicalData.Cases = canonicalData.Cases.OrderBy(c => c.Property == "real" || c.Property == "imaginary" ? 0 : 1).ToArray();
|
18
|
+
|
19
|
+
foreach (var canonicalDataCase in canonicalData.Cases)
|
20
|
+
{
|
21
|
+
canonicalDataCase.TestedMethodType = TestedMethodType.Instance;
|
22
|
+
|
23
|
+
// Process expected
|
24
|
+
if (IsComplexNumber(canonicalDataCase.Expected))
|
25
|
+
{
|
26
|
+
canonicalDataCase.UseVariableForExpected = true;
|
27
|
+
}
|
28
|
+
|
29
|
+
canonicalDataCase.Expected = ConvertToType(canonicalDataCase.Expected);
|
30
|
+
|
31
|
+
// Process constructor param
|
32
|
+
var constructorParamName = canonicalDataCase.Input.ContainsKey("input") ? "input" : "z1";
|
33
|
+
|
34
|
+
var constructorParamValues = canonicalDataCase.Input[constructorParamName]
|
35
|
+
.ConvertToEnumerable<string>()
|
36
|
+
.Select(v => ConvertMathDouble(v))
|
37
|
+
.ToArray();
|
38
|
+
|
39
|
+
canonicalDataCase.ConstructorInput = new Dictionary<string, object>
|
40
|
+
{
|
41
|
+
["real"] = constructorParamValues[0],
|
42
|
+
["imaginary"] = constructorParamValues[1]
|
43
|
+
};
|
44
|
+
|
45
|
+
canonicalDataCase.Input.Remove(constructorParamName);
|
46
|
+
|
47
|
+
// Process function param
|
48
|
+
var keys = canonicalDataCase.Input.Keys.ToArray();
|
49
|
+
|
50
|
+
foreach (var key in keys)
|
51
|
+
{
|
52
|
+
canonicalDataCase.Input[key] = ConvertToType(canonicalDataCase.Input[key]);
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
protected override string RenderTestMethodBodyAssert(TestMethodBody testMethodBody)
|
58
|
+
{
|
59
|
+
if (testMethodBody.UseVariableForExpected)
|
60
|
+
return RenderComplexNumberAssert(testMethodBody);
|
61
|
+
|
62
|
+
return base.RenderTestMethodBodyAssert(testMethodBody);
|
63
|
+
}
|
64
|
+
|
65
|
+
private static string RenderComplexNumberAssert(TestMethodBody testMethodBody)
|
66
|
+
{
|
67
|
+
var tmeplate = "Assert.Equal({{ ExpectedParameter }}.Real(), {{ TestedValue }}.Real(), 15);\r\nAssert.Equal({{ ExpectedParameter }}.Imaginary(), {{ TestedValue }}.Imaginary(), 15);";
|
68
|
+
|
69
|
+
return TemplateRenderer.RenderInline(tmeplate, testMethodBody.AssertTemplateParameters);
|
70
|
+
}
|
71
|
+
|
72
|
+
protected override HashSet<string> GetUsingNamespaces()
|
73
|
+
{
|
74
|
+
var usingNamespaces = base.GetUsingNamespaces();
|
75
|
+
usingNamespaces.Add(typeof(Math).Namespace);
|
76
|
+
|
77
|
+
return usingNamespaces;
|
78
|
+
}
|
79
|
+
|
80
|
+
private object ConvertToType(object rawValue)
|
81
|
+
{
|
82
|
+
if (IsComplexNumber(rawValue))
|
83
|
+
{
|
84
|
+
var array = rawValue
|
85
|
+
.ConvertToEnumerable<string>()
|
86
|
+
.Select(rv => ConvertToType(rv))
|
87
|
+
.ToArray();
|
88
|
+
|
89
|
+
return new UnescapedValue($"new ComplexNumber({array[0]}, {array[1]})");
|
90
|
+
}
|
91
|
+
else if (rawValue is string)
|
92
|
+
{
|
93
|
+
return ConvertMathDouble((string)rawValue);
|
94
|
+
}
|
95
|
+
else
|
96
|
+
{
|
97
|
+
return rawValue;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
|
101
|
+
private bool IsComplexNumber(object rawValue)
|
102
|
+
{
|
103
|
+
return rawValue is JArray;
|
104
|
+
}
|
105
|
+
|
106
|
+
private object ConvertMathDouble(string value)
|
107
|
+
{
|
108
|
+
switch (value)
|
109
|
+
{
|
110
|
+
case "e":
|
111
|
+
return new UnescapedValue("Math.E");
|
112
|
+
case "pi":
|
113
|
+
return new UnescapedValue("Math.PI");
|
114
|
+
default:
|
115
|
+
return double.Parse(value);
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
using System;
|
2
|
+
using Generators.Input;
|
3
|
+
|
4
|
+
namespace Generators.Exercises
|
5
|
+
{
|
6
|
+
public class Grains : Exercise
|
7
|
+
{
|
8
|
+
protected override void UpdateCanonicalData(CanonicalData canonicalData)
|
9
|
+
{
|
10
|
+
foreach (var canonicalDataCase in canonicalData.Cases)
|
11
|
+
{
|
12
|
+
if (ShouldThrowException(canonicalDataCase.Expected))
|
13
|
+
{
|
14
|
+
canonicalDataCase.ExceptionThrown = typeof(ArgumentOutOfRangeException);
|
15
|
+
}
|
16
|
+
else
|
17
|
+
{
|
18
|
+
canonicalDataCase.Expected = ulong.Parse(canonicalDataCase.Expected.ToString());
|
19
|
+
}
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
private static bool ShouldThrowException(object value)
|
24
|
+
{
|
25
|
+
return int.TryParse(value.ToString(), out int result)
|
26
|
+
&& result == -1;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
@@ -2,15 +2,12 @@ unit utwofer;
|
|
2
2
|
|
3
3
|
interface
|
4
4
|
|
5
|
-
function twoFer(aName: string=''): string;
|
5
|
+
function twoFer(aName: string='you'): string;
|
6
6
|
|
7
7
|
implementation
|
8
|
-
uses SysUtils;
|
9
8
|
|
10
|
-
function twoFer(aName: string=''): string;
|
9
|
+
function twoFer(aName: string='you'): string;
|
11
10
|
begin
|
12
|
-
if trim(aName).IsEmpty then
|
13
|
-
aName := 'you';
|
14
11
|
result := 'One for ' + aName + ', one for me.';
|
15
12
|
end;
|
16
13
|
|
@@ -1,10 +1,34 @@
|
|
1
|
-
const W = 8
|
2
|
-
|
3
|
-
|
1
|
+
const W = 8;
|
2
|
+
const H = 8;
|
3
|
+
const STARTING = { black: [7, 3], white: [0, 3] };
|
4
|
+
|
5
|
+
function samePosition({ white, black }) {
|
6
|
+
return white[0] === black[0] && white[1] === black[1];
|
7
|
+
}
|
8
|
+
|
9
|
+
function buildRow(cell, colCount) {
|
10
|
+
return Array(...Array(colCount)).map(() => cell);
|
11
|
+
}
|
12
|
+
|
13
|
+
function concatRows(row, rowCount) {
|
14
|
+
return [...Array.prototype.concat.apply(buildRow(row, rowCount)).join('')];
|
15
|
+
}
|
16
|
+
|
17
|
+
function constructBoard() {
|
18
|
+
let row = buildRow('_ ', W).join('');
|
19
|
+
row = `${row.substring(0, row.length - 1)}\n`;
|
20
|
+
return concatRows(row, H);
|
21
|
+
}
|
22
|
+
|
23
|
+
function placePieces(self) {
|
24
|
+
const board = self.board;
|
25
|
+
board[(self.black[0] * W * 2) + (self.black[1] * 2)] = 'B';
|
26
|
+
board[(self.white[0] * W * 2) + (self.white[1] * 2)] = 'W';
|
27
|
+
}
|
4
28
|
|
5
29
|
const QueenAttack = (params = STARTING) => {
|
6
30
|
const self = this instanceof QueenAttack ? this : Object.getPrototypeOf(QueenAttack);
|
7
|
-
if (params
|
31
|
+
if (samePosition(params)) {
|
8
32
|
throw new Error('Queens cannot share the same space');
|
9
33
|
}
|
10
34
|
|
@@ -25,23 +49,4 @@ const QueenAttack = (params = STARTING) => {
|
|
25
49
|
return self;
|
26
50
|
};
|
27
51
|
|
28
|
-
function constructBoard() {
|
29
|
-
let row = buildRow('_ ', W).join('');
|
30
|
-
row = `${row.substring(0, row.length - 1)}\n`;
|
31
|
-
return concatRows(row, H);
|
32
|
-
}
|
33
|
-
|
34
|
-
function placePieces(self) {
|
35
|
-
self.board[self.black[0] * W * 2 + self.black[1] * 2] = 'B';
|
36
|
-
self.board[self.white[0] * W * 2 + self.white[1] * 2] = 'W';
|
37
|
-
}
|
38
|
-
|
39
|
-
function buildRow(cell, colCount) {
|
40
|
-
return Array(...Array(colCount)).map(() => cell);
|
41
|
-
}
|
42
|
-
|
43
|
-
function concatRows(row, rowCount) {
|
44
|
-
return [...Array.prototype.concat.apply(buildRow(row, rowCount)).join('')];
|
45
|
-
}
|
46
|
-
|
47
52
|
export default QueenAttack;
|
@@ -15,26 +15,21 @@ describe('Queens', () => {
|
|
15
15
|
|
16
16
|
xtest('cannot occupy the same space', () => {
|
17
17
|
const positioning = { white: [2, 4], black: [2, 4] };
|
18
|
-
|
19
|
-
|
20
|
-
new Queens(positioning);
|
21
|
-
} catch (error) {
|
22
|
-
expect(error).toEqual('Queens cannot share the same space');
|
23
|
-
}
|
18
|
+
const expectedError = 'Queens cannot share the same space';
|
19
|
+
expect(() => new Queens(positioning)).toThrow(expectedError);
|
24
20
|
});
|
25
21
|
|
26
22
|
xtest('toString representation', () => {
|
27
23
|
const positioning = { white: [2, 4], black: [6, 6] };
|
28
24
|
const queens = new Queens(positioning);
|
29
|
-
const board = '_ _ _ _ _ _ _ _
|
30
|
-
_ _ _ _ _ _ _ _
|
31
|
-
_ _ _ _ W _ _ _
|
32
|
-
_ _ _ _ _ _ _ _
|
33
|
-
_ _ _ _ _ _ _ _
|
34
|
-
_ _ _ _ _ _ _ _
|
35
|
-
_ _ _ _ _ _ B _
|
36
|
-
_ _ _ _ _ _ _ _\n\
|
37
|
-
';
|
25
|
+
const board = ['_ _ _ _ _ _ _ _',
|
26
|
+
'_ _ _ _ _ _ _ _',
|
27
|
+
'_ _ _ _ W _ _ _',
|
28
|
+
'_ _ _ _ _ _ _ _',
|
29
|
+
'_ _ _ _ _ _ _ _',
|
30
|
+
'_ _ _ _ _ _ _ _',
|
31
|
+
'_ _ _ _ _ _ B _',
|
32
|
+
'_ _ _ _ _ _ _ _\n'].join('\n');
|
38
33
|
expect(queens.toString()).toEqual(board);
|
39
34
|
});
|
40
35
|
|
data/tracks/java/config.json
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"language": "Java",
|
3
3
|
"active": true,
|
4
|
+
"blurb": "Java is a very widely used Object Oriented programming language. It's safe, simple to use and portable so that you can \"write once, run anywhere\".",
|
4
5
|
"exercises": [
|
5
6
|
{
|
6
7
|
"uuid": "f77dc7e3-35a8-4300-a7c8-2c1765e9644d",
|
@@ -3,73 +3,73 @@ library(testthat)
|
|
3
3
|
|
4
4
|
test_that("Smallest perfect number is classified correctly", {
|
5
5
|
n <- 6
|
6
|
-
expect_equal(
|
6
|
+
expect_equal(number_type(n), "perfect")
|
7
7
|
})
|
8
8
|
|
9
9
|
test_that("Medium perfect number is classified correctly", {
|
10
10
|
n <- 28
|
11
|
-
expect_equal(
|
11
|
+
expect_equal(number_type(n), "perfect")
|
12
12
|
})
|
13
13
|
|
14
14
|
test_that("Large perfect number is classified correctly", {
|
15
15
|
n <- 33550336
|
16
|
-
expect_equal(
|
16
|
+
expect_equal(number_type(n), "perfect")
|
17
17
|
})
|
18
18
|
|
19
19
|
|
20
20
|
|
21
21
|
test_that("Smallest abundant number is classified correctly", {
|
22
22
|
n <- 12
|
23
|
-
expect_equal(
|
23
|
+
expect_equal(number_type(n), "abundant")
|
24
24
|
})
|
25
25
|
|
26
26
|
test_that("Medium abundant number is classified correctly", {
|
27
27
|
n <- 30
|
28
|
-
expect_equal(
|
28
|
+
expect_equal(number_type(n), "abundant")
|
29
29
|
})
|
30
30
|
|
31
31
|
test_that("Large abundant number is classified correctly", {
|
32
32
|
n <- 33550335
|
33
|
-
expect_equal(
|
33
|
+
expect_equal(number_type(n), "abundant")
|
34
34
|
})
|
35
35
|
|
36
36
|
|
37
37
|
|
38
38
|
test_that("Smallest prime deficient number is classified correctly", {
|
39
39
|
n <- 2
|
40
|
-
expect_equal(
|
40
|
+
expect_equal(number_type(n), "deficient")
|
41
41
|
})
|
42
42
|
|
43
43
|
test_that("Smallest non-prime deficient number is classified correctly", {
|
44
44
|
n <- 4
|
45
|
-
expect_equal(
|
45
|
+
expect_equal(number_type(n), "deficient")
|
46
46
|
})
|
47
47
|
|
48
48
|
test_that("Medium deficient number is classified correctly", {
|
49
49
|
n <- 32
|
50
|
-
expect_equal(
|
50
|
+
expect_equal(number_type(n), "deficient")
|
51
51
|
})
|
52
52
|
|
53
53
|
test_that("Large deficient number is classified correctly", {
|
54
54
|
n <- 33550337
|
55
|
-
expect_equal(
|
55
|
+
expect_equal(number_type(n), "deficient")
|
56
56
|
})
|
57
57
|
|
58
58
|
test_that("Edge case (no factors other than itself) is classified correctly", {
|
59
59
|
n <- 1
|
60
|
-
expect_equal(
|
60
|
+
expect_equal(number_type(n), "deficient")
|
61
61
|
})
|
62
62
|
|
63
63
|
|
64
64
|
|
65
65
|
test_that("Zero is rejected (not a natural number)", {
|
66
66
|
n <- 0
|
67
|
-
expect_error(
|
67
|
+
expect_error(number_type(n))
|
68
68
|
})
|
69
69
|
|
70
70
|
test_that("Negative integer is rejected (not a natural number)", {
|
71
71
|
n <- -1
|
72
|
-
expect_error(
|
72
|
+
expect_error(number_type(n))
|
73
73
|
})
|
74
74
|
|
75
75
|
|
@@ -18,4 +18,4 @@ Something missing? Create a pull request!
|
|
18
18
|
|
19
19
|
Check out the [Getting Involved in a Track](https://github.com/exercism/exercism.io/blob/master/docs/getting-involved-in-a-track.md) documentation, and some [ideas for things we are looking for](http://exercism.io/languages/ruby/todo) for exercises that are needed to be implemented.
|
20
20
|
|
21
|
-
We are available to answer questions in the
|
21
|
+
We are available to answer questions in the [![Join the chat at https://gitter.im/exercism/ruby](https://badges.gitter.im/exercism/ruby.svg)](https://gitter.im/exercism/ruby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge).
|
@@ -4,7 +4,7 @@ begin
|
|
4
4
|
require_relative 'hello_world'
|
5
5
|
rescue Gem::LoadError => e
|
6
6
|
puts "\nMissing Dependency:\n#{e.backtrace.first} #{e.message}"
|
7
|
-
puts 'Minitest 5.0 gem must be installed for the
|
7
|
+
puts 'Minitest 5.0 gem must be installed for the Ruby track.'
|
8
8
|
rescue LoadError => e
|
9
9
|
puts "\nError:\n#{e.backtrace.first} #{e.message}"
|
10
10
|
puts DATA.read
|
@@ -4,7 +4,7 @@ begin
|
|
4
4
|
require_relative 'hello_world'
|
5
5
|
rescue Gem::LoadError => e
|
6
6
|
puts "\nMissing Dependency:\n#{e.backtrace.first} #{e.message}"
|
7
|
-
puts 'Minitest 5.0 gem must be installed for the
|
7
|
+
puts 'Minitest 5.0 gem must be installed for the Ruby track.'
|
8
8
|
rescue LoadError => e
|
9
9
|
puts "\nError:\n#{e.backtrace.first} #{e.message}"
|
10
10
|
puts DATA.read
|