trackler 2.2.1.117 → 2.2.1.118

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/c/exercises/palindrome-products/src/example.c +73 -64
  4. data/tracks/c/exercises/palindrome-products/src/example.h +2 -4
  5. data/tracks/ceylon/exercises/largest-series-product/example/Series.ceylon +17 -5
  6. data/tracks/ceylon/exercises/largest-series-product/source/largestseriesproduct/Series.ceylon +12 -1
  7. data/tracks/ceylon/exercises/largest-series-product/source/largestseriesproduct/SeriesTest.ceylon +7 -12
  8. data/tracks/haskell/config.json +2 -2
  9. data/tracks/haskell/exercises/all-your-base/examples/success-standard/src/Base.hs +9 -6
  10. data/tracks/haskell/exercises/all-your-base/src/Base.hs +5 -2
  11. data/tracks/haskell/exercises/all-your-base/test/Tests.hs +28 -27
  12. data/tracks/haskell/exercises/largest-series-product/examples/success-standard/src/Series.hs +11 -5
  13. data/tracks/haskell/exercises/largest-series-product/src/Series.hs +4 -2
  14. data/tracks/haskell/exercises/largest-series-product/test/Tests.hs +16 -16
  15. data/tracks/java/config.json +1 -1
  16. data/tracks/java/exercises/bowling/.meta/version +1 -1
  17. data/tracks/java/exercises/bowling/src/test/java/BowlingTest.java +30 -5
  18. data/tracks/javascript/config.json +5 -5
  19. data/tracks/ocaml/README.md +3 -2
  20. data/tracks/typescript/config.json +28 -0
  21. data/tracks/typescript/exercises/sieve/README.md +60 -0
  22. data/tracks/typescript/exercises/sieve/package.json +36 -0
  23. data/tracks/typescript/exercises/sieve/sieve.example.ts +37 -0
  24. data/tracks/typescript/exercises/sieve/sieve.test.ts +41 -0
  25. data/tracks/typescript/exercises/sieve/sieve.ts +0 -0
  26. data/tracks/typescript/exercises/sieve/tsconfig.json +22 -0
  27. data/tracks/typescript/exercises/sieve/tslint.json +127 -0
  28. data/tracks/typescript/exercises/sieve/yarn.lock +2624 -0
  29. data/tracks/typescript/exercises/sublist/README.md +46 -0
  30. data/tracks/typescript/exercises/sublist/package.json +36 -0
  31. data/tracks/typescript/exercises/sublist/sublist.example.ts +30 -0
  32. data/tracks/typescript/exercises/sublist/sublist.test.ts +139 -0
  33. data/tracks/typescript/exercises/sublist/sublist.ts +0 -0
  34. data/tracks/typescript/exercises/sublist/tsconfig.json +22 -0
  35. data/tracks/typescript/exercises/sublist/tslint.json +127 -0
  36. data/tracks/typescript/exercises/sublist/yarn.lock +2624 -0
  37. metadata +18 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 86698b18430cbc49e1e2e16167ec6aa9df9cfc40
4
- data.tar.gz: c5b5f72aed663aa799b536bd3c79fcba1aeae8c7
3
+ metadata.gz: 66abff986feb8a1f8154e773673f580604efc53c
4
+ data.tar.gz: c89d411e969b41da2b3aecd01cdf82b0dd8bbaf8
5
5
  SHA512:
6
- metadata.gz: 537f35ce200183dfda9210b561a74917663cbac1cef101f2958493fe61f905358496e068c2014ad92b6e2dd8962b4e2c96a2dd95f174d65a83265ba25c82058a
7
- data.tar.gz: a025234caa3468b897a04e4002591bed0e7b7535fa52cd8920436eacf6ff443ffc3a19cb20a9b25102f63ec5d162ec86c4202fd1d3b17cacacf0d2fc92dde563
6
+ metadata.gz: cd29181a45f5d886605ed8ba63b8c5efae514a23e21b5dab03705d9c1413c3adc4c8a8d687340aee461cf19e04a3338ab0e854d58b32b0c696483dfba86a1716
7
+ data.tar.gz: 7d18ef16291d535e0acfa4c4c72ae1a2e627dd70b7a62f8e10f73409e4c99d0517b88ac64203dfbf4aa629aa5c99e76eb8b25950e1b095caeb9e68f93ae91054
@@ -1,3 +1,3 @@
1
1
  module Trackler
2
- VERSION = "2.2.1.117"
2
+ VERSION = "2.2.1.118"
3
3
  end
@@ -2,64 +2,34 @@
2
2
  #include <stdlib.h>
3
3
  #include <stdio.h>
4
4
  #include <limits.h>
5
+ #include <stdbool.h>
5
6
 
6
- static int palindrome(int n);
7
- static int addfactors(factor_t ** p, int i, int k);
8
- static void free_ll(struct factors *p);
9
-
10
- product_t *get_palindrome_product(int from, int to)
7
+ __attribute__ ((optimize("-O3")))
8
+ static bool palindrome(int n)
11
9
  {
12
- product_t *res = malloc(sizeof(product_t));
13
- if (res == NULL) {
14
- fprintf(stderr, "Memory error!\n");
15
- return NULL;
16
- }
10
+ /* 0 is palindrome */
11
+ if (n == 0)
12
+ return true;
17
13
 
18
- res->error[MAXERR - 1] = '\0';
19
- res->smallest = INT_MAX;
20
- res->largest = INT_MIN;
21
- res->factors_lg = NULL;
22
- res->factors_sm = NULL;
14
+ /* negative can not be palindrome */
15
+ if (n < 0)
16
+ return false;
23
17
 
24
- if (from > to) {
25
- snprintf(res->error, MAXERR - 1,
26
- "invalid input: min is %i and max is %i", from, to);
27
- return res;
28
- }
18
+ int tail;
29
19
 
30
- int i, k, n;
31
- int err = 0;
32
- for (i = from; i <= to; i++)
33
- for (k = i; k <= to; k++)
34
- if (palindrome(n = i * k)) {
35
- if (n <= res->smallest) {
36
- res->smallest = n;
37
- err = addfactors(&res->factors_sm, i, k);
38
- } else if (n >= res->largest) {
39
- res->largest = n;
40
- err = addfactors(&res->factors_lg, i, k);
41
- }
42
- if (err) {
43
- free(res);
44
- return NULL;
45
- }
46
- }
20
+ /* a not-null number can not start with 0 */
21
+ if ((tail = n % 10) == 0)
22
+ return false;
23
+ n /= 10;
47
24
 
48
- if ((res->smallest == INT_MAX) || (res->largest == INT_MIN)) {
49
- snprintf(res->error, MAXERR - 1,
50
- "no palindrome with factors in the range %i to %i", from, to);
51
- return res;
25
+ /* split and reverse the second half */
26
+ while (n > tail) {
27
+ tail = (tail * 10) + (n % 10);
28
+ n /= 10;
52
29
  }
53
- return res;
54
- }
55
30
 
56
- void free_product(product_t * p)
57
- {
58
- if (p == NULL)
59
- return;
60
- free_ll(p->factors_lg);
61
- free_ll(p->factors_sm);
62
- free(p);
31
+ return (n == tail) /* even length */
32
+ ||(n == tail / 10); /* odd length - discard the middle */
63
33
  }
64
34
 
65
35
  static void free_ll(struct factors *p)
@@ -71,9 +41,9 @@ static void free_ll(struct factors *p)
71
41
  free(p);
72
42
  }
73
43
 
74
- static int addfactors(factor_t ** p, int i, int k)
44
+ static int addfactors(factor_t ** p, int factor_one, int factor_two)
75
45
  {
76
- int n = i * k;
46
+ int n = factor_one * factor_two;
77
47
  if ((*p == NULL) || (((*p)->factor_a) * (*p)->factor_b != n)) {
78
48
  free_ll(*p);
79
49
  *p = NULL;
@@ -86,24 +56,63 @@ static int addfactors(factor_t ** p, int i, int k)
86
56
  }
87
57
 
88
58
  tmp->next = *p;
89
- tmp->factor_a = i;
90
- tmp->factor_b = k;
59
+ tmp->factor_a = factor_one;
60
+ tmp->factor_b = factor_two;
91
61
  *p = tmp;
92
62
  return 0;
93
63
  }
94
64
 
95
- static int palindrome(int n)
65
+ product_t *get_palindrome_product(int from, int to)
96
66
  {
97
- if (n < 0)
98
- n *= -1;
99
- int r = 0;
100
- int nn = n;
67
+ product_t *result = malloc(sizeof(product_t));
68
+ if (result == NULL) {
69
+ fprintf(stderr, "Memory error!\n");
70
+ return NULL;
71
+ }
101
72
 
102
- /* inverse n in r */
103
- while (n >= 1) {
104
- r = (r * 10) + (n % 10);
105
- n /= 10;
73
+ result->error[MAXERR - 1] = '\0';
74
+ result->smallest = INT_MAX;
75
+ result->largest = INT_MIN;
76
+ result->factors_lg = NULL;
77
+ result->factors_sm = NULL;
78
+
79
+ if (from > to) {
80
+ snprintf(result->error, MAXERR - 1,
81
+ "invalid input: min is %i and max is %i", from, to);
82
+ return result;
83
+ }
84
+
85
+ int i, k, n;
86
+ int err = 0;
87
+ for (i = from; i <= to; i++)
88
+ for (k = i; k <= to; k++)
89
+ if (palindrome(n = i * k)) {
90
+ if (n <= result->smallest) {
91
+ result->smallest = n;
92
+ err = addfactors(&result->factors_sm, i, k);
93
+ } else if (n >= result->largest) {
94
+ result->largest = n;
95
+ err = addfactors(&result->factors_lg, i, k);
96
+ }
97
+ if (err) {
98
+ free(result);
99
+ return NULL;
100
+ }
101
+ }
102
+
103
+ if ((result->smallest == INT_MAX) || (result->largest == INT_MIN)) {
104
+ snprintf(result->error, MAXERR - 1,
105
+ "no palindrome with factors in the range %i to %i", from, to);
106
+ return result;
106
107
  }
108
+ return result;
109
+ }
107
110
 
108
- return (nn == r);
111
+ void free_product(product_t * p)
112
+ {
113
+ if (p == NULL)
114
+ return;
115
+ free_ll(p->factors_lg);
116
+ free_ll(p->factors_sm);
117
+ free(p);
109
118
  }
@@ -3,13 +3,11 @@
3
3
 
4
4
  #define MAXERR 100
5
5
 
6
- struct factors {
6
+ typedef struct factors {
7
7
  int factor_a;
8
8
  int factor_b;
9
9
  struct factors *next;
10
- };
11
-
12
- typedef struct factors factor_t;
10
+ } factor_t;
13
11
 
14
12
  struct product {
15
13
  int smallest;
@@ -1,13 +1,25 @@
1
- class Error() {}
1
+ abstract class Error() of InvalidWindowSize | InvalidDigit {}
2
+ class InvalidWindowSize() extends Error() {
3
+ shared actual default Boolean equals(Object that) => that is InvalidWindowSize;
4
+ }
5
+ class InvalidDigit(Character c) extends Error() {
6
+ shared actual default Boolean equals(Object that) {
7
+ if (is InvalidDigit that) {
8
+ return that.c == c;
9
+ }
10
+ return false;
11
+ }
12
+ }
2
13
 
3
14
  Integer|Error largestProduct(String digits, Integer window) {
4
15
  if (window<0 || window>digits.size) {
5
- return Error();
16
+ return InvalidWindowSize();
6
17
  }
7
- value parsed = [for (d in digits) if (('0'..'9').contains(d)) d.integer - '0'.integer];
8
- if (parsed.size < digits.size) {
9
- return Error();
18
+ value invalids = [for (d in digits) if (!('0'..'9').contains(d)) d];
19
+ if (nonempty invalids) {
20
+ return InvalidDigit(invalids[0]);
10
21
  }
22
+ value parsed = [for (d in digits) d.integer - '0'.integer];
11
23
  value ranges = { for (i in 0 .. (digits.size - window)) parsed[i:window] };
12
24
  return max({ for (r in ranges) r.fold(1)((acc, e) => acc * e) });
13
25
  }
@@ -1,4 +1,15 @@
1
- class Error() {}
1
+ abstract class Error() of InvalidWindowSize | InvalidDigit {}
2
+ class InvalidWindowSize() extends Error() {
3
+ shared actual default Boolean equals(Object that) => that is InvalidWindowSize;
4
+ }
5
+ class InvalidDigit(Character c) extends Error() {
6
+ shared actual default Boolean equals(Object that) {
7
+ if (is InvalidDigit that) {
8
+ return that.c == c;
9
+ }
10
+ return false;
11
+ }
12
+ }
2
13
 
3
14
  Integer|Error largestProduct(String digits, Integer window) {
4
15
  return nothing;
@@ -4,7 +4,7 @@ import ceylon.test {
4
4
 
5
5
  // Tests adapted from problem-specifications version 1.1.0
6
6
 
7
- {[String, Integer, Integer?]*} cases => {
7
+ {[String, Integer, Integer|Error]*} cases => {
8
8
  // finds the largest product if span equals length
9
9
  ["29", 2, 18],
10
10
  // can find the largest product of 2 with numbers in order
@@ -24,26 +24,21 @@ import ceylon.test {
24
24
  // reports zero if all spans include zero
25
25
  ["99099", 3, 0],
26
26
  // rejects span longer than string length
27
- ["123", 4, null],
27
+ ["123", 4, InvalidWindowSize()],
28
28
  // reports 1 for empty string and empty product (0 span)
29
29
  ["", 0, 1],
30
30
  // reports 1 for nonempty string and empty product (0 span)
31
31
  ["123", 0, 1],
32
32
  // rejects empty string and nonzero span
33
- ["", 1, null],
33
+ ["", 1, InvalidWindowSize()],
34
34
  // rejects invalid character in digits
35
- ["1234a5", 2, null],
35
+ ["1234a5", 2, InvalidDigit('a')],
36
36
  // rejects negative span
37
- ["12345", -1, null]
37
+ ["12345", -1, InvalidWindowSize()]
38
38
  };
39
39
 
40
40
  test
41
41
  parameters (`value cases`)
42
- void testLargestProduct(String digits, Integer window, Integer? expected) {
43
- value result = largestProduct(digits, window);
44
- if (exists expected) {
45
- assertEquals(result, expected);
46
- } else if (!is Error result) {
47
- fail("should have errored, but got ``result``");
48
- }
42
+ void testLargestProduct(String digits, Integer window, Integer|Error expected) {
43
+ assertEquals(largestProduct(digits, window), expected);
49
44
  }
@@ -400,7 +400,7 @@
400
400
  "unlocked_by": null,
401
401
  "difficulty": 4,
402
402
  "topics": [
403
- "Maybe"
403
+ "Either"
404
404
  ]
405
405
  },
406
406
  {
@@ -410,7 +410,7 @@
410
410
  "unlocked_by": null,
411
411
  "difficulty": 4,
412
412
  "topics": [
413
- "Maybe"
413
+ "Either"
414
414
  ]
415
415
  },
416
416
  {
@@ -1,20 +1,23 @@
1
- module Base (rebase) where
1
+ module Base (Error(..), rebase) where
2
2
 
3
3
  import Control.Monad (foldM)
4
4
  import Data.List (unfoldr)
5
5
  import Data.Tuple (swap)
6
6
 
7
- rebase :: Integral a => a -> a -> [a] -> Maybe [a]
7
+ data Error a = InvalidInputBase | InvalidOutputBase | InvalidDigit a
8
+ deriving (Show, Eq)
9
+
10
+ rebase :: Integral a => a -> a -> [a] -> Either (Error a) [a]
8
11
  rebase ibase obase ds
9
- | ibase < 2 = Nothing
10
- | obase < 2 = Nothing
12
+ | ibase < 2 = Left InvalidInputBase
13
+ | obase < 2 = Left InvalidOutputBase
11
14
  | otherwise = toDigits obase <$> fromDigits ibase ds
12
15
  where
13
16
 
14
17
  fromDigits base = foldM f 0
15
18
  where
16
- f acc x | x >= 0 && x < base = Just (acc * base + x)
17
- | otherwise = Nothing
19
+ f acc x | x >= 0 && x < base = Right (acc * base + x)
20
+ | otherwise = Left (InvalidDigit x)
18
21
 
19
22
  toDigits base = reverse . unfoldr f
20
23
  where
@@ -1,4 +1,7 @@
1
- module Base (rebase) where
1
+ module Base (Error(..), rebase) where
2
2
 
3
- rebase :: Integral a => a -> a -> [a] -> Maybe [a]
3
+ data Error a = InvalidInputBase | InvalidOutputBase | InvalidDigit a
4
+ deriving (Show, Eq)
5
+
6
+ rebase :: Integral a => a -> a -> [a] -> Either (Error a) [a]
4
7
  rebase inputBase outputBase inputDigits = error "You need to implement this function."
@@ -4,7 +4,7 @@ import Data.Foldable (for_)
4
4
  import Test.Hspec (Spec, describe, it, shouldBe)
5
5
  import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)
6
6
 
7
- import Base (rebase)
7
+ import Base (Error(..), rebase)
8
8
 
9
9
  main :: IO ()
10
10
  main = hspecWith defaultConfig {configFastFail = True} specs
@@ -18,11 +18,11 @@ specs = describe "rebase" $ for_ cases test
18
18
  assertion = expression `shouldBe` outputDigits
19
19
  expression = rebase inputBase outputBase inputDigits
20
20
 
21
- data Case = Case { description :: String
22
- , inputBase :: Integer
23
- , inputDigits :: [Integer]
24
- , outputBase :: Integer
25
- , outputDigits :: Maybe [Integer]
21
+ data Case = Case { description :: String
22
+ , inputBase :: Integer
23
+ , inputDigits :: [Integer]
24
+ , outputBase :: Integer
25
+ , outputDigits :: Either (Error Integer) [Integer]
26
26
  }
27
27
 
28
28
  cases :: [Case]
@@ -30,49 +30,49 @@ cases = [ Case { description = "single bit one to decimal"
30
30
  , inputBase = 2
31
31
  , inputDigits = [1]
32
32
  , outputBase = 10
33
- , outputDigits = Just [1]
33
+ , outputDigits = Right [1]
34
34
  }
35
35
  , Case { description = "binary to single decimal"
36
36
  , inputBase = 2
37
37
  , inputDigits = [1, 0, 1]
38
38
  , outputBase = 10
39
- , outputDigits = Just [5]
39
+ , outputDigits = Right [5]
40
40
  }
41
41
  , Case { description = "single decimal to binary"
42
42
  , inputBase = 10
43
43
  , inputDigits = [5]
44
44
  , outputBase = 2
45
- , outputDigits = Just [1, 0, 1]
45
+ , outputDigits = Right [1, 0, 1]
46
46
  }
47
47
  , Case { description = "binary to multiple decimal"
48
48
  , inputBase = 2
49
49
  , inputDigits = [1, 0, 1, 0, 1, 0]
50
50
  , outputBase = 10
51
- , outputDigits = Just [4, 2]
51
+ , outputDigits = Right [4, 2]
52
52
  }
53
53
  , Case { description = "decimal to binary"
54
54
  , inputBase = 10
55
55
  , inputDigits = [4, 2]
56
56
  , outputBase = 2
57
- , outputDigits = Just [1, 0, 1, 0, 1, 0]
57
+ , outputDigits = Right [1, 0, 1, 0, 1, 0]
58
58
  }
59
59
  , Case { description = "trinary to hexadecimal"
60
60
  , inputBase = 3
61
61
  , inputDigits = [1, 1, 2, 0]
62
62
  , outputBase = 16
63
- , outputDigits = Just [2, 10]
63
+ , outputDigits = Right [2, 10]
64
64
  }
65
65
  , Case { description = "hexadecimal to trinary"
66
66
  , inputBase = 16
67
67
  , inputDigits = [2, 10]
68
68
  , outputBase = 3
69
- , outputDigits = Just [1, 1, 2, 0]
69
+ , outputDigits = Right [1, 1, 2, 0]
70
70
  }
71
71
  , Case { description = "15-bit integer"
72
72
  , inputBase = 97
73
73
  , inputDigits = [3, 46, 60]
74
74
  , outputBase = 73
75
- , outputDigits = Just [6, 10, 45]
75
+ , outputDigits = Right [6, 10, 45]
76
76
  }
77
77
 
78
78
  -- The following three cases are [0] in all-your-base.json.
@@ -81,79 +81,80 @@ cases = [ Case { description = "single bit one to decimal"
81
81
  , inputBase = 2
82
82
  , inputDigits = []
83
83
  , outputBase = 10
84
- , outputDigits = Just []
84
+ , outputDigits = Right []
85
85
  }
86
86
  , Case { description = "single zero"
87
87
  , inputBase = 10
88
88
  , inputDigits = [0]
89
89
  , outputBase = 2
90
- , outputDigits = Just []
90
+ , outputDigits = Right []
91
91
  }
92
92
  , Case { description = "multiple zeros"
93
93
  , inputBase = 10
94
94
  , inputDigits = [0, 0, 0]
95
95
  , outputBase = 2
96
- , outputDigits = Just []
96
+ , outputDigits = Right []
97
97
  }
98
98
 
99
99
  , Case { description = "leading zeros"
100
100
  , inputBase = 7
101
101
  , inputDigits = [0, 6, 0]
102
102
  , outputBase = 10
103
- , outputDigits = Just [4, 2]
103
+ , outputDigits = Right [4, 2]
104
104
  }
105
105
  , Case { description = "input base is one"
106
106
  , inputBase = 1
107
107
  , inputDigits = [0]
108
108
  , outputBase = 10
109
- , outputDigits = Nothing
109
+ , outputDigits = Left InvalidInputBase
110
110
  }
111
111
  , Case { description = "input base is zero"
112
112
  , inputBase = 0
113
113
  , inputDigits = []
114
114
  , outputBase = 10
115
- , outputDigits = Nothing
115
+ , outputDigits = Left InvalidInputBase
116
116
  }
117
117
  , Case { description = "input base is negative"
118
118
  , inputBase = -2
119
119
  , inputDigits = [1]
120
120
  , outputBase = 10
121
- , outputDigits = Nothing
121
+ , outputDigits = Left InvalidInputBase
122
122
  }
123
123
  , Case { description = "negative digit"
124
124
  , inputBase = 2
125
125
  , inputDigits = [1, -1, 1, 0, 1, 0]
126
126
  , outputBase = 10
127
- , outputDigits = Nothing
127
+ , outputDigits = Left (InvalidDigit (-1))
128
128
  }
129
129
  , Case { description = "invalid positive digit"
130
130
  , inputBase = 2
131
131
  , inputDigits = [1, 2, 1, 0, 1, 0]
132
132
  , outputBase = 10
133
- , outputDigits = Nothing
133
+ , outputDigits = Left (InvalidDigit 2)
134
134
  }
135
135
  , Case { description = "output base is one"
136
136
  , inputBase = 2
137
137
  , inputDigits = [1, 0, 1, 0, 1, 0]
138
138
  , outputBase = 1
139
- , outputDigits = Nothing
139
+ , outputDigits = Left InvalidOutputBase
140
140
  }
141
141
  , Case { description = "output base is zero"
142
142
  , inputBase = 10
143
143
  , inputDigits = [7]
144
144
  , outputBase = 0
145
- , outputDigits = Nothing
145
+ , outputDigits = Left InvalidOutputBase
146
146
  }
147
147
  , Case { description = "output base is negative"
148
148
  , inputBase = 2
149
149
  , inputDigits = [1]
150
150
  , outputBase = -7
151
- , outputDigits = Nothing
151
+ , outputDigits = Left InvalidOutputBase
152
152
  }
153
153
  , Case { description = "both bases are negative"
154
154
  , inputBase = -2
155
155
  , inputDigits = [1]
156
156
  , outputBase = -7
157
- , outputDigits = Nothing
157
+ -- debatable: This could be Left InvalidOutputBase as well.
158
+ , outputDigits = Left InvalidInputBase
158
159
  }
159
160
  ]