trackler 2.0.3.4 → 2.0.3.5

Sign up to get free protection for your applications and to get access to all the features.
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;