trackler 2.2.1.117 → 2.2.1.118

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