trackler 2.2.1.164 → 2.2.1.165

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/c/exercises/binary-search-tree/README.md +39 -0
  4. data/tracks/c/exercises/bracket-push/README.md +39 -0
  5. data/tracks/c/exercises/crypto-square/README.md +39 -0
  6. data/tracks/c/exercises/diamond/README.md +39 -0
  7. data/tracks/c/exercises/etl/README.md +39 -0
  8. data/tracks/c/exercises/luhn/README.md +39 -0
  9. data/tracks/c/exercises/minesweeper/README.md +35 -0
  10. data/tracks/c/exercises/pig-latin/README.md +43 -4
  11. data/tracks/c/exercises/prime-factors/README.md +39 -0
  12. data/tracks/c/exercises/rna-transcription/README.md +1 -1
  13. data/tracks/c/exercises/run-length-encoding/README.md +39 -0
  14. data/tracks/c/exercises/say/README.md +39 -0
  15. data/tracks/c/exercises/secret-handshake/README.md +39 -0
  16. data/tracks/c/exercises/two-fer/README.md +39 -0
  17. data/tracks/c/exercises/wordy/README.md +39 -0
  18. data/tracks/cpp/config.json +36 -36
  19. data/tracks/cpp/docs/ABOUT.md +1 -1
  20. data/tracks/java/exercises/luhn/.meta/version +1 -0
  21. data/tracks/java/exercises/luhn/src/test/java/LuhnValidatorTest.java +35 -24
  22. data/tracks/javascript/config.json +1 -1
  23. data/tracks/javascript/exercises/nth-prime/example.js +5 -1
  24. data/tracks/javascript/exercises/nth-prime/nth-prime.spec.js +8 -0
  25. data/tracks/kotlin/config.json +60 -60
  26. data/tracks/kotlin/exercises/binary-search/.meta/version +1 -1
  27. data/tracks/kotlin/exercises/flatten-array/.meta/version +1 -1
  28. data/tracks/kotlin/exercises/isogram/.meta/version +1 -1
  29. data/tracks/kotlin/exercises/minesweeper/.meta/version +1 -1
  30. data/tracks/kotlin/exercises/nucleotide-count/.meta/version +1 -1
  31. data/tracks/kotlin/exercises/pig-latin/.meta/version +1 -1
  32. data/tracks/kotlin/exercises/prime-factors/.meta/version +1 -1
  33. data/tracks/kotlin/exercises/spiral-matrix/.meta/version +1 -1
  34. data/tracks/kotlin/exercises/word-count/.meta/version +1 -1
  35. data/tracks/powershell/exercises/hamming/HammingDifference.example.ps1 +12 -2
  36. data/tracks/powershell/exercises/hamming/HammingDifference.ps1 +1 -12
  37. data/tracks/python/exercises/simple-cipher/example.py +11 -15
  38. data/tracks/python/exercises/simple-cipher/simple_cipher.py +0 -5
  39. data/tracks/python/exercises/simple-cipher/simple_cipher_test.py +69 -70
  40. data/tracks/reasonml/bin/new-exercise.sh +11 -0
  41. data/tracks/reasonml/config.json +11 -0
  42. data/tracks/reasonml/exercises/anagram/__tests__/Anagram_test.re +44 -0
  43. data/tracks/reasonml/exercises/anagram/bsconfig.json +30 -0
  44. data/tracks/reasonml/exercises/anagram/package.json +20 -0
  45. data/tracks/reasonml/exercises/anagram/src/Example.re +26 -0
  46. data/tracks/reasonml/template/bsconfig.json +30 -0
  47. data/tracks/reasonml/template/package.json +20 -0
  48. data/tracks/reasonml/template/src/Example.re +0 -0
  49. metadata +11 -2
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.1.0
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.2.0
@@ -1 +1 @@
1
- 1.2.0
1
+ 1.3.0
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.1.0
@@ -1 +1 @@
1
- 1.2.0
1
+ 1.3.0
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.2.0
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.1.0
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.1.0
@@ -1 +1 @@
1
- 1.0.0
1
+ 1.2.0
@@ -1,4 +1,14 @@
1
1
  function Get-HammingDifference([string]$strand1, [string]$strand2) {
2
-
3
- Throw "Exercise not implemented"
2
+ if ( $strand1.length -ne $strand2.length) {
3
+ Throw "Mismatching string lengths"
4
+ }
5
+ $first = [char[]][string]$strand1
6
+ $second = [char[]][string]$strand2
7
+ $result = 0
8
+ for ($i=0; $i -lt $first.length; $i++) {
9
+ if ( $first[$i] -ne $second[$i] ) {
10
+ $result += 1
11
+ }
12
+ }
13
+ return $result
4
14
  }
@@ -1,14 +1,3 @@
1
1
  function Get-HammingDifference([string]$strand1, [string]$strand2) {
2
- if ( $strand1.length -ne $strand2.length) {
3
- Throw "Mismatching string lengths"
4
- }
5
- $first = [char[]][string]$strand1
6
- $second = [char[]][string]$strand2
7
- $result = 0
8
- for ($i=0; $i -lt $first.length; $i++) {
9
- if ( $first[$i] -ne $second[$i] ) {
10
- $result += 1
11
- }
12
- }
13
- return $result
2
+ Throw "Exercise not implemented"
14
3
  }
@@ -1,31 +1,27 @@
1
1
  from string import ascii_lowercase
2
2
  from time import time
3
3
  import random
4
+ from itertools import cycle
4
5
 
5
6
 
6
7
  class Cipher(object):
7
8
 
8
9
  def __init__(self, key=None):
9
- if not key:
10
+ if key is None:
10
11
  random.seed(time())
11
12
  key = ''.join(random.choice(ascii_lowercase) for i in range(100))
12
- elif not key.isalpha() or not key.islower():
13
+ elif not key or not key.isalpha() or not key.islower():
13
14
  raise ValueError('Wrong key parameter!')
14
15
  self.key = key
15
16
 
16
17
  def encode(self, text):
17
- text = ''.join(c for c in text if c.isalpha()).lower()
18
- key = self.key * (len(text) // len(self.key) + 1)
19
- return ''.join(chr((ord(c) - 194 + ord(k)) % 26 + 97)
20
- for c, k in zip(text, key))
18
+ return ''.join(
19
+ chr(((ord(c) - 2 * ord('a') + ord(k)) % 26) + ord('a'))
20
+ for c, k in zip(text, cycle(self.key))
21
+ )
21
22
 
22
23
  def decode(self, text):
23
- key = self.key * (len(text) // len(self.key) + 1)
24
- return ''.join(chr((ord(c) - ord(k) + 26) % 26 + 97)
25
- for c, k in zip(text, key))
26
-
27
-
28
- class Caesar(Cipher):
29
-
30
- def __init__(self):
31
- Cipher.__init__(self, 'd')
24
+ return ''.join(
25
+ chr(((ord(c) - ord(k) + 26) % 26) + ord('a'))
26
+ for c, k in zip(text, cycle(self.key))
27
+ )
@@ -7,8 +7,3 @@ class Cipher(object):
7
7
 
8
8
  def decode(self, text):
9
9
  pass
10
-
11
-
12
- class Caesar(object):
13
- def __init__(self):
14
- pass
@@ -1,78 +1,12 @@
1
1
  import unittest
2
+ import re
2
3
 
3
- from simple_cipher import Caesar, Cipher
4
+ from simple_cipher import Cipher
4
5
 
5
6
 
6
- class SimpleCipherTest(unittest.TestCase):
7
- def test_caesar_encode1(self):
8
- self.assertEqual(Caesar().encode('itisawesomeprogramminginpython'),
9
- 'lwlvdzhvrphsurjudpplqjlqsbwkrq')
10
-
11
- def test_caesar_encode2(self):
12
- self.assertEqual(Caesar().encode('venividivici'), 'yhqlylglylfl')
13
-
14
- def test_caesar_encode3(self):
15
- self.assertEqual(Caesar().encode('\'Twas the night before Christmas'),
16
- 'wzdvwkhqljkwehiruhfkulvwpdv')
17
-
18
- def test_caesar_encode_with_numbers(self):
19
- self.assertEqual(Caesar().encode('1, 2, 3, Go!'), 'jr')
20
-
21
- def test_caesar_decode(self):
22
- self.assertEqual(Caesar().decode('yhqlylglylfl'), 'venividivici')
23
-
24
- def test_cipher_encode1(self):
25
- c = Cipher('a')
26
- self.assertEqual(
27
- c.encode('itisawesomeprogramminginpython'),
28
- 'itisawesomeprogramminginpython')
29
-
30
- def test_cipher_encode2(self):
31
- c = Cipher('aaaaaaaaaaaaaaaaaaaaaa')
32
- self.assertEqual(
33
- c.encode('itisawesomeprogramminginpython'),
34
- 'itisawesomeprogramminginpython')
35
-
36
- def test_cipher_encode3(self):
37
- c = Cipher('dddddddddddddddddddddd')
38
- self.assertEqual(c.encode('venividivici'), 'yhqlylglylfl')
39
-
40
- def test_cipher_encode4(self):
41
- key = ('duxrceqyaimciuucnelkeoxjhdyduucpmrxmaivacmybmsdrzwqxvbxsy'
42
- 'gzsabdjmdjabeorttiwinfrpmpogvabiofqexnohrqu')
43
- c = Cipher(key)
44
- self.assertEqual(c.encode('diffiehellman'), 'gccwkixcltycv')
45
-
46
- def test_cipher_encode_short_key(self):
47
- c = Cipher('abcd')
48
- self.assertEqual(c.encode('aaaaaaaa'), 'abcdabcd')
49
-
50
- def test_cipher_compositiion1(self):
51
- key = ('duxrceqyaimciuucnelkeoxjhdyduucpmrxmaivacmybmsdrzwqxvbxsy'
52
- 'gzsabdjmdjabeorttiwinfrpmpogvabiofqexnohrqu')
53
- plaintext = 'adaywithoutlaughterisadaywasted'
54
- c = Cipher(key)
55
- self.assertEqual(c.decode(c.encode(plaintext)), plaintext)
56
-
57
- def test_cipher_compositiion2(self):
58
- plaintext = 'adaywithoutlaughterisadaywasted'
59
- c = Cipher()
60
- self.assertEqual(c.decode(c.encode(plaintext)), plaintext)
61
-
62
- def test_cipher_random_key(self):
63
- c = Cipher()
64
- self.assertTrue(
65
- len(c.key) >= 100,
66
- 'A random key must be generated when no key is given!')
67
- self.assertTrue(c.key.islower() and c.key.isalpha(),
68
- 'All items in the key must be chars and lowercase!')
69
-
70
- def test_cipher_wrong_key(self):
71
- with self.assertRaisesWithMessage(ValueError):
72
- Cipher('a1cde')
73
- with self.assertRaisesWithMessage(ValueError):
74
- Cipher('aBcde')
7
+ # Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.0
75
8
 
9
+ class SimpleCipherTest(unittest.TestCase):
76
10
  # Utility functions
77
11
  def setUp(self):
78
12
  try:
@@ -84,5 +18,70 @@ class SimpleCipherTest(unittest.TestCase):
84
18
  return self.assertRaisesRegex(exception, r".+")
85
19
 
86
20
 
21
+ class RandomKeyCipherTest(SimpleCipherTest):
22
+ def test_can_encode(self):
23
+ cipher = Cipher()
24
+ self.assertEqual(cipher.encode('aaaaaaaaaa'), cipher.key[:10])
25
+
26
+ def test_can_decode(self):
27
+ cipher = Cipher()
28
+ plaintext = 'aaaaaaaaaa'
29
+ self.assertEqual(cipher.decode(cipher.key[:len(plaintext)]), plaintext)
30
+
31
+ def test_is_reversible(self):
32
+ cipher = Cipher()
33
+ plaintext = 'abcdefghij'
34
+ self.assertEqual(cipher.decode(cipher.encode(plaintext)), plaintext)
35
+
36
+ def test_key_is_only_made_of_lowercase_letters(self):
37
+ self.assertIsNotNone(re.match('^[a-z]+$', Cipher().key))
38
+
39
+
40
+ class SubstitutionCipherTest(SimpleCipherTest):
41
+ def test_can_encode(self):
42
+ cipher = Cipher('abcdefghij')
43
+ self.assertEqual(cipher.encode('aaaaaaaaaa'), cipher.key)
44
+
45
+ def test_can_decode(self):
46
+ cipher = Cipher('abcdefghij')
47
+ self.assertEqual(cipher.decode(cipher.key), 'aaaaaaaaaa')
48
+
49
+ def test_is_reversible(self):
50
+ cipher = Cipher('abcdefghij')
51
+ plaintext = 'abcdefghij'
52
+ self.assertEqual(cipher.decode(cipher.encode(plaintext)), plaintext)
53
+
54
+ def test_can_double_shift_encode(self):
55
+ plaintext = 'iamapandabear'
56
+ cipher = Cipher(plaintext)
57
+ self.assertEqual(cipher.encode(plaintext), 'qayaeaagaciai')
58
+
59
+ def test_can_wrap_on_encode(self):
60
+ cipher = Cipher('abcdefghij')
61
+ self.assertEqual(cipher.encode('zzzzzzzzzz'), 'zabcdefghi')
62
+
63
+ def test_can_wrap_on_decode(self):
64
+ cipher = Cipher('abcdefghij')
65
+ self.assertEqual(cipher.decode('zabcdefghi'), 'zzzzzzzzzz')
66
+
67
+ def test_can_handle_messages_longer_than_key(self):
68
+ cipher = Cipher('abc')
69
+ self.assertEqual(cipher.encode('iamapandabear'), 'iboaqcnecbfcr')
70
+
71
+
72
+ class IncorrectKeyCipher(SimpleCipherTest):
73
+ def test_throws_an_error_with_all_uppercase_key(self):
74
+ with self.assertRaisesWithMessage(ValueError):
75
+ Cipher('ABCDEF')
76
+
77
+ def test_throws_an_error_with_a_numeric_key(self):
78
+ with self.assertRaisesWithMessage(ValueError):
79
+ Cipher('12345')
80
+
81
+ def test_throws_an_error_with_empty_key(self):
82
+ with self.assertRaisesWithMessage(ValueError):
83
+ Cipher('')
84
+
85
+
87
86
  if __name__ == '__main__':
88
87
  unittest.main()
@@ -0,0 +1,11 @@
1
+ #!/bin/bash
2
+
3
+ # From under reasonml: ./bin/new-exercise.sh <exercise-name>
4
+
5
+ # Creates a new exercise folder with the standard structure and empty test and example reason files.
6
+
7
+ cp -r ./template ./exercises
8
+ mv ./exercises/template ./exercises/$1
9
+ find ./exercises/$1/ -type f | xargs sed -i "s/"'$(name)'"/$1/g"
10
+ test_file=`echo $1_test.re | sed -e "s/\b\(.\)/\u\1/"`
11
+ touch ./exercises/$1/__tests__/$test_file
@@ -55,6 +55,17 @@
55
55
  "list map function",
56
56
  "variants"
57
57
  ]
58
+ },
59
+ {
60
+ "slug": "anagram",
61
+ "uuid": "1ddb534c-54e9-44a2-bd5f-fdcded7b03c8",
62
+ "core": false,
63
+ "unlocked_by": null,
64
+ "difficulty": 3,
65
+ "topics": [
66
+ "strings",
67
+ "filtering"
68
+ ]
58
69
  }
59
70
  ]
60
71
  }
@@ -0,0 +1,44 @@
1
+ open Jest;
2
+ open Expect;
3
+ open Anagram;
4
+
5
+ describe("Anagram", () => {
6
+ test("no matches", () =>
7
+ expect(anagrams("diaper", ["hello", "world", "zombies", "pants"])) |> toEqual([])
8
+ );
9
+ test("detects two anagrams", () =>
10
+ expect(anagrams("master", ["stream", "pigeon", "maters"])) |> toEqual(["stream", "maters"])
11
+ );
12
+ test("does not detect anagram subsets", () =>
13
+ expect(anagrams("good", ["dog", "goody"])) |> toEqual([])
14
+ );
15
+ test("detects anagram", () =>
16
+ expect(anagrams("listen", ["enlists", "google", "inlets", "banana"])) |> toEqual(["inlets"])
17
+ );
18
+ test("detects three anagrams", () =>
19
+ expect(anagrams("allergy", ["gallery", "ballerina", "regally", "clergy", "largely", "leading"])) |> toEqual(["gallery", "regally", "largely"])
20
+ );
21
+ test("does not detect non-anagrams(with identical checksum", () =>
22
+ expect(anagrams("mass", ["last"])) |> toEqual([])
23
+ );
24
+ test("detects anagrams(case-insensitively", () =>
25
+ expect(anagrams("Orchestra", ["cashregister", "Carthorse", "radishes"])) |> toEqual(["Carthorse"])
26
+ );
27
+ test("detects anagrams(using case-insensitive subject", () =>
28
+ expect(anagrams("Orchestra", ["cashregister", "carthorse", "radishes"])) |> toEqual(["carthorse"])
29
+ );
30
+ test("detects anagrams(using case-insensitive possible matches", () =>
31
+ expect(anagrams("orchestra", ["cashregister", "Carthorse", "radishes"])) |> toEqual(["Carthorse"])
32
+ );
33
+ test("does not detect a anagram if the original word is repeated", () =>
34
+ expect(anagrams("go", ["go Go GO"])) |> toEqual([])
35
+ );
36
+ test("anagrams(must use all letters exactly once", () =>
37
+ expect(anagrams("tapper", ["patter"])) |> toEqual([])
38
+ );
39
+ test("capital word is not own anagram", () =>
40
+ expect(anagrams("BANANA", ["Banana"])) |> toEqual([])
41
+ );
42
+ })
43
+
44
+
@@ -0,0 +1,30 @@
1
+ // This is the configuration file used by BuckleScript's build system bsb. Its documentation lives here: http://bucklescript.github.io/bucklescript/docson/#build-schema.json
2
+ // BuckleScript comes with its own parser for bsconfig.json, which is normal JSON, with the extra support of comments and trailing commas.
3
+ {
4
+ "name": "anagram",
5
+ "version": "0.1.0",
6
+ "sources": [
7
+ {
8
+ "dir" : "src",
9
+ "subdirs" : true
10
+ },
11
+ {
12
+ "dir": "__tests__",
13
+ "type": "dev"
14
+ }
15
+ ],
16
+ "package-specs": {
17
+ "module": "commonjs",
18
+ "in-source": true
19
+ },
20
+ "suffix": ".bs.js",
21
+ "bs-dependencies": [
22
+ // add your dependencies here. You'd usually install them normally through `npm install my-dependency`. If my-dependency has a bsconfig.json too, then everything will work seamlessly.
23
+ ],
24
+ "bs-dev-dependencies": ["@glennsl/bs-jest"],
25
+ "warnings": {
26
+ "error" : "+101"
27
+ },
28
+ "namespace": true,
29
+ "refmt": 3
30
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "anagram",
3
+ "version": "0.1.0",
4
+ "scripts": {
5
+ "build": "bsb -make-world",
6
+ "start": "bsb -make-world -w",
7
+ "clean": "bsb -clean-world",
8
+ "test": "jest --watchAll",
9
+ "test:ci": "jest --ci --bail --no-cache"
10
+ },
11
+ "keywords": [
12
+ "BuckleScript"
13
+ ],
14
+ "author": "",
15
+ "license": "MIT",
16
+ "devDependencies": {
17
+ "@glennsl/bs-jest": "^0.4.2",
18
+ "bs-platform": "^3.1.5"
19
+ }
20
+ }
@@ -0,0 +1,26 @@
1
+ let stringToCharArray = (s) => {
2
+ let len = String.length(s);
3
+ Array.init(len, n => s.[n]);
4
+ }
5
+
6
+ let isAnagram = (base, word) => {
7
+ if(String.length(base) != String.length(word)) {
8
+ false
9
+ } else {
10
+ let base = String.lowercase(base);
11
+ let word = String.lowercase(word);
12
+ if(base == word) {
13
+ false
14
+ } else {
15
+ let base = stringToCharArray(base);
16
+ Array.sort(Char.compare, base);
17
+ let word = stringToCharArray(word);
18
+ Array.sort(Char.compare, word);
19
+ base == word;
20
+ }
21
+ }
22
+ };
23
+
24
+ let anagrams = (base, candidates) => {
25
+ List.filter(isAnagram(base), candidates);
26
+ };
@@ -0,0 +1,30 @@
1
+ // This is the configuration file used by BuckleScript's build system bsb. Its documentation lives here: http://bucklescript.github.io/bucklescript/docson/#build-schema.json
2
+ // BuckleScript comes with its own parser for bsconfig.json, which is normal JSON, with the extra support of comments and trailing commas.
3
+ {
4
+ "name": "$(name)",
5
+ "version": "0.1.0",
6
+ "sources": [
7
+ {
8
+ "dir" : "src",
9
+ "subdirs" : true
10
+ },
11
+ {
12
+ "dir": "__tests__",
13
+ "type": "dev"
14
+ }
15
+ ],
16
+ "package-specs": {
17
+ "module": "commonjs",
18
+ "in-source": true
19
+ },
20
+ "suffix": ".bs.js",
21
+ "bs-dependencies": [
22
+ // add your dependencies here. You'd usually install them normally through `npm install my-dependency`. If my-dependency has a bsconfig.json too, then everything will work seamlessly.
23
+ ],
24
+ "bs-dev-dependencies": ["@glennsl/bs-jest"],
25
+ "warnings": {
26
+ "error" : "+101"
27
+ },
28
+ "namespace": true,
29
+ "refmt": 3
30
+ }