trackler 2.0.3.4 → 2.0.3.5

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 (83) hide show
  1. checksums.yaml +4 -4
  2. data/common/exercises/all-your-base/canonical-data.json +21 -21
  3. data/common/exercises/wordy/description.md +24 -38
  4. data/common/exercises/wordy/metadata.yml +1 -1
  5. data/lib/trackler/version.rb +1 -1
  6. data/tracks/c/config.json +10 -0
  7. data/tracks/c/exercises/meetup/makefile +15 -0
  8. data/tracks/c/exercises/meetup/src/example.c +139 -0
  9. data/tracks/c/exercises/meetup/src/example.h +7 -0
  10. data/tracks/c/exercises/meetup/test/test_meetup.c +223 -0
  11. data/tracks/c/exercises/meetup/test/vendor/unity.c +1300 -0
  12. data/tracks/c/exercises/meetup/test/vendor/unity.h +274 -0
  13. data/tracks/c/exercises/meetup/test/vendor/unity_internals.h +701 -0
  14. data/tracks/crystal/config.json +12 -0
  15. data/tracks/crystal/exercises/pascals-triangle/spec/pascals_triangle_spec.cr +30 -0
  16. data/tracks/crystal/exercises/pascals-triangle/src/example.cr +19 -0
  17. data/tracks/crystal/exercises/pascals-triangle/src/pascals_triangle.cr +1 -0
  18. data/tracks/crystal/exercises/run-length-encoding/spec/run_length_encoding_spec.cr +36 -0
  19. data/tracks/crystal/exercises/run-length-encoding/src/example.cr +40 -0
  20. data/tracks/crystal/src/generator/exercises/pascals-triangle.cr +58 -0
  21. data/tracks/crystal/src/generator/exercises/run_length_encoding.cr +42 -0
  22. data/tracks/javascript/config.json +8 -1
  23. data/tracks/javascript/exercises/all-your-base/all-your-base.spec.js +141 -0
  24. data/tracks/javascript/exercises/all-your-base/example.js +59 -0
  25. data/tracks/javascript/exercises/word-count/example.js +5 -5
  26. data/tracks/javascript/exercises/word-count/word-count.spec.js +23 -8
  27. data/tracks/lua/SETUP.md +60 -7
  28. data/tracks/lua/config.json +9 -0
  29. data/tracks/lua/exercises/say/example.lua +4 -4
  30. data/tracks/lua/exercises/variable-length-quantity/example.lua +36 -0
  31. data/tracks/lua/exercises/variable-length-quantity/variable-length-quantity_spec.lua +73 -0
  32. data/tracks/objective-c/.travis.yml +1 -0
  33. data/tracks/objective-c/config.json +8 -0
  34. data/tracks/objective-c/docs/TESTS.md +1 -1
  35. data/tracks/objective-c/exercises/transpose/TransposeExample.h +7 -0
  36. data/tracks/objective-c/exercises/transpose/TransposeExample.m +59 -0
  37. data/tracks/objective-c/exercises/transpose/TransposeTest.m +150 -0
  38. data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +18 -0
  39. data/tracks/ocaml/.gitignore +1 -0
  40. data/tracks/ocaml/tools/test-generator/Makefile +3 -0
  41. data/tracks/ocaml/tools/test-generator/src/controller.ml +11 -16
  42. data/tracks/ocaml/tools/test-generator/src/model.ml +4 -0
  43. data/tracks/ocaml/tools/test-generator/src/parser.ml +8 -1
  44. data/tracks/ocaml/tools/test-generator/src/special_cases.ml +5 -0
  45. data/tracks/ocaml/tools/test-generator/templates/all-your-base/template.ml +16 -0
  46. data/tracks/ocaml/tools/test-generator/test/model_test.ml +2 -0
  47. data/tracks/ocaml/tools/test-generator/test/parser_test.ml +8 -0
  48. data/tracks/perl5/docs/RESOURCES.md +57 -0
  49. data/tracks/perl5/exercises/hamming/Example.pm +7 -0
  50. data/tracks/perl5/exercises/hamming/hamming.t +17 -4
  51. data/tracks/perl5/exercises/rna-transcription/rna.t +4 -4
  52. data/tracks/perl6/.gitignore +2 -0
  53. data/tracks/perl6/config.json +5 -0
  54. data/tracks/perl6/exercises/phone-number/Example.pm +30 -0
  55. data/tracks/perl6/exercises/phone-number/cases.json +47 -0
  56. data/tracks/perl6/exercises/phone-number/phone.t +48 -0
  57. data/tracks/purescript/.gitignore +8 -0
  58. data/tracks/purescript/config.json +8 -3
  59. data/tracks/purescript/exercises/hello-world/bower.json +17 -0
  60. data/tracks/purescript/exercises/hello-world/examples/src/HelloWorld.purs +8 -0
  61. data/tracks/purescript/exercises/hello-world/src/HelloWorld.purs +6 -0
  62. data/tracks/purescript/exercises/hello-world/test/Main.purs +18 -0
  63. data/tracks/scala/exercises/leap/HINTS.md +4 -0
  64. data/tracks/scala/exercises/robot-name/HINTS.md +5 -0
  65. data/tracks/swift/docs/INSTALLATION.md +4 -1
  66. data/tracks/swift/exercises/accumulate/AccumulateTest.swift +1 -1
  67. data/tracks/swift/exercises/binary/BinaryExample.swift +4 -1
  68. data/tracks/swift/exercises/crypto-square/CryptoSquareExample.swift +3 -2
  69. data/tracks/swift/exercises/leap/LeapExample.swift +1 -3
  70. data/tracks/swift/exercises/pascals-triangle/PascalsTriangleTest.swift +1 -1
  71. data/tracks/swift/exercises/poker/PokerExample.swift +3 -3
  72. data/tracks/swift/exercises/poker/PokerTest.swift +38 -38
  73. data/tracks/swift/exercises/saddle-points/SaddlePointsTest.swift +1 -1
  74. data/tracks/swift/exercises/scrabble-score/ScrabbleScoreExample.swift +6 -3
  75. data/tracks/swift/exercises/series/SeriesTest.swift +1 -1
  76. data/tracks/swift/exercises/simple-linked-list/SimpleLinkedListExample.swift +2 -2
  77. data/tracks/swift/exercises/space-age/SpaceAgeExample.swift +10 -12
  78. data/tracks/swift/exercises/strain/StrainTest.swift +1 -1
  79. data/tracks/swift/exercises/tournament/TournamentExample.swift +2 -2
  80. data/tracks/swift/exercises/triangle/TriangleExample.swift +7 -3
  81. data/tracks/swift/exercises/wordy/WordyExample.swift +1 -2
  82. metadata +34 -3
  83. data/tracks/purescript/exercises/.keep +0 -0
@@ -131,6 +131,18 @@
131
131
  "topics": [
132
132
  ]
133
133
  },
134
+ {
135
+ "slug": "run-length-encoding",
136
+ "difficulty": 1,
137
+ "topics": [
138
+ ]
139
+ },
140
+ {
141
+ "slug": "pascals-triangle",
142
+ "difficulty": 1,
143
+ "topics": [
144
+ ]
145
+ },
134
146
  {
135
147
  "slug": "forth",
136
148
  "difficulty": 3,
@@ -0,0 +1,30 @@
1
+ require "spec"
2
+ require "../src/*"
3
+
4
+ describe "PascalsTriangle" do
5
+ it "will return the first 0 row(s)" do
6
+ PascalsTriangle.rows(0).should eq([] of Int32)
7
+ end
8
+
9
+ pending "will return the first 1 row(s)" do
10
+ PascalsTriangle.rows(1).should eq([[1]])
11
+ end
12
+
13
+ pending "will return the first 2 row(s)" do
14
+ PascalsTriangle.rows(2).should eq([[1], [1, 1]])
15
+ end
16
+
17
+ pending "will return the first 3 row(s)" do
18
+ PascalsTriangle.rows(3).should eq([[1], [1, 1], [1, 2, 1]])
19
+ end
20
+
21
+ pending "will return the first 4 row(s)" do
22
+ PascalsTriangle.rows(4).should eq([[1], [1, 1], [1, 2, 1], [1, 3, 3, 1]])
23
+ end
24
+
25
+ pending "will raise an Argument error for negative rows" do
26
+ expect_raises do
27
+ PascalsTriangle.rows(-1)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,19 @@
1
+ class PascalsTriangle
2
+ include Iterator(Array(Int32))
3
+
4
+ def self.rows(n)
5
+ raise ArgumentError.new("Number must not be less than zero") if n < 0
6
+ new.first(n).to_a
7
+ end
8
+
9
+ def initialize
10
+ @m = -1
11
+ end
12
+
13
+ def next
14
+ @m += 1
15
+ @m.times.reduce([1]) do |row, k|
16
+ row << (row[k] * (@m - k) / (k + 1))
17
+ end
18
+ end
19
+ end
@@ -0,0 +1 @@
1
+ # Please implement your solution to pascals-triangle in this file
@@ -0,0 +1,36 @@
1
+ require "spec"
2
+ require "../src/*"
3
+
4
+ describe "RunLengthEncoding" do
5
+ it "encode empty string" do
6
+ RunLengthEncoding.encode("").should eq("")
7
+ end
8
+
9
+ pending "encode single characters only" do
10
+ RunLengthEncoding.encode("XYZ").should eq("XYZ")
11
+ end
12
+
13
+ pending "decode empty string" do
14
+ RunLengthEncoding.decode("").should eq("")
15
+ end
16
+
17
+ pending "decode single characters only" do
18
+ RunLengthEncoding.decode("XYZ").should eq("XYZ")
19
+ end
20
+
21
+ pending "encode simple" do
22
+ RunLengthEncoding.encode("AABBBCCCC").should eq("2A3B4C")
23
+ end
24
+
25
+ pending "decode simple" do
26
+ RunLengthEncoding.decode("2A3B4C").should eq("AABBBCCCC")
27
+ end
28
+
29
+ pending "encode with single values" do
30
+ RunLengthEncoding.encode("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB").should eq("12WB12W3B24WB")
31
+ end
32
+
33
+ pending "decode with single values" do
34
+ RunLengthEncoding.decode("12WB12W3B24WB").should eq("WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWWWB")
35
+ end
36
+ end
@@ -0,0 +1,40 @@
1
+ module RunLengthEncoding
2
+ extend self
3
+
4
+ def encode(str)
5
+ reader = Char::Reader.new(str)
6
+ String.build do |io|
7
+ while reader.has_next?
8
+ count = 1
9
+
10
+ while reader.current_char == reader.peek_next_char
11
+ count += 1
12
+ reader.next_char
13
+ end
14
+
15
+ io << count if count > 1
16
+ io << reader.current_char
17
+ reader.next_char
18
+ end
19
+ end
20
+ end
21
+
22
+ def decode(str)
23
+ reader = Char::Reader.new(str)
24
+ String.build do |io|
25
+ while reader.has_next?
26
+ num = 0
27
+
28
+ while reader.current_char.number?
29
+ num *= 10
30
+ num += reader.current_char.to_i
31
+ reader.next_char
32
+ end
33
+
34
+ io << reader.current_char if num == 0
35
+ num.times { |i| io << reader.current_char }
36
+ reader.next_char
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,58 @@
1
+ require "./exercise_generator"
2
+ require "./exercise_test_case"
3
+
4
+ class PascalsTriangleGenerator < ExerciseGenerator
5
+ def exercise_name
6
+ "pascals-triangle"
7
+ end
8
+
9
+ def test_cases
10
+ JSON.parse(data)["rows"]["cases"].map do |test_case|
11
+ PascalsTriangleTestCase.new(test_case) unless test_case["count"]?.nil?
12
+ end.compact
13
+ end
14
+ end
15
+
16
+ class PascalsTriangleTestCase < ExerciseTestCase
17
+ private getter description : JSON::Any
18
+ private getter count : JSON::Any
19
+ private getter expected : JSON::Any
20
+
21
+ def initialize(test_case)
22
+ @description = test_case["description"]
23
+ @count = test_case["count"]
24
+ @expected = fix_empty_array(test_case["expected"])
25
+ end
26
+
27
+ def workload
28
+ if !error?
29
+ "PascalsTriangle.rows(#{count}).should eq(#{expected})"
30
+ else
31
+ <<-WL
32
+ expect_raises do
33
+ PascalsTriangle.rows(#{count})
34
+ end
35
+ WL
36
+ end
37
+ end
38
+
39
+ def test_name
40
+ if !error?
41
+ "will return the first #{count} row(s)"
42
+ else
43
+ "will raise an Argument error for #{description}"
44
+ end
45
+ end
46
+
47
+ private def error?
48
+ expected == -1
49
+ end
50
+
51
+ private def fix_empty_array(json)
52
+ if json.to_s.match(/\[\]/)
53
+ JSON.parse("[] of Int32".to_json)
54
+ else
55
+ json
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,42 @@
1
+ require "./exercise_generator"
2
+ require "./exercise_test_case"
3
+
4
+ class RunLengthEncodingGenerator < ExerciseGenerator
5
+ def exercise_name
6
+ "run-length-encoding"
7
+ end
8
+
9
+ def test_cases
10
+ JSON.parse(data)["cases"].map do |test_case|
11
+ RunLengthEncodingTestCase.new(test_case)
12
+ end
13
+ end
14
+ end
15
+
16
+ class RunLengthEncodingTestCase < ExerciseTestCase
17
+ private getter description : JSON::Any
18
+ private getter input : JSON::Any
19
+ private getter expected : JSON::Any
20
+
21
+ def initialize(test_case)
22
+ @description = test_case["description"]
23
+ @input = test_case["input"]
24
+ @expected = test_case["expected"]
25
+ end
26
+
27
+ def workload
28
+ "RunLengthEncoding.#{method}(\"#{input}\").should eq(\"#{expected}\")"
29
+ end
30
+
31
+ def test_name
32
+ description
33
+ end
34
+
35
+ private def method
36
+ if description.as_s.match(/encode/)
37
+ "encode"
38
+ else
39
+ "decode"
40
+ end
41
+ end
42
+ end
@@ -70,7 +70,8 @@
70
70
  "bracket-push",
71
71
  "two-bucket",
72
72
  "bowling",
73
- "diamond"
73
+ "diamond",
74
+ "all-your-base"
74
75
  ],
75
76
  "exercises": [
76
77
  {
@@ -468,6 +469,12 @@
468
469
  "difficulty": 1,
469
470
  "topics": [
470
471
  ]
472
+ },
473
+ {
474
+ "slug": "all-your-base",
475
+ "difficulty": 1,
476
+ "topics": [
477
+ ]
471
478
  }
472
479
  ],
473
480
  "deprecated": [
@@ -0,0 +1,141 @@
1
+ 'use strict';
2
+
3
+ const Converter = require('./all-your-base');
4
+
5
+ const converter = new Converter();
6
+
7
+ describe('Converter', function () {
8
+
9
+ xit('single bit one to decimal', function () {
10
+ expect(converter.convert([1], 2, 10)).toEqual([1]);
11
+ });
12
+
13
+ xit('binary to single decimal', function () {
14
+ expect(converter.convert([1, 0, 1], 2, 10)).toEqual([5]);
15
+ });
16
+
17
+ xit('single decimal to binary', function () {
18
+ expect(converter.convert([5], 10, 2)).toEqual([1, 0, 1]);
19
+ });
20
+
21
+ xit('binary to multiple decimal', function () {
22
+ expect(converter.convert([1, 0, 1, 0, 1, 0], 2, 10)).toEqual([4, 2]);
23
+ });
24
+
25
+ xit('decimal to binary', function () {
26
+ expect(converter.convert([4, 2], 10, 2)).toEqual([1, 0, 1, 0, 1, 0]);
27
+ });
28
+
29
+ xit('trinary to hexadecimal', function () {
30
+ expect(converter.convert([1, 1, 2, 0], 3, 16)).toEqual([2, 10]);
31
+ });
32
+
33
+ xit('hexadecimal to trinary', function () {
34
+ expect(converter.convert([2, 10], 16, 3)).toEqual([1, 1, 2, 0]);
35
+ });
36
+
37
+ xit('15-bit integer', function () {
38
+ expect(converter.convert([3, 46, 60], 97, 73)).toEqual([6, 10, 45]);
39
+ });
40
+
41
+ xit('empty list', function () {
42
+ expect(function () {
43
+ converter.convert([], 2, 10);
44
+ }).toThrow(new Error('Input has wrong format'));
45
+ });
46
+
47
+ xit('single zero', function () {
48
+ expect(converter.convert([0], 10, 2)).toEqual([0]);
49
+ });
50
+
51
+ xit('multiple zeros', function () {
52
+ expect(function () {
53
+ converter.convert([0, 0, 0], 10, 2);
54
+ }).toThrow(new Error('Input has wrong format'));
55
+ });
56
+
57
+ xit('leading zeros', function () {
58
+ expect(function () {
59
+ converter.convert([0, 6, 0], 7, 10);
60
+ }).toThrow(new Error('Input has wrong format'));
61
+ });
62
+
63
+ xit('negative digit', function () {
64
+ expect(function () {
65
+ converter.convert([1, -1, 1, 0, 1, 0], 2, 10);
66
+ }).toThrow(new Error('Input has wrong format'));
67
+ });
68
+
69
+ xit('invalid positive digit', function () {
70
+ expect(function () {
71
+ converter.convert([1, 2, 1, 0, 1, 0], 2, 10);
72
+ }).toThrow(new Error('Input has wrong format'));
73
+ });
74
+
75
+ xit('first base is one', function () {
76
+ expect(function () {
77
+ converter.convert([], 1, 10);
78
+ }).toThrow(new Error('Wrong input base'));
79
+ });
80
+
81
+ xit('second base is one', function () {
82
+ expect(function () {
83
+ converter.convert([1, 0, 1, 0, 1, 0], 2, 1);
84
+ }).toThrow(new Error('Wrong output base'));
85
+ });
86
+
87
+ xit('first base is zero', function () {
88
+ expect(function () {
89
+ converter.convert([], 0, 10);
90
+ }).toThrow(new Error('Wrong input base'));
91
+ });
92
+
93
+ xit('second base is zero', function () {
94
+ expect(function () {
95
+ converter.convert([7], 10, 0);
96
+ }).toThrow(new Error('Wrong output base'));
97
+ });
98
+
99
+ xit('first base is negative', function () {
100
+ expect(function () {
101
+ converter.convert([1], -2, 10);
102
+ }).toThrow(new Error('Wrong input base'));
103
+ });
104
+
105
+ xit('second base is negative', function () {
106
+ expect(function () {
107
+ converter.convert([1], 2, -7);
108
+ }).toThrow(new Error('Wrong output base'));
109
+ });
110
+
111
+ xit('both bases are negative', function () {
112
+ expect(function () {
113
+ converter.convert([1], -2, -7);
114
+ }).toThrow(new Error('Wrong input base'));
115
+ });
116
+
117
+ it('missing input base throws an error', function () {
118
+ expect(function () {
119
+ converter.convert([0]);
120
+ }).toThrow(new Error('Wrong input base'));
121
+ });
122
+
123
+ xit('wrong input_base base not integer', function () {
124
+ expect(function () {
125
+ converter.convert([0], 2.5);
126
+ }).toThrow(new Error('Wrong input base'));
127
+ });
128
+
129
+ xit('missing output base throws an error', function () {
130
+ expect(function () {
131
+ converter.convert([0], 2);
132
+ }).toThrow(new Error('Wrong output base'));
133
+ });
134
+
135
+ xit('wrong output_base base not integer', function () {
136
+ expect(function () {
137
+ converter.convert([0], 3, 2.5);
138
+ }).toThrow(new Error('Wrong output base'));
139
+ });
140
+
141
+ });
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ const Converter = function () { };
4
+
5
+ const isValidBase = function (base) {
6
+ return !base || base < 2 || Math.floor(base) !== base;
7
+ };
8
+
9
+ const isInputValid = function (array, base) {
10
+ if (!array || !array.length) {
11
+ return false;
12
+ }
13
+ const val = base - 1;
14
+ for (let i = 0, n = array.length; i < n; i++) {
15
+ const tmp = array[i];
16
+ if (tmp > val || tmp < 0) {
17
+ return false;
18
+ }
19
+ }
20
+ return true;
21
+ };
22
+
23
+ const convertFromDecimalToBase = function (num, outputBase) {
24
+ let tmp = num;
25
+ const result = [];
26
+ while (tmp) {
27
+ result.unshift(tmp % outputBase);
28
+ tmp = Math.floor(tmp / outputBase);
29
+ }
30
+ return result;
31
+ };
32
+
33
+ Converter.prototype.convert = function (array, inputBase, outputBase) {
34
+ if (isValidBase(inputBase)) {
35
+ throw new Error('Wrong input base');
36
+ }
37
+ if (isValidBase(outputBase)) {
38
+ throw new Error('Wrong output base');
39
+ }
40
+ const regexp = new RegExp('^0.', 'g');
41
+ const str = array.join('');
42
+ if (str.match(regexp)
43
+ || !isInputValid(array, inputBase)) {
44
+ throw new Error('Input has wrong format');
45
+ }
46
+ if (str === '0') {
47
+ return [0];
48
+ }
49
+ if (str === '1') {
50
+ return [1];
51
+ }
52
+ const decimalValue = array
53
+ .reduce((accumulator, value) => {
54
+ return accumulator * inputBase + value;
55
+ }, 0);
56
+ return convertFromDecimalToBase(decimalValue, outputBase);
57
+ };
58
+
59
+ module.exports = Converter;