trackler 2.2.1.75 → 2.2.1.76

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/alphametics/canonical-data.json +18 -1
  4. data/problem-specifications/exercises/anagram/canonical-data.json +72 -39
  5. data/problem-specifications/exercises/binary/canonical-data.json +47 -17
  6. data/tracks/clojure/exercises/beer-song/src/beer_song.clj +11 -0
  7. data/tracks/erlang/config.json +10 -0
  8. data/tracks/erlang/exercises/raindrops/README.md +67 -0
  9. data/tracks/erlang/exercises/raindrops/rebar.config +30 -0
  10. data/tracks/erlang/exercises/raindrops/src/example.erl +30 -0
  11. data/tracks/erlang/exercises/raindrops/src/raindrops.app.src +9 -0
  12. data/tracks/erlang/exercises/raindrops/src/raindrops.erl +8 -0
  13. data/tracks/erlang/exercises/raindrops/test/raindrops_tests.erl +50 -0
  14. data/tracks/fsharp/exercises/bob/BobTest.fs +2 -2
  15. data/tracks/fsharp/exercises/bob/Example.fs +10 -4
  16. data/tracks/fsharp/exercises/book-store/BookStoreTest.fs +5 -1
  17. data/tracks/fsharp/exercises/rna-transcription/RnaTranscriptionTest.fs +1 -13
  18. data/tracks/fsharp/generators/CanonicalData.fs +14 -7
  19. data/tracks/fsharp/generators/Exercise.fs +84 -18
  20. data/tracks/fsharp/generators/Generators.fs +65 -62
  21. data/tracks/fsharp/generators/Generators.fsproj +0 -4
  22. data/tracks/fsharp/generators/Options.fs +51 -17
  23. data/tracks/fsharp/generators/Program.fs +34 -7
  24. data/tracks/fsharp/generators/Rendering.fs +2 -1
  25. data/tracks/go/config.json +11 -0
  26. data/tracks/go/exercises/reverse-string/.meta/gen.go +52 -0
  27. data/tracks/go/exercises/reverse-string/README.md +31 -0
  28. data/tracks/go/exercises/reverse-string/cases_test.go +37 -0
  29. data/tracks/go/exercises/reverse-string/example.go +10 -0
  30. data/tracks/go/exercises/reverse-string/reverse_string_test.go +25 -0
  31. data/tracks/haskell/exercises/bob/README.md +2 -0
  32. data/tracks/haskell/exercises/bob/examples/success-standard/src/Bob.hs +7 -3
  33. data/tracks/haskell/exercises/bob/package.yaml +1 -1
  34. data/tracks/haskell/exercises/bob/test/Tests.hs +1 -1
  35. data/tracks/haskell/exercises/isbn-verifier/README.md +25 -20
  36. data/tracks/haskell/exercises/pov/README.md +0 -2
  37. data/tracks/haskell/exercises/secret-handshake/README.md +1 -1
  38. data/tracks/haskell/exercises/simple-cipher/README.md +4 -6
  39. data/tracks/java/config.json +12 -0
  40. data/tracks/java/exercises/beer-song/README.md +1 -1
  41. data/tracks/java/exercises/house/README.md +1 -1
  42. data/tracks/java/exercises/isbn-verifier/README.md +27 -21
  43. data/tracks/java/exercises/kindergarten-garden/README.md +3 -3
  44. data/tracks/java/exercises/meetup/README.md +16 -12
  45. data/tracks/java/exercises/nucleotide-count/README.md +2 -2
  46. data/tracks/java/exercises/palindrome-products/README.md +1 -1
  47. data/tracks/java/exercises/parallel-letter-frequency/.meta/HINTS.md +3 -0
  48. data/tracks/java/exercises/parallel-letter-frequency/.meta/src/reference/java/ParallelLetterFrequency.java +45 -0
  49. data/tracks/java/exercises/parallel-letter-frequency/README.md +30 -0
  50. data/tracks/java/exercises/parallel-letter-frequency/build.gradle +18 -0
  51. data/tracks/java/exercises/parallel-letter-frequency/src/main/java/.keep +0 -0
  52. data/tracks/java/exercises/parallel-letter-frequency/src/test/java/ParallelLetterFrequencyTest.java +235 -0
  53. data/tracks/java/exercises/pig-latin/README.md +1 -0
  54. data/tracks/java/exercises/protein-translation/README.md +4 -2
  55. data/tracks/java/exercises/rectangles/README.md +9 -9
  56. data/tracks/java/exercises/settings.gradle +1 -0
  57. data/tracks/java/exercises/simple-cipher/README.md +4 -6
  58. data/tracks/java/exercises/sum-of-multiples/README.md +3 -3
  59. data/tracks/objective-c/config.json +11 -0
  60. data/tracks/objective-c/exercises/two-fer/TwoFerExample.h +15 -0
  61. data/tracks/objective-c/exercises/two-fer/TwoFerExample.m +21 -0
  62. data/tracks/objective-c/exercises/two-fer/TwoFerTest.m +31 -0
  63. data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +18 -0
  64. data/tracks/rust/exercises/bob/Cargo.toml +1 -1
  65. data/tracks/rust/exercises/bob/README.md +2 -0
  66. data/tracks/rust/exercises/bob/example.rs +1 -0
  67. data/tracks/rust/exercises/bob/tests/bob.rs +1 -1
  68. data/tracks/rust/exercises/isbn-verifier/README.md +25 -20
  69. data/tracks/typescript/config.json +13 -0
  70. data/tracks/typescript/exercises/atbash-cipher/README.md +60 -0
  71. data/tracks/typescript/exercises/atbash-cipher/atbash-cipher.example.ts +32 -0
  72. data/tracks/typescript/exercises/atbash-cipher/atbash-cipher.test.ts +73 -0
  73. data/tracks/typescript/exercises/atbash-cipher/atbash-cipher.ts +0 -0
  74. data/tracks/typescript/exercises/atbash-cipher/package.json +36 -0
  75. data/tracks/typescript/exercises/atbash-cipher/tsconfig.json +22 -0
  76. data/tracks/typescript/exercises/atbash-cipher/tslint.json +127 -0
  77. data/tracks/typescript/exercises/atbash-cipher/yarn.lock +2624 -0
  78. metadata +31 -2
@@ -2,8 +2,6 @@
2
2
 
3
3
  Reparent a graph on a selected node.
4
4
 
5
- # Tree Reparenting
6
-
7
5
  This exercise is all about re-orientating a graph to see things from a different
8
6
  point of view. For example family trees are usually presented from the
9
7
  ancestor's perspective:
@@ -83,7 +83,7 @@ one, head over there and create an issue. We'll do our best to help you!
83
83
 
84
84
  ## Source
85
85
 
86
- Bert, in Mary Poppins [http://www.imdb.com/character/ch0011238/quotes](http://www.imdb.com/character/ch0011238/quotes)
86
+ Bert, in Mary Poppins [http://www.imdb.com/title/tt0058331/quotes/qt0437047](http://www.imdb.com/title/tt0058331/quotes/qt0437047)
87
87
 
88
88
  ## Submitting Incomplete Solutions
89
89
  It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -58,15 +58,13 @@ would get the same thing as the Caesar Cipher.
58
58
 
59
59
  The weakest link in any cipher is the human being. Let's make your
60
60
  substitution cipher a little more fault tolerant by providing a source
61
- of randomness and ensuring that the key is not composed of numbers or
62
- capital letters.
61
+ of randomness and ensuring that the key contains only lowercase letters.
63
62
 
64
63
  If someone doesn't submit a key at all, generate a truly random key of
65
- at least 100 characters in length, accessible via Cipher#key (the #
66
- syntax means instance variable)
64
+ at least 100 characters in length.
67
65
 
68
- If the key submitted has capital letters or numbers, throw an
69
- ArgumentError with a message to that effect.
66
+ If the key submitted is not composed only of lowercase letters, your
67
+ solution should handle the error in a language-appropriate way.
70
68
 
71
69
  ## Extensions
72
70
 
@@ -23,6 +23,18 @@
23
23
  "unlocked_by": null,
24
24
  "uuid": "74515d45-565b-4be2-96c4-77e58efa9257"
25
25
  },
26
+ {
27
+ "core": false,
28
+ "difficulty": 6,
29
+ "slug": "parallel-letter-frequency",
30
+ "topics": [
31
+ "concurrency",
32
+ "maps",
33
+ "strings"
34
+ ],
35
+ "unlocked_by": "hamming",
36
+ "uuid": "38a405e8-619d-400f-b53c-2f06461fdf9d"
37
+ },
26
38
  {
27
39
  "core": false,
28
40
  "difficulty": 1,
@@ -1,6 +1,6 @@
1
1
  # Beer Song
2
2
 
3
- Produce the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall.
3
+ Recite the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall.
4
4
 
5
5
  Note that not all verses are identical.
6
6
 
@@ -1,6 +1,6 @@
1
1
  # House
2
2
 
3
- Output the nursery rhyme 'This is the House that Jack Built'.
3
+ Recite the nursery rhyme 'This is the House that Jack Built'.
4
4
 
5
5
  > [The] process of placing a phrase of clause within another phrase of
6
6
  > clause is called embedding. It is through the processes of recursion
@@ -1,39 +1,45 @@
1
- Check if a given ISBN-10 is valid.
1
+ # Isbn Verifier
2
2
 
3
- ## Functionality
3
+ The [ISBN-10 verification process](https://en.wikipedia.org/wiki/International_Standard_Book_Number) is used to validate book identification
4
+ numbers. These normally contain dashes and look like: `3-598-21508-8`
4
5
 
5
- Given an unknown string the program should check if the provided string is a valid ISBN-10.
6
- Putting this into place requires some thinking about preprocessing/parsing of the string prior to calculating the check digit for the ISBN.
6
+ ## ISBN
7
7
 
8
- The program should allow for ISBN-10 without the separating dashes to be verified as well.
8
+ The ISBN-10 format is 9 digits (0 to 9) plus one check character (either a digit or an X only). In the case the check character is an X, this represents the value '10'. These may be communicated with or without hyphens, and can be checked for their validity by the following formula:
9
9
 
10
- ## ISBN
10
+ ```
11
+ (x1 * 10 + x2 * 9 + x3 * 8 + x4 * 7 + x5 * 6 + x6 * 5 + x7 * 4 + x8 * 3 + x9 * 2 + x10 * 1) mod 11 == 0
12
+ ```
11
13
 
12
- Let's take a random ISBN-10 number, say `3-598-21508-8` for this.
13
- The first digit block indicates the group where the ISBN belongs. Groups can consist of shared languages, geographic regions or countries. The leading '3' signals this ISBN is from a german speaking country.
14
- The following number block is to identify the publisher. Since this is a three digit publisher number there is a 5 digit title number for this book.
15
- The last digit in the ISBN is the check digit which is used to detect read errors.
14
+ If the result is 0, then it is a valid ISBN-10, otherwise it is invalid.
16
15
 
17
- The first 9 digits in the ISBN have to be between 0 and 9.
18
- The check digit can additionally be an 'X' to allow 10 to be a valid check digit as well.
16
+ ## Example
19
17
 
20
- A valid ISBN-10 is calculated with this formula `(x1 * 10 + x2 * 9 + x3 * 8 + x4 * 7 + x5 * 6 + x6 * 5 + x7 * 4 + x8 * 3 + x9 * 2 + x10 * 1) mod 11 == 0`
21
- So for our example ISBN this means:
22
- (3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11 = 0
18
+ Let's take the ISBN-10 `3-598-21508-8`. We plug it in to the formula, and get:
19
+ ```
20
+ (3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11 == 0
21
+ ```
22
+
23
+ Since the result is 0, this proves that our ISBN is valid.
24
+
25
+ ## Task
26
+
27
+ Given a string the program should check if the provided string is a valid ISBN-10.
28
+ Putting this into place requires some thinking about preprocessing/parsing of the string prior to calculating the check digit for the ISBN.
29
+
30
+ The program should be able to verify ISBN-10 both with and without separating dashes.
23
31
 
24
- Which proves that the ISBN is valid.
25
32
 
26
33
  ## Caveats
27
34
 
28
- Converting from string to number can be tricky in certain languages.
29
- It's getting even trickier since the check-digit of an ISBN-10 can be 'X'.
35
+ Converting from strings to numbers can be tricky in certain languages.
36
+ Now, it's even trickier since the check digit of an ISBN-10 may be 'X' (representing '10'). For instance `3-598-21507-X` is a valid ISBN-10.
30
37
 
31
38
  ## Bonus tasks
32
39
 
33
- * Generate a valid ISBN-13 from the input ISBN-10 (and maybe verify it again with a derived verifier)
34
-
35
- * Generate valid ISBN, maybe even from a given starting ISBN
40
+ * Generate a valid ISBN-13 from the input ISBN-10 (and maybe verify it again with a derived verifier).
36
41
 
42
+ * Generate valid ISBN, maybe even from a given starting ISBN.
37
43
  # Running the tests
38
44
 
39
45
  You can run all the tests for an exercise by entering
@@ -9,8 +9,8 @@ actual dirt, and grow actual plants.
9
9
 
10
10
  They've chosen to grow grass, clover, radishes, and violets.
11
11
 
12
- To this end, the children have put little cups along the window sills, and
13
- planted one type of plant in each cup, choosing randomly from the available
12
+ To this end, the children have put little cups along the window sills, and
13
+ planted one type of plant in each cup, choosing randomly from the available
14
14
  types of seeds.
15
15
 
16
16
  ```text
@@ -25,7 +25,7 @@ There are 12 children in the class:
25
25
  - Eve, Fred, Ginny, Harriet,
26
26
  - Ileana, Joseph, Kincaid, and Larry.
27
27
 
28
- Each child gets 4 cups, two on each row. Their teacher assigns cups to
28
+ Each child gets 4 cups, two on each row. Their teacher assigns cups to
29
29
  the children alphabetically by their names.
30
30
 
31
31
  The following diagram represents Alice's plants:
@@ -2,25 +2,29 @@
2
2
 
3
3
  Calculate the date of meetups.
4
4
 
5
- Typically meetups happen on the same day of the week. In this exercise, you will take
6
- a description of a meetup date, and return the actual meetup date.
5
+ Typically meetups happen on the same day of the week. In this exercise, you
6
+ will take a description of a meetup date, and return the actual meetup date.
7
7
 
8
8
  Examples of general descriptions are:
9
9
 
10
- - the first Monday of January 2017
11
- - the third Tuesday of January 2017
12
- - the Wednesteenth of January 2017
13
- - the last Thursday of January 2017
10
+ - The first Monday of January 2017
11
+ - The third Tuesday of January 2017
12
+ - The wednesteenth of January 2017
13
+ - The last Thursday of January 2017
14
14
 
15
- Note that "Monteenth", "Tuesteenth", etc are all made up words. There
16
- was a meetup whose members realized that there are exactly 7 numbered days in a month that
17
- end in '-teenth'. Therefore, one is guaranteed that each day of the week
15
+ The descriptors you are expected to parse are:
16
+ first, second, third, fourth, fifth, last, monteenth, tuesteenth, wednesteenth,
17
+ thursteenth, friteenth, saturteenth, sunteenth
18
+
19
+ Note that "monteenth", "tuesteenth", etc are all made up words. There was a
20
+ meetup whose members realized that there are exactly 7 numbered days in a month
21
+ that end in '-teenth'. Therefore, one is guaranteed that each day of the week
18
22
  (Monday, Tuesday, ...) will have exactly one date that is named with '-teenth'
19
23
  in every month.
20
24
 
21
- Given examples of a meetup dates, each containing a month, day, year, and descriptor
22
- (first, second, teenth, etc), calculate the date of the actual meetup.
23
- For example, if given "First Monday of January 2017", the correct meetup date is 2017/1/2
25
+ Given examples of a meetup dates, each containing a month, day, year, and
26
+ descriptor calculate the date of the actual meetup. For example, if given
27
+ "The first Monday of January 2017", the correct meetup date is 2017/1/2.
24
28
 
25
29
  # Running the tests
26
30
 
@@ -2,8 +2,8 @@
2
2
 
3
3
  Given a single stranded DNA string, compute how many times each nucleotide occurs in the string.
4
4
 
5
- The genetic language of every living thing on the planet is DNA.
6
- DNA is a large molecule that is built from an extremely long sequence of individual elements called nucleotides.
5
+ The genetic language of every living thing on the planet is DNA.
6
+ DNA is a large molecule that is built from an extremely long sequence of individual elements called nucleotides.
7
7
  4 types exist in DNA and these differ only slightly and can be represented as the following symbols: 'A' for adenine, 'C' for cytosine, 'G' for guanine, and 'T' thymine.
8
8
 
9
9
  Here is an analogy:
@@ -9,7 +9,7 @@ Given a range of numbers, find the largest and smallest palindromes which
9
9
  are products of numbers within that range.
10
10
 
11
11
  Your solution should return the largest and smallest palindromes, along with the
12
- factors of each within the range. If the largest or smallest palindrome has more
12
+ factors of each within the range. If the largest or smallest palindrome has more
13
13
  than one pair of factors within the range, then return all the pairs.
14
14
 
15
15
  ## Example 1
@@ -0,0 +1,3 @@
1
+ Single-threaded (non-concurrent) solutions can pass all tests [but the last.](https://www.youtube.com/watch?v=mJZZNHekEQw) Your solution will be tested for concurrency by submitting it as a [Runnable](https://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html) to an [ExecutorService.](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html) Your solution must leverage multiple [Threads](https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html) to pass the final test.
2
+
3
+ Java documentation on [parallel streams](https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html) may provide some help.
@@ -0,0 +1,45 @@
1
+ import java.util.Collections;
2
+ import java.util.HashMap;
3
+ import java.util.Map;
4
+
5
+
6
+ class ParallelLetterFrequency {
7
+
8
+ private static Map<Integer, Integer> letterFrequencyMap;
9
+ private final String NOT_A_LETTER = "\\P{L}+";
10
+
11
+
12
+ ParallelLetterFrequency(String letters) {
13
+ letterFrequencyMap = getMapFromLetters(letters.toLowerCase().replaceAll(NOT_A_LETTER, ""));
14
+ }
15
+
16
+ Map<Integer, Integer> getMapFromLetters(String letters) {
17
+ return letters
18
+ .chars()
19
+ .parallel()
20
+ .collect(Counts::new, Counts::increment, Counts::combine)
21
+ .buildMap();
22
+ }
23
+
24
+ private static class Counts {
25
+
26
+ private Map<Integer, Integer> letterCounts = new HashMap<>();
27
+
28
+ private void increment(int letter) {
29
+ letterCounts.put(letter, letterCounts.getOrDefault(letter, 0) + 1);
30
+ }
31
+
32
+ private void combine(Counts other) {
33
+ other.letterCounts.keySet()
34
+ .forEach(letter -> letterCounts.merge(letter, other.letterCounts.get(letter), Integer::sum));
35
+ }
36
+
37
+ private Map<Integer, Integer> buildMap() {
38
+ return Collections.unmodifiableMap(letterCounts);
39
+ }
40
+ }
41
+
42
+ Map<Integer, Integer> letterCounts() {
43
+ return letterFrequencyMap;
44
+ }
45
+ }
@@ -0,0 +1,30 @@
1
+ # Parallel Letter Frequency
2
+
3
+ Count the frequency of letters in texts using parallel computation.
4
+
5
+ Parallelism is about doing things in parallel that can also be done
6
+ sequentially. A common example is counting the frequency of letters.
7
+ Create a function that returns the total frequency of each letter in a
8
+ list of texts and that employs parallelism.
9
+
10
+ # Java Tips
11
+
12
+ Single-threaded (non-concurrent) solutions can pass all tests [but the last.](https://www.youtube.com/watch?v=mJZZNHekEQw) Your solution will be tested for concurrency by submitting it as a [Runnable](https://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html) to an [ExecutorService.](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html) Your solution must leverage multiple [Threads](https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html) to pass the final test.
13
+
14
+ Java documentation on [parallel streams](https://docs.oracle.com/javase/tutorial/collections/streams/parallelism.html) may provide some help.
15
+
16
+
17
+ # Running the tests
18
+
19
+ You can run all the tests for an exercise by entering
20
+
21
+ ```sh
22
+ $ gradle test
23
+ ```
24
+
25
+ in your terminal.
26
+
27
+
28
+ ## Submitting Incomplete Solutions
29
+
30
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,18 @@
1
+ apply plugin: "java"
2
+ apply plugin: "eclipse"
3
+ apply plugin: "idea"
4
+
5
+ repositories {
6
+ mavenCentral()
7
+ }
8
+
9
+ dependencies {
10
+ testCompile "junit:junit:4.12"
11
+ }
12
+
13
+ test {
14
+ testLogging {
15
+ exceptionFormat = 'full'
16
+ events = ["passed", "failed", "skipped"]
17
+ }
18
+ }
@@ -0,0 +1,235 @@
1
+ import org.junit.*;
2
+
3
+ import static org.junit.Assert.*;
4
+
5
+ import java.util.concurrent.*;
6
+ import java.util.stream.*;
7
+ import java.util.*;
8
+
9
+ public class ParallelLetterFrequencyTest {
10
+
11
+ // Poem by Friedrich Schiller. The corresponding music is the European Anthem.
12
+ private String OdeAnDieFreude =
13
+ "Freude schöner Götterfunken\n" +
14
+ "Tochter aus Elysium,\n" +
15
+ "Wir betreten feuertrunken,\n" +
16
+ "Himmlische, dein Heiligtum!\n" +
17
+ "Deine Zauber binden wieder\n" +
18
+ "Was die Mode streng geteilt;\n" +
19
+ "Alle Menschen werden Brüder,\n" +
20
+ "Wo dein sanfter Flügel weilt.";
21
+
22
+ // Dutch national anthem
23
+ private String Wilhelmus =
24
+ "Wilhelmus van Nassouwe\n" +
25
+ "ben ik, van Duitsen bloed,\n" +
26
+ "den vaderland getrouwe\n" +
27
+ "blijf ik tot in den dood.\n" +
28
+ "Een Prinse van Oranje\n" +
29
+ "ben ik, vrij, onverveerd,\n" +
30
+ "den Koning van Hispanje\n" +
31
+ "heb ik altijd geëerd.";
32
+
33
+ // American national anthem
34
+ private String StarSpangledBanner =
35
+ "O say can you see by the dawn's early light,\n" +
36
+ "What so proudly we hailed at the twilight's last gleaming,\n" +
37
+ "Whose broad stripes and bright stars through the perilous fight,\n" +
38
+ "O'er the ramparts we watched, were so gallantly streaming?\n" +
39
+ "And the rockets' red glare, the bombs bursting in air,\n" +
40
+ "Gave proof through the night that our flag was still there;\n" +
41
+ "O say does that star-spangled banner yet wave,\n" +
42
+ "O'er the land of the free and the home of the brave?\n";
43
+
44
+
45
+ @Test
46
+ public void noTextsMeansNoLetters() {
47
+ String input = "";
48
+ Map<Integer, Integer> expectedOutput = new HashMap<Integer, Integer>();
49
+ ParallelLetterFrequency p = new ParallelLetterFrequency(input);
50
+
51
+ assertEquals(expectedOutput, p.letterCounts());
52
+ }
53
+
54
+ @Ignore("Remove to run test")
55
+ @Test
56
+ public void oneLetterIsCorrectlyCounted() {
57
+ String input = "a";
58
+ Map<Integer, Integer> expectedOutput = new HashMap<Integer, Integer>() {
59
+ {
60
+ put((int) 'a', 1);
61
+ }
62
+ };
63
+ ParallelLetterFrequency p = new ParallelLetterFrequency(input);
64
+
65
+ assertEquals(expectedOutput, p.letterCounts());
66
+ }
67
+
68
+ @Ignore("Remove to run test")
69
+ @Test
70
+ public void resultsAreCaseInsensitive() {
71
+ String input = "Aa";
72
+ Map<Integer, Integer> expectedOutput = new HashMap<Integer, Integer>() {
73
+ {
74
+ put((int) 'a', 2);
75
+ }
76
+ };
77
+ ParallelLetterFrequency p = new ParallelLetterFrequency(input);
78
+
79
+ assertEquals(expectedOutput, p.letterCounts());
80
+ }
81
+
82
+
83
+ @Ignore("Remove to run test")
84
+ @Test
85
+ public void biggerEmptyTextsStillReturnNoResults() {
86
+ StringBuilder b = new StringBuilder();
87
+ for (int i = 0; i < 10000; i++) {
88
+ b.append(" ");
89
+ }
90
+
91
+ Map<Integer, Integer> expectedOutput = new HashMap<Integer, Integer>();
92
+ ParallelLetterFrequency p = new ParallelLetterFrequency(b.toString());
93
+
94
+ assertEquals(expectedOutput, p.letterCounts());
95
+ }
96
+
97
+ @Ignore("Remove to run test")
98
+ @Test
99
+ public void manyRepetitionsOfTheSameTextGiveAPredictableResult() {
100
+ StringBuilder b = new StringBuilder();
101
+ for (int i = 0; i < 10000; i++) {
102
+ b.append("abc");
103
+ }
104
+
105
+ Map<Integer, Integer> expectedOutput = new HashMap<Integer, Integer>() {
106
+ {
107
+ put((int) 'a', 10000);
108
+ put((int) 'b', 10000);
109
+ put((int) 'c', 10000);
110
+ }
111
+ };
112
+ ParallelLetterFrequency p = new ParallelLetterFrequency(b.toString());
113
+
114
+ assertEquals(expectedOutput, p.letterCounts());
115
+ }
116
+
117
+
118
+ @Ignore("Remove to run test")
119
+ @Test
120
+ public void punctuationDoesntCount() {
121
+ ParallelLetterFrequency p = new ParallelLetterFrequency(OdeAnDieFreude);
122
+
123
+ assertFalse(p.letterCounts().containsKey((int) ','));
124
+ }
125
+
126
+ @Ignore("Remove to run test")
127
+ @Test
128
+ public void numbersDontCount() {
129
+ ParallelLetterFrequency p = new ParallelLetterFrequency("Testing, 1, 2, 3");
130
+
131
+ assertFalse(p.letterCounts().containsKey((int) '1'));
132
+ }
133
+
134
+ @Ignore("Remove to run test")
135
+ @Test
136
+ public void allThreeAnthemsTogetherProduceCorrectCounts() {
137
+ StringBuilder b = new StringBuilder();
138
+ b.append(OdeAnDieFreude);
139
+ b.append(Wilhelmus);
140
+ b.append(StarSpangledBanner);
141
+
142
+ ParallelLetterFrequency p = new ParallelLetterFrequency(b.toString());
143
+
144
+ assertEquals(new Integer(49), p.letterCounts().get((int) 'a'));
145
+ assertEquals(new Integer(56), p.letterCounts().get((int) 't'));
146
+ assertEquals(new Integer(2), p.letterCounts().get((int) 'ü'));
147
+ }
148
+
149
+ @Ignore("Remove to run test")
150
+ @Test
151
+ public void multipleThreadsGetUsed()
152
+ throws InterruptedException, ExecutionException {
153
+
154
+
155
+ class MyForkJoinWorkerThread extends ForkJoinWorkerThread {
156
+
157
+ boolean wasStarted = false;
158
+
159
+ public MyForkJoinWorkerThread(ForkJoinPool pool) {
160
+ super(pool);
161
+ }
162
+
163
+ @Override
164
+ public void start() {
165
+ super.start();
166
+ this.wasStarted = true;
167
+ }
168
+ }
169
+
170
+ List<MyForkJoinWorkerThread> allThreads = new ArrayList<>();
171
+
172
+ class MyForkJoinThreadFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory {
173
+ public MyForkJoinThreadFactory() {
174
+ super();
175
+ }
176
+
177
+ public MyForkJoinWorkerThread newThread(ForkJoinPool pool) {
178
+ final MyForkJoinWorkerThread worker = new MyForkJoinWorkerThread(pool);
179
+ worker.setName("Thread number: " + worker.getPoolIndex());
180
+ allThreads.add(worker);
181
+ return worker;
182
+ }
183
+ }
184
+
185
+ MyForkJoinThreadFactory factory = new MyForkJoinThreadFactory();
186
+ ForkJoinPool multiThreadPool = new ForkJoinPool(4, (ForkJoinPool.ForkJoinWorkerThreadFactory) factory, null, false);
187
+
188
+ String input = "abcdefghijklmnopqrstuvwxyz";
189
+ StringBuilder b = new StringBuilder();
190
+ for (int i = 1; i < 10000000; i++) {
191
+ b.append(input);
192
+ }
193
+
194
+ Map<Integer, Integer> expectedOutput = new HashMap<Integer, Integer>() {
195
+ {
196
+ put((int) 'a', 10000000);
197
+ put((int) 'b', 10000000);
198
+ put((int) 'c', 10000000);
199
+ put((int) 'd', 10000000);
200
+ put((int) 'e', 10000000);
201
+ put((int) 'f', 10000000);
202
+ put((int) 'g', 10000000);
203
+ put((int) 'h', 10000000);
204
+ put((int) 'i', 10000000);
205
+ put((int) 'j', 10000000);
206
+ put((int) 'k', 10000000);
207
+ put((int) 'l', 10000000);
208
+ put((int) 'm', 10000000);
209
+ put((int) 'n', 10000000);
210
+ put((int) 'o', 10000000);
211
+ put((int) 'p', 10000000);
212
+ put((int) 'q', 10000000);
213
+ put((int) 'r', 10000000);
214
+ put((int) 's', 10000000);
215
+ put((int) 't', 10000000);
216
+ put((int) 'u', 10000000);
217
+ put((int) 'v', 10000000);
218
+ put((int) 'w', 10000000);
219
+ put((int) 'x', 10000000);
220
+ put((int) 'y', 10000000);
221
+ put((int) 'z', 10000000);
222
+ }
223
+ };
224
+
225
+ Map<Integer, Integer> multiCounts = multiThreadPool.submit(
226
+ () -> (new ParallelLetterFrequency(b.toString()).letterCounts())
227
+ ).get();
228
+
229
+ boolean startedThreadCountEqualsPoolSize = allThreads.stream()
230
+ .filter(thread -> thread.wasStarted)
231
+ .count() == allThreads.size();
232
+
233
+ assertTrue(startedThreadCountEqualsPoolSize);
234
+ }
235
+ }