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.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/alphametics/canonical-data.json +18 -1
- data/problem-specifications/exercises/anagram/canonical-data.json +72 -39
- data/problem-specifications/exercises/binary/canonical-data.json +47 -17
- data/tracks/clojure/exercises/beer-song/src/beer_song.clj +11 -0
- data/tracks/erlang/config.json +10 -0
- data/tracks/erlang/exercises/raindrops/README.md +67 -0
- data/tracks/erlang/exercises/raindrops/rebar.config +30 -0
- data/tracks/erlang/exercises/raindrops/src/example.erl +30 -0
- data/tracks/erlang/exercises/raindrops/src/raindrops.app.src +9 -0
- data/tracks/erlang/exercises/raindrops/src/raindrops.erl +8 -0
- data/tracks/erlang/exercises/raindrops/test/raindrops_tests.erl +50 -0
- data/tracks/fsharp/exercises/bob/BobTest.fs +2 -2
- data/tracks/fsharp/exercises/bob/Example.fs +10 -4
- data/tracks/fsharp/exercises/book-store/BookStoreTest.fs +5 -1
- data/tracks/fsharp/exercises/rna-transcription/RnaTranscriptionTest.fs +1 -13
- data/tracks/fsharp/generators/CanonicalData.fs +14 -7
- data/tracks/fsharp/generators/Exercise.fs +84 -18
- data/tracks/fsharp/generators/Generators.fs +65 -62
- data/tracks/fsharp/generators/Generators.fsproj +0 -4
- data/tracks/fsharp/generators/Options.fs +51 -17
- data/tracks/fsharp/generators/Program.fs +34 -7
- data/tracks/fsharp/generators/Rendering.fs +2 -1
- data/tracks/go/config.json +11 -0
- data/tracks/go/exercises/reverse-string/.meta/gen.go +52 -0
- data/tracks/go/exercises/reverse-string/README.md +31 -0
- data/tracks/go/exercises/reverse-string/cases_test.go +37 -0
- data/tracks/go/exercises/reverse-string/example.go +10 -0
- data/tracks/go/exercises/reverse-string/reverse_string_test.go +25 -0
- data/tracks/haskell/exercises/bob/README.md +2 -0
- data/tracks/haskell/exercises/bob/examples/success-standard/src/Bob.hs +7 -3
- data/tracks/haskell/exercises/bob/package.yaml +1 -1
- data/tracks/haskell/exercises/bob/test/Tests.hs +1 -1
- data/tracks/haskell/exercises/isbn-verifier/README.md +25 -20
- data/tracks/haskell/exercises/pov/README.md +0 -2
- data/tracks/haskell/exercises/secret-handshake/README.md +1 -1
- data/tracks/haskell/exercises/simple-cipher/README.md +4 -6
- data/tracks/java/config.json +12 -0
- data/tracks/java/exercises/beer-song/README.md +1 -1
- data/tracks/java/exercises/house/README.md +1 -1
- data/tracks/java/exercises/isbn-verifier/README.md +27 -21
- data/tracks/java/exercises/kindergarten-garden/README.md +3 -3
- data/tracks/java/exercises/meetup/README.md +16 -12
- data/tracks/java/exercises/nucleotide-count/README.md +2 -2
- data/tracks/java/exercises/palindrome-products/README.md +1 -1
- data/tracks/java/exercises/parallel-letter-frequency/.meta/HINTS.md +3 -0
- data/tracks/java/exercises/parallel-letter-frequency/.meta/src/reference/java/ParallelLetterFrequency.java +45 -0
- data/tracks/java/exercises/parallel-letter-frequency/README.md +30 -0
- data/tracks/java/exercises/parallel-letter-frequency/build.gradle +18 -0
- data/tracks/java/exercises/parallel-letter-frequency/src/main/java/.keep +0 -0
- data/tracks/java/exercises/parallel-letter-frequency/src/test/java/ParallelLetterFrequencyTest.java +235 -0
- data/tracks/java/exercises/pig-latin/README.md +1 -0
- data/tracks/java/exercises/protein-translation/README.md +4 -2
- data/tracks/java/exercises/rectangles/README.md +9 -9
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/java/exercises/simple-cipher/README.md +4 -6
- data/tracks/java/exercises/sum-of-multiples/README.md +3 -3
- data/tracks/objective-c/config.json +11 -0
- data/tracks/objective-c/exercises/two-fer/TwoFerExample.h +15 -0
- data/tracks/objective-c/exercises/two-fer/TwoFerExample.m +21 -0
- data/tracks/objective-c/exercises/two-fer/TwoFerTest.m +31 -0
- data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +18 -0
- data/tracks/rust/exercises/bob/Cargo.toml +1 -1
- data/tracks/rust/exercises/bob/README.md +2 -0
- data/tracks/rust/exercises/bob/example.rs +1 -0
- data/tracks/rust/exercises/bob/tests/bob.rs +1 -1
- data/tracks/rust/exercises/isbn-verifier/README.md +25 -20
- data/tracks/typescript/config.json +13 -0
- data/tracks/typescript/exercises/atbash-cipher/README.md +60 -0
- data/tracks/typescript/exercises/atbash-cipher/atbash-cipher.example.ts +32 -0
- data/tracks/typescript/exercises/atbash-cipher/atbash-cipher.test.ts +73 -0
- data/tracks/typescript/exercises/atbash-cipher/atbash-cipher.ts +0 -0
- data/tracks/typescript/exercises/atbash-cipher/package.json +36 -0
- data/tracks/typescript/exercises/atbash-cipher/tsconfig.json +22 -0
- data/tracks/typescript/exercises/atbash-cipher/tslint.json +127 -0
- data/tracks/typescript/exercises/atbash-cipher/yarn.lock +2624 -0
- metadata +31 -2
@@ -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/
|
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
|
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
|
66
|
-
syntax means instance variable)
|
64
|
+
at least 100 characters in length.
|
67
65
|
|
68
|
-
If the key submitted
|
69
|
-
|
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
|
|
data/tracks/java/config.json
CHANGED
@@ -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
|
# House
|
2
2
|
|
3
|
-
|
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
|
-
|
1
|
+
# Isbn Verifier
|
2
2
|
|
3
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
21
|
-
|
22
|
-
(3 * 10 + 5 * 9 + 9 * 8 + 8 * 7 + 2 * 6 + 1 * 5 + 5 * 4 + 0 * 3 + 8 * 2 + 8 * 1) mod 11
|
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
|
29
|
-
|
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
|
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
|
-
-
|
11
|
-
-
|
12
|
-
-
|
13
|
-
-
|
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
|
-
|
16
|
-
|
17
|
-
|
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
|
22
|
-
|
23
|
-
|
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
|
+
}
|
File without changes
|
data/tracks/java/exercises/parallel-letter-frequency/src/test/java/ParallelLetterFrequencyTest.java
ADDED
@@ -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
|
+
}
|