trackler 2.2.1.82 → 2.2.1.83

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/bash/.gitattributes +10 -0
  4. data/tracks/bash/CONTRIBUTING.md +3 -1
  5. data/tracks/{java/_template/src/example/java → bash/_template/.meta}/.keep +0 -0
  6. data/tracks/bash/_template/README.md +11 -0
  7. data/tracks/bash/_template/example.sh +3 -0
  8. data/tracks/bash/_template/exercise_slug_test.sh +17 -0
  9. data/tracks/bash/exercises/acronym/example.sh +1 -1
  10. data/tracks/bash/exercises/anagram/example.sh +1 -1
  11. data/tracks/bash/exercises/armstrong-numbers/example.sh +1 -1
  12. data/tracks/bash/exercises/atbash-cipher/example.sh +1 -1
  13. data/tracks/bash/exercises/bob/example.sh +1 -1
  14. data/tracks/bash/exercises/error-handling/example.sh +2 -0
  15. data/tracks/bash/exercises/gigasecond/example.sh +2 -0
  16. data/tracks/bash/exercises/hamming/example.sh +1 -1
  17. data/tracks/bash/exercises/hello-world/example.sh +1 -1
  18. data/tracks/bash/exercises/leap/example.sh +1 -1
  19. data/tracks/bash/exercises/nucleotide-count/example.sh +1 -1
  20. data/tracks/bash/exercises/pangram/example.sh +1 -1
  21. data/tracks/bash/exercises/raindrops/example.sh +1 -1
  22. data/tracks/bash/exercises/reverse-string/example.sh +1 -1
  23. data/tracks/bash/exercises/rna-transcription/example.sh +2 -0
  24. data/tracks/bash/exercises/roman-numerals/example.sh +1 -1
  25. data/tracks/bash/exercises/triangle/example.sh +3 -2
  26. data/tracks/bash/exercises/two-fer/example.sh +1 -1
  27. data/tracks/bash/exercises/word-count/example.sh +2 -2
  28. data/tracks/clojure/config.json +8 -0
  29. data/tracks/clojure/exercises/armstrong-numbers/README.md +19 -0
  30. data/tracks/clojure/exercises/armstrong-numbers/project.clj +4 -0
  31. data/tracks/clojure/exercises/armstrong-numbers/src/armstrong_numbers.clj +3 -0
  32. data/tracks/clojure/exercises/armstrong-numbers/src/example.clj +6 -0
  33. data/tracks/clojure/exercises/armstrong-numbers/test/armstrong_numbers_test.clj +35 -0
  34. data/tracks/common-lisp/exercises/sieve/example.lisp +10 -11
  35. data/tracks/common-lisp/exercises/sieve/sieve-test.lisp +30 -20
  36. data/tracks/go/exercises/all-your-base/all_your_base_test.go +5 -4
  37. data/tracks/go/exercises/pig-latin/.meta/gen.go +58 -0
  38. data/tracks/go/exercises/pig-latin/cases_test.go +122 -0
  39. data/tracks/go/exercises/pig-latin/example.go +20 -8
  40. data/tracks/go/exercises/pig-latin/pig_latin_test.go +9 -23
  41. data/tracks/java/_template/.meta/src/reference/java/.keep +0 -0
  42. data/tracks/java/exercises/acronym/.meta/src/reference/java/Acronym.java +8 -10
  43. data/tracks/java/exercises/anagram/.meta/src/reference/java/Anagram.java +4 -9
  44. data/tracks/java/exercises/atbash-cipher/.meta/src/reference/java/Atbash.java +2 -10
  45. data/tracks/java/exercises/hamming/.meta/version +1 -1
  46. data/tracks/java/exercises/hamming/src/test/java/HammingTest.java +3 -2
  47. data/tracks/java/exercises/isogram/.meta/version +1 -0
  48. data/tracks/java/exercises/isogram/src/test/java/IsogramCheckerTest.java +14 -21
  49. data/tracks/ruby/config.json +14 -2
  50. data/tracks/ruby/exercises/book-store/.meta/generator/book_store_case.rb +9 -0
  51. data/tracks/ruby/exercises/book-store/.meta/solutions/.version +1 -0
  52. data/tracks/ruby/exercises/book-store/.meta/solutions/book_store.rb +47 -0
  53. data/tracks/ruby/exercises/book-store/README.md +100 -0
  54. data/tracks/ruby/exercises/book-store/book_store_test.rb +97 -0
  55. data/tracks/ruby/exercises/change/README.md +49 -0
  56. metadata +22 -3
@@ -0,0 +1,122 @@
1
+ package piglatin
2
+
3
+ // Source: exercism/problem-specifications
4
+ // Commit: b5ddd0a pig-latin: tests for Y as a vowel (#904)
5
+ // Problem Specifications Version: 1.1.0
6
+
7
+ var testCases = []struct {
8
+ description string
9
+ input string
10
+ expected string
11
+ }{
12
+ {
13
+ description: "word beginning with a",
14
+ input: "apple",
15
+ expected: "appleay",
16
+ },
17
+ {
18
+ description: "word beginning with e",
19
+ input: "ear",
20
+ expected: "earay",
21
+ },
22
+ {
23
+ description: "word beginning with i",
24
+ input: "igloo",
25
+ expected: "iglooay",
26
+ },
27
+ {
28
+ description: "word beginning with o",
29
+ input: "object",
30
+ expected: "objectay",
31
+ },
32
+ {
33
+ description: "word beginning with u",
34
+ input: "under",
35
+ expected: "underay",
36
+ },
37
+ {
38
+ description: "word beginning with a vowel and followed by a qu",
39
+ input: "equal",
40
+ expected: "equalay",
41
+ },
42
+ {
43
+ description: "word beginning with p",
44
+ input: "pig",
45
+ expected: "igpay",
46
+ },
47
+ {
48
+ description: "word beginning with k",
49
+ input: "koala",
50
+ expected: "oalakay",
51
+ },
52
+ {
53
+ description: "word beginning with x",
54
+ input: "xenon",
55
+ expected: "enonxay",
56
+ },
57
+ {
58
+ description: "word beginning with q without a following u",
59
+ input: "qat",
60
+ expected: "atqay",
61
+ },
62
+ {
63
+ description: "word beginning with ch",
64
+ input: "chair",
65
+ expected: "airchay",
66
+ },
67
+ {
68
+ description: "word beginning with qu",
69
+ input: "queen",
70
+ expected: "eenquay",
71
+ },
72
+ {
73
+ description: "word beginning with qu and a preceding consonant",
74
+ input: "square",
75
+ expected: "aresquay",
76
+ },
77
+ {
78
+ description: "word beginning with th",
79
+ input: "therapy",
80
+ expected: "erapythay",
81
+ },
82
+ {
83
+ description: "word beginning with thr",
84
+ input: "thrush",
85
+ expected: "ushthray",
86
+ },
87
+ {
88
+ description: "word beginning with sch",
89
+ input: "school",
90
+ expected: "oolschay",
91
+ },
92
+ {
93
+ description: "word beginning with yt",
94
+ input: "yttria",
95
+ expected: "yttriaay",
96
+ },
97
+ {
98
+ description: "word beginning with xr",
99
+ input: "xray",
100
+ expected: "xrayay",
101
+ },
102
+ {
103
+ description: "y is treated like a consonant at the beginning of a word",
104
+ input: "yellow",
105
+ expected: "ellowyay",
106
+ },
107
+ {
108
+ description: "y is treated like a vowel at the end of a consonant cluster",
109
+ input: "rhythm",
110
+ expected: "ythmrhay",
111
+ },
112
+ {
113
+ description: "y as second letter in two letter word",
114
+ input: "my",
115
+ expected: "ymay",
116
+ },
117
+ {
118
+ description: "a whole phrase",
119
+ input: "quick fast run",
120
+ expected: "ickquay astfay unray",
121
+ },
122
+ }
@@ -1,4 +1,4 @@
1
- package igpay
1
+ package piglatin
2
2
 
3
3
  import (
4
4
  "regexp"
@@ -7,16 +7,28 @@ import (
7
7
 
8
8
  var vowel = regexp.MustCompile(`^([aeiou]|y[^aeiou]|xr)[a-z]*`)
9
9
  var cons = regexp.MustCompile(`^([^aeiou]?qu|[^aeiou]+)([a-z]*)`)
10
+ var containsy = regexp.MustCompile(`^([^aeiou]+)y([a-z]*)`)
10
11
 
11
- func PigLatin(s string) string {
12
+ // Sentence translates a whole sentence in piglatin
13
+ func Sentence(s string) string {
12
14
  sw := strings.Fields(s)
13
15
  for i, w := range sw {
14
- l := strings.ToLower(w)
15
- if vowel.MatchString(l) {
16
- sw[i] = l + "ay"
17
- } else if x := cons.FindStringSubmatchIndex(l); x != nil {
18
- sw[i] = l[x[3]:] + l[:x[3]] + "ay"
19
- }
16
+ sw[i] = Word(strings.ToLower(w))
20
17
  }
21
18
  return strings.Join(sw, " ")
22
19
  }
20
+
21
+ // Word translates a single word
22
+ func Word(s string) (result string) {
23
+ //special case for y as a vowel
24
+ if containsy.MatchString(s) {
25
+ pos := containsy.FindStringSubmatchIndex(s)
26
+ return s[pos[3]:] + s[:pos[3]] + "ay"
27
+ }
28
+ if vowel.MatchString(s) {
29
+ result = s + "ay"
30
+ } else if x := cons.FindStringSubmatchIndex(s); x != nil {
31
+ result = s[x[3]:] + s[:x[3]] + "ay"
32
+ }
33
+ return result
34
+ }
@@ -1,29 +1,15 @@
1
- package igpay
1
+ package piglatin
2
2
 
3
- import "testing"
4
-
5
- var tests = []struct{ pl, in string }{
6
- {"appleay", "apple"},
7
- {"earay", "ear"},
8
- {"igpay", "pig"},
9
- {"oalakay", "koala"},
10
- {"airchay", "chair"},
11
- {"eenquay", "queen"},
12
- {"aresquay", "square"},
13
- {"erapythay", "therapy"},
14
- {"ushthray", "thrush"},
15
- {"oolschay", "school"},
16
- {"ickquay astfay unray", "quick fast run"},
17
- {"ellowyay", "yellow"},
18
- {"yttriaay", "yttria"},
19
- {"enonxay", "xenon"},
20
- {"xrayay", "xray"},
21
- }
3
+ import (
4
+ "fmt"
5
+ "testing"
6
+ )
22
7
 
23
8
  func TestPigLatin(t *testing.T) {
24
- for _, test := range tests {
25
- if pl := PigLatin(test.in); pl != test.pl {
26
- t.Fatalf("PigLatin(%q) = %q, want %q.", test.in, pl, test.pl)
9
+ for _, test := range testCases {
10
+ if pl := Sentence(test.input); pl != test.expected {
11
+ t.Fatalf("FAIL: Sentence(%q) = %q, want %q.", test.input, pl, test.expected)
27
12
  }
13
+ fmt.Printf("PASS: %s\n", test.description)
28
14
  }
29
15
  }
@@ -1,5 +1,5 @@
1
- import java.util.regex.Matcher;
2
- import java.util.regex.Pattern;
1
+ import java.util.Arrays;
2
+ import java.util.stream.Collectors;
3
3
 
4
4
  final class Acronym {
5
5
 
@@ -13,14 +13,12 @@ final class Acronym {
13
13
  return acronym;
14
14
  }
15
15
 
16
- private String generateAcronym(String phrase){
17
- final Pattern BREAK_WORDS = Pattern.compile("[A-Z]+[a-z]*|[a-z]+");
18
- final Matcher matcher = BREAK_WORDS.matcher(phrase);
19
- final StringBuilder stringBuilder = new StringBuilder();
20
- while (matcher.find()){
21
- stringBuilder.append(matcher.group().charAt(0));
22
- }
23
- return stringBuilder.toString().toUpperCase();
16
+ private String generateAcronym(String phrase) {
17
+ return Arrays.stream(phrase.split("[^a-zA-Z]"))
18
+ .filter(word -> !word.isEmpty()) // Remove empty strings from the result of phrase.split
19
+ .map(word -> word.substring(0, 1)) // Get the first character of each word
20
+ .collect(Collectors.joining()) // Concatenate the characters
21
+ .toUpperCase();
24
22
  }
25
23
 
26
24
  }
@@ -1,4 +1,5 @@
1
1
  import java.util.*;
2
+ import java.util.stream.Collectors;
2
3
 
3
4
  class Anagram {
4
5
 
@@ -9,15 +10,9 @@ class Anagram {
9
10
  }
10
11
 
11
12
  List<String> match(List<String> candidates) {
12
- List<String> anagrams = new ArrayList<String>();
13
-
14
- for (String candidate : candidates) {
15
- if (anagramSubject.anagramOf(candidate)) {
16
- anagrams.add(candidate);
17
- }
18
- }
19
-
20
- return anagrams;
13
+ return candidates.stream()
14
+ .filter(anagramSubject::anagramOf)
15
+ .collect(Collectors.toList());
21
16
  }
22
17
 
23
18
  static final class AnagramSubject {
@@ -30,15 +30,7 @@ class Atbash {
30
30
  }
31
31
 
32
32
  private String stripInvalidCharacters(String input) {
33
- StringBuilder filteredValue = new StringBuilder(input.length());
34
-
35
- for (char c : input.toCharArray()) {
36
- if (Character.isLetterOrDigit(c)) {
37
- filteredValue.append(c);
38
- }
39
- }
40
-
41
- return filteredValue.toString();
33
+ return input.replaceAll("\\W", "");
42
34
  }
43
35
 
44
36
  private char applyCipher(char input) {
@@ -51,7 +43,7 @@ class Atbash {
51
43
  List<String> words = new ArrayList<>();
52
44
 
53
45
  for (int i = 0; i < value.length(); i += GROUP_SIZE) {
54
- words.add(i + GROUP_SIZE <= value.length() ? value.substring(i, i + GROUP_SIZE) : value.substring(i));
46
+ words.add(value.substring(i, Math.min(value.length(), i + GROUP_SIZE)));
55
47
  }
56
48
 
57
49
  return String.join(" ", words);
@@ -1 +1 @@
1
- 1.1.0
1
+ 2.0.1
@@ -5,6 +5,7 @@ import org.junit.rules.ExpectedException;
5
5
 
6
6
  import static org.junit.Assert.assertEquals;
7
7
 
8
+
8
9
  public class HammingTest {
9
10
 
10
11
  @Rule
@@ -60,13 +61,13 @@ public class HammingTest {
60
61
  @Ignore("Remove to run test")
61
62
  @Test
62
63
  public void testNonUniqueCharacterInFirstStrand() {
63
- assertEquals(1, new Hamming("AGA", "AGG").getHammingDistance());
64
+ assertEquals(1, new Hamming("AAG", "AAA").getHammingDistance());
64
65
  }
65
66
 
66
67
  @Ignore("Remove to run test")
67
68
  @Test
68
69
  public void testNonUniqueCharacterInSecondStrand() {
69
- assertEquals(1, new Hamming("AGG", "AGA").getHammingDistance());
70
+ assertEquals(1, new Hamming("AAA", "AAG").getHammingDistance());
70
71
  }
71
72
 
72
73
  @Ignore("Remove to run test")
@@ -0,0 +1 @@
1
+ 1.2.0
@@ -6,9 +6,16 @@ import static org.junit.Assert.*;
6
6
  public class IsogramCheckerTest {
7
7
 
8
8
  @Test
9
- public void testIsogram() {
9
+ public void testEmptyString() {
10
10
  IsogramChecker iso = new IsogramChecker();
11
- assertTrue(iso.isIsogram("duplicates"));
11
+ assertTrue(iso.isIsogram(""));
12
+ }
13
+
14
+ @Ignore("Remove to run test")
15
+ @Test
16
+ public void testLowercaseIsogram() {
17
+ IsogramChecker iso = new IsogramChecker();
18
+ assertTrue(iso.isIsogram("isogram"));
12
19
  }
13
20
 
14
21
  @Ignore("Remove to run test")
@@ -41,37 +48,23 @@ public class IsogramCheckerTest {
41
48
 
42
49
  @Ignore("Remove to run test")
43
50
  @Test
44
- public void testIgnoresMultipleHyphens() {
45
- IsogramChecker iso = new IsogramChecker();
46
- assertTrue(iso.isIsogram("Hjelmqvist-Gryb-Zock-Pfund-Wax"));
47
- }
48
-
49
- @Ignore("Remove to run test")
50
- @Test
51
- public void testWorksWithGermanLetters() {
52
- IsogramChecker iso = new IsogramChecker();
53
- assertTrue(iso.isIsogram("Heizölrückstoßabdämpfung"));
54
- }
55
-
56
- @Ignore("Remove to run test")
57
- @Test
58
- public void testIgnoresSpaces() {
51
+ public void testIsogramWithDuplicatedHyphen() {
59
52
  IsogramChecker iso = new IsogramChecker();
60
- assertFalse(iso.isIsogram("the quick brown fox"));
53
+ assertTrue(iso.isIsogram("six-year-old"));
61
54
  }
62
55
 
63
56
  @Ignore("Remove to run test")
64
57
  @Test
65
- public void testIgnoresSpaces2() {
58
+ public void testMadeUpNameThatIsAnIsogram() {
66
59
  IsogramChecker iso = new IsogramChecker();
67
60
  assertTrue(iso.isIsogram("Emily Jung Schwartzkopf"));
68
61
  }
69
62
 
70
63
  @Ignore("Remove to run test")
71
64
  @Test
72
- public void testDuplicateAccentedLetters() {
65
+ public void testDuplicatedCharacterInTheMiddleIsNotIsogram() {
73
66
  IsogramChecker iso = new IsogramChecker();
74
- assertFalse(iso.isIsogram("éléphant"));
67
+ assertFalse(iso.isIsogram("accentor"));
75
68
  }
76
69
 
77
70
  }
@@ -887,7 +887,7 @@
887
887
  ]
888
888
  },
889
889
  {
890
- "uuid": "b02a4214-0f1a-9480-2132-2ea3d5073dbfbec0aa4",
890
+ "uuid": "1304b188-6d08-4361-be40-c6b1b88e5e54",
891
891
  "slug": "two-fer",
892
892
  "core": false,
893
893
  "unlocked_by": null,
@@ -908,7 +908,7 @@
908
908
  "deprecated": true
909
909
  },
910
910
  {
911
- "uuid": "4ca1322e-0c39-1e80-91e9-6b3f9ccf894f9058490",
911
+ "uuid": "d75bd7c0-52c5-44f2-a046-f63cb332425f",
912
912
  "slug": "complex-numbers",
913
913
  "difficulty": 3,
914
914
  "topics": [ "Mathematics" ]
@@ -923,6 +923,18 @@
923
923
  "strings",
924
924
  "logic"
925
925
  ]
926
+ },
927
+ {
928
+ "uuid": "0ec96460-08be-49a0-973a-4336f21b763c",
929
+ "slug": "book-store",
930
+ "core": false,
931
+ "unlocked_by": null,
932
+ "difficulty": 6,
933
+ "topics": [
934
+ "loops",
935
+ "arrays",
936
+ "logic"
937
+ ]
926
938
  }
927
939
  ],
928
940
  "foregone": [
@@ -0,0 +1,9 @@
1
+ require 'generator/exercise_case'
2
+
3
+ class BookStoreCase < Generator::ExerciseCase
4
+
5
+ def workload
6
+ assert_equal { "BookStore.calculate_price(#{basket})" }
7
+ end
8
+
9
+ end
@@ -0,0 +1,47 @@
1
+ module BookKeeping
2
+ VERSION = 0
3
+ end
4
+
5
+ class BookStore
6
+
7
+ GROUP_DISCOUNTS = [0, 0.05, 0.1, 0.2, 0.25]
8
+ INDIVIDUAL_PRICE = 8
9
+
10
+ def self.calculate_price(basket)
11
+ groups = []
12
+ remaining_books = basket.dup
13
+
14
+ # Make as many groups of 4 as you can
15
+ while (largest_group = remaining_books.uniq).length > 3
16
+ group_of_four = largest_group[0..3]
17
+ group_of_four.each {|book| remaining_books.delete_at(remaining_books.index(book)) }
18
+ groups << group_of_four
19
+ end
20
+
21
+ # Bump as many of them to groups of 5 as you can
22
+ groups.each do |group|
23
+ fifth_book = (remaining_books - group).first
24
+ next unless fifth_book
25
+
26
+ group << fifth_book
27
+ remaining_books.delete_at(remaining_books.index(fifth_book))
28
+ end
29
+
30
+ # Make the largest groups you can with the remaining books
31
+ while (new_group = remaining_books.uniq).any?
32
+ new_group.each {|book| remaining_books.delete_at(remaining_books.index(book)) }
33
+ groups << new_group
34
+ end
35
+
36
+ groups.map {|group| group_price(group.length) }.inject(0,:+)
37
+ end
38
+
39
+ private
40
+
41
+ def self.group_price(group_size)
42
+ discount = GROUP_DISCOUNTS[group_size - 1]
43
+
44
+ group_size * INDIVIDUAL_PRICE * (1 - discount)
45
+ end
46
+
47
+ end