Bläddra i källkod

Merge pull request #1 from exercism/master

Merge
Aaditya Arvind Kulkarni 6 år sedan
förälder
incheckning
da4c3dd4c1
No account linked to committer's email
100 ändrade filer med 2955 tillägg och 657 borttagningar
  1. 44
    9
      CONTRIBUTING.md
  2. 68
    3
      POLICIES.md
  3. 74
    8
      config.json
  4. 10
    10
      exercises/acronym/src/test/java/AcronymTest.java
  5. 1
    1
      exercises/all-your-base/.meta/version
  6. 40
    40
      exercises/all-your-base/src/test/java/BaseConverterTest.java
  7. 1
    0
      exercises/alphametics/.meta/version
  8. 1
    0
      exercises/binary-search-tree/.meta/version
  9. 25
    10
      exercises/binary-search-tree/src/test/java/BinarySearchTreeTest.java
  10. 1
    1
      exercises/book-store/.meta/version
  11. 1
    1
      exercises/bowling/.meta/version
  12. 30
    5
      exercises/bowling/src/test/java/BowlingTest.java
  13. 14
    14
      exercises/bracket-push/src/test/java/BracketCheckerTest.java
  14. 1
    1
      exercises/change/.meta/version
  15. 1
    1
      exercises/circular-buffer/.meta/version
  16. 1
    1
      exercises/clock/.meta/version
  17. 1
    1
      exercises/collatz-conjecture/.meta/version
  18. 1
    1
      exercises/complex-numbers/.meta/version
  19. 56
    48
      exercises/complex-numbers/src/test/java/ComplexNumberTest.java
  20. 1
    1
      exercises/crypto-square/.meta/version
  21. 4
    5
      exercises/crypto-square/README.md
  22. 1
    1
      exercises/custom-set/.meta/version
  23. 18
    18
      exercises/difference-of-squares/src/test/java/DifferenceOfSquaresCalculatorTest.java
  24. 5
    0
      exercises/dominoes/.meta/src/reference/java/ChainNotFoundException.java
  25. 30
    0
      exercises/dominoes/.meta/src/reference/java/Domino.java
  26. 67
    0
      exercises/dominoes/.meta/src/reference/java/Dominoes.java
  27. 2
    0
      exercises/dominoes/.meta/version
  28. 29
    0
      exercises/dominoes/README.md
  29. 18
    0
      exercises/dominoes/build.gradle
  30. 5
    0
      exercises/dominoes/src/main/java/ChainNotFoundException.java
  31. 30
    0
      exercises/dominoes/src/main/java/Domino.java
  32. 230
    0
      exercises/dominoes/src/test/java/DominoesTest.java
  33. 35
    0
      exercises/error-handling/.meta/hints.md
  34. 11
    0
      exercises/error-handling/.meta/src/reference/java/CustomCheckedException.java
  35. 11
    0
      exercises/error-handling/.meta/src/reference/java/CustomUncheckedException.java
  36. 63
    0
      exercises/error-handling/.meta/src/reference/java/ErrorHandling.java
  37. 62
    0
      exercises/error-handling/README.md
  38. 18
    0
      exercises/error-handling/build.gradle
  39. 11
    0
      exercises/error-handling/src/main/java/CustomCheckedException.java
  40. 11
    0
      exercises/error-handling/src/main/java/CustomUncheckedException.java
  41. 49
    0
      exercises/error-handling/src/main/java/ErrorHandling.java
  42. 116
    0
      exercises/error-handling/src/test/java/ErrorHandlingTest.java
  43. 1
    1
      exercises/flatten-array/.meta/version
  44. 1
    1
      exercises/forth/.meta/version
  45. 152
    0
      exercises/go-counting/.meta/src/reference/java/GoCounting.java
  46. 3
    0
      exercises/go-counting/.meta/src/reference/java/Player.java
  47. 2
    0
      exercises/go-counting/.meta/version
  48. 50
    0
      exercises/go-counting/README.md
  49. 18
    0
      exercises/go-counting/build.gradle
  50. 0
    0
      exercises/go-counting/src/main/java/.keep
  51. 3
    0
      exercises/go-counting/src/main/java/Player.java
  52. 178
    0
      exercises/go-counting/src/test/java/GoCountingTest.java
  53. 58
    0
      exercises/grep/.meta/hints.md
  54. 65
    0
      exercises/grep/.meta/src/reference/java/GrepTool.java
  55. 0
    0
      exercises/grep/.meta/version
  56. 145
    0
      exercises/grep/README.md
  57. 18
    0
      exercises/grep/build.gradle
  58. 0
    0
      exercises/grep/src/main/java/.keep
  59. 395
    0
      exercises/grep/src/test/java/GrepToolTest.java
  60. 2
    2
      exercises/house/.meta/src/reference/java/House.java
  61. 1
    1
      exercises/house/.meta/version
  62. 157
    172
      exercises/house/src/test/java/HouseTest.java
  63. 1
    1
      exercises/isogram/.meta/version
  64. 36
    36
      exercises/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java
  65. 1
    1
      exercises/list-ops/.meta/version
  66. 1
    1
      exercises/markdown/.meta/version
  67. 1
    1
      exercises/minesweeper/.meta/version
  68. 36
    36
      exercises/minesweeper/src/test/java/MinesweeperBoardTest.java
  69. 1
    1
      exercises/nth-prime/.meta/version
  70. 1
    1
      exercises/ocr-numbers/.meta/version
  71. 1
    1
      exercises/perfect-numbers/.meta/version
  72. 14
    14
      exercises/phone-number/src/test/java/PhoneNumberTest.java
  73. 4
    4
      exercises/pig-latin/README.md
  74. 5
    2
      exercises/poker/.meta/src/reference/java/Card.java
  75. 51
    12
      exercises/poker/.meta/src/reference/java/Hand.java
  76. 1
    0
      exercises/poker/.meta/version.txt
  77. 143
    66
      exercises/poker/src/test/java/PokerTest.java
  78. 10
    10
      exercises/pythagorean-triplet/src/test/java/PythagoreanTripletTest.java
  79. 0
    39
      exercises/queen-attack/.meta/src/reference/java/BoardCoordinate.java
  80. 38
    0
      exercises/queen-attack/.meta/src/reference/java/Queen.java
  81. 11
    12
      exercises/queen-attack/.meta/src/reference/java/QueenAttackCalculator.java
  82. 1
    1
      exercises/queen-attack/.meta/version
  83. 50
    44
      exercises/queen-attack/src/test/java/QueenAttackCalculatorTest.java
  84. 1
    1
      exercises/rectangles/.meta/version
  85. 9
    1
      exercises/rectangles/src/test/java/RectangleCounterTest.java
  86. 2
    0
      exercises/rna-transcription/.meta/hints.md
  87. 6
    0
      exercises/rna-transcription/README.md
  88. 1
    1
      exercises/robot-simulator/.meta/version
  89. 1
    1
      exercises/robot-simulator/src/test/java/RobotTest.java
  90. 1
    1
      exercises/roman-numerals/.meta/version
  91. 7
    0
      exercises/roman-numerals/src/test/java/RomanNumeralsTest.java
  92. 1
    1
      exercises/saddle-points/.meta/version
  93. 6
    6
      exercises/series/README.md
  94. 5
    0
      exercises/settings.gradle
  95. 5
    3
      exercises/sieve/README.md
  96. 1
    1
      exercises/sublist/.meta/version
  97. 1
    1
      exercises/tournament/.meta/version
  98. 53
    0
      exercises/variable-length-quantity/.meta/src/reference/java/VariableLengthQuantity.java
  99. 1
    0
      exercises/variable-length-quantity/.meta/version
  100. 0
    0
      exercises/variable-length-quantity/README.md

+ 44
- 9
CONTRIBUTING.md Visa fil

9
 * [Advanced: Complete Local Setup](#advanced-complete-local-setup)
9
 * [Advanced: Complete Local Setup](#advanced-complete-local-setup)
10
   * [Tip: `gradle clean` before `exercism fetch`](#tip-gradle-clean-before-exercism-fetch)
10
   * [Tip: `gradle clean` before `exercism fetch`](#tip-gradle-clean-before-exercism-fetch)
11
 * [Adding a New Exercise](#adding-a-new-exercise)
11
 * [Adding a New Exercise](#adding-a-new-exercise)
12
+* [Updating the READMEs](#updating-the-readmes)
13
+* [Checking tests are up to date](#checking-tests-are-up-to-date)
12
 
14
 
13
 ## Overview
15
 ## Overview
14
 
16
 
22
 
24
 
23
 Hi! Thanks for contributing to the Exercism Java track!
25
 Hi! Thanks for contributing to the Exercism Java track!
24
 
26
 
25
-Before opening your pull request, please review the track policies linked below and make sure your changes comply with them all. This helps us focus our review time on the more important aspects of your changes.
27
+Before opening your pull request, please review the [track policies](https://github.com/exercism/java/blob/master/POLICIES.md) and make sure your changes comply with them all. This helps us focus our review time on the more important aspects of your changes.
26
 
28
 
27
-- [Prefer instance methods](https://github.com/exercism/java/blob/master/POLICIES.md#prefer-instance-methods)
28
-- [Starter implementations](https://github.com/exercism/java/blob/master/POLICIES.md#starter-implementations)
29
-- [Ignore noninitial tests](https://github.com/exercism/java/blob/master/POLICIES.md#ignore-noninitial-tests)
30
-- [Multiple file submissions](https://github.com/exercism/java/blob/master/POLICIES.md#multiple-file-submissions)
29
+Also please only address one issue per pull request. This makes it easier for us to review it, and it means that if we request changes to the fix for one issue, it won't prevent to a fix for another issue being merged.
31
 
30
 
32
-One last thing to note before you get started. When you fork the repository and you want to sync your fork, you can perform a [`git rebase`](https://git-scm.com/docs/git-rebase). This is preferred over merging the changes because merging leads to a dirty commit history whereas performing a rebase adds in those changes without making extra commit messages. However, this is only preferred, so don't worry about it too much.
31
+It's perfectly fine to have more than one pull request open at a time. In that case it's important to keep the work for each pull request on a separate [branch](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell) to prevent unrelated commits being added to your pull request. This is good practice to do always, even if you only have one pull request open.
32
+
33
+One last thing to note before you get started. When you fork the repository and you want to [sync your fork](https://help.github.com/articles/syncing-a-fork/), you can perform a [`git rebase`](https://git-scm.com/docs/git-rebase). This is preferred over merging the changes because merging leads to a dirty commit history whereas performing a rebase adds in those changes without making extra commit messages. However, this is only preferred, so don't worry about it too much.
33
 
34
 
34
 ## Contributing With Minimal Setup
35
 ## Contributing With Minimal Setup
35
 
36
 
146
 
147
 
147
 There is a [general Exercism guide for porting an exercise to a new language](https://github.com/exercism/docs/blob/master/you-can-help/implement-an-exercise-from-specification.md).
148
 There is a [general Exercism guide for porting an exercise to a new language](https://github.com/exercism/docs/blob/master/you-can-help/implement-an-exercise-from-specification.md).
148
 Please review this before porting an exercise to the Java track.
149
 Please review this before porting an exercise to the Java track.
149
- 
150
+
150
 See [here](http://exercism.io/languages/java/todo) for a list of exercises that have yet to be implemented on the Java track and can therefore be ported to this track.
151
 See [here](http://exercism.io/languages/java/todo) for a list of exercises that have yet to be implemented on the Java track and can therefore be ported to this track.
151
 Please make sure no one else has a pull request open to implement your chosen exercise before you start.
152
 Please make sure no one else has a pull request open to implement your chosen exercise before you start.
152
-Also please make a [dibs pull request](https://github.com/exercism/docs/blob/master/you-can-help/implement-an-exercise-from-specification.md#avoiding-duplicate-work) to make it clear to others that you are working on this exercise.
153
+
154
+It might also be a good idea to open a WIP pull request to make it clear to others that you are working on this exercise.
155
+This can just be a pull request with an empty commit that states which new exercise you're working on, with WIP (work in progress) in the title so that the maintainers know that it's not ready for review yet.
153
 
156
 
154
 The Java specific details you need to know about adding an exercise are:
157
 The Java specific details you need to know about adding an exercise are:
155
 
158
 
167
 The `README.md` file can be generated using [configlet](https://github.com/exercism/configlet/releases).
170
 The `README.md` file can be generated using [configlet](https://github.com/exercism/configlet/releases).
168
 You can do this by:
171
 You can do this by:
169
 
172
 
170
-  1. Download configlet and put it somewhere in your PATH
173
+  1. Download configlet and put it somewhere in your [PATH](https://en.wikipedia.org/wiki/PATH_(variable))
171
 
174
 
172
   2. Clone [the problem-specifications repository](https://github.com/exercism/problem-specifications).
175
   2. Clone [the problem-specifications repository](https://github.com/exercism/problem-specifications).
173
 
176
 
181
 The canonical data version can be found at the top of the canonical data file for that exercise.
184
 The canonical data version can be found at the top of the canonical data file for that exercise.
182
 See other exercises, e.g. [acronym](https://github.com/exercism/java/tree/master/exercises/acronym/.meta), for an example `version` file.
185
 See other exercises, e.g. [acronym](https://github.com/exercism/java/tree/master/exercises/acronym/.meta), for an example `version` file.
183
 
186
 
187
+* Make sure you've followed the [track policies](https://github.com/exercism/java/blob/master/POLICIES.md), especially the ones for exercise added/updated.
188
+
184
 Hopefully that should be enough information to help you port an exercise to the Java track.
189
 Hopefully that should be enough information to help you port an exercise to the Java track.
185
 Feel free to open an issue or post in the [Gitter exercism/java room](https://gitter.im/exercism/java) if you have any questions and we'll try and answer as soon as we can.
190
 Feel free to open an issue or post in the [Gitter exercism/java room](https://gitter.im/exercism/java) if you have any questions and we'll try and answer as soon as we can.
191
+
192
+## Updating the READMEs
193
+
194
+The `README.md` files are generated from the exercise descriptions in [problem specifications](https://github.com/exercism/problem-specifications/tree/master/exercises).
195
+They need to be regenerated regularly so that any changes to the descriptions in problem specifications propagate to our READMEs.
196
+This can be done using [configlet](https://github.com/exercism/configlet/releases):
197
+
198
+  1. Download configlet and put it somewhere in your [PATH](https://en.wikipedia.org/wiki/PATH_(variable))
199
+
200
+  2. Clone [the problem-specifications repository](https://github.com/exercism/problem-specifications).
201
+
202
+  3. Run `configlet generate . --spec-path path_to_problem_specifications` from the root of this repository.
203
+
204
+## Checking tests are up to date
205
+
206
+The tests for each exercise should follow the canonical data in [problem specifications](https://github.com/exercism/problem-specifications/tree/master/exercises) as closely as possible.
207
+The canonical data can change quite regularly, in which case the [canonical data version](https://github.com/exercism/problem-specifications#test-data-versioning) for that exercise will be updated.
208
+
209
+We keep track of which version of the canonical data each exercise implements in a version file, for example: https://github.com/exercism/java/blob/master/exercises/two-fer/.meta/version.
210
+Not all exercises have canonical data in problem specifications.
211
+For those that don't we don't add a version file.
212
+
213
+We have [a script](https://github.com/exercism/java/blob/master/scripts/canonical_data_check.sh) which can check if these version are up to date with the ones in problem specification.
214
+This script can be used to check if any version files, tests and reference implementations need updating.
215
+
216
+To run this script:
217
+
218
+  1. Clone [the problem-specifications repository](https://github.com/exercism/problem-specifications).
219
+
220
+  2. Run `./scripts/canonical_data_check.sh -t . -s --spec-path path_to_problem_specifications` from the root of this repository.

+ 68
- 3
POLICIES.md Visa fil

17
 
17
 
18
 | Track Event | Policies to review |
18
 | Track Event | Policies to review |
19
 |:------------|:-----------------|
19
 |:------------|:-----------------|
20
-| Exercise added/updated | [Prefer instance methods](#prefer-instance-methods); [Avoid using final](#avoid-using-final); [Adhere to best practices](#adhere-to-best-practices); [Starter implementations](#starter-implementations); [Ignore noninitial tests](#ignore-noninitial-tests); [Multiple file submissions](#multiple-file-submissions); [Name test class after class under test](#name-test-class-after-class-under-test); [Add hint for the first exercises without starter implementation](#add-hint-for-the-first-exercises-without-starter-implementation)
20
+| Exercise added/updated | [Prefer instance methods](#prefer-instance-methods); [Avoid using final](#avoid-using-final); [Adhere to best practices](#adhere-to-best-practices); [Starter implementations](#starter-implementations); [Ignore noninitial tests](#ignore-noninitial-tests); [Multiple file submissions](#multiple-file-submissions); [Name test class after class under test](#name-test-class-after-class-under-test); [Add hint for the first exercises without starter implementation](#add-hint-for-the-first-exercises-without-starter-implementation); [Reference tutorial in the first exercises](#reference-tutorial-in-the-first-exercises); [Avoid returning null](#avoid-returning-null); [Use ExpectedException](#use-expectedexception)
21
 | Track rearranged | [Starter implementations](#starter-implementations); [Multiple file submissions](#multiple-file-submissions) |
21
 | Track rearranged | [Starter implementations](#starter-implementations); [Multiple file submissions](#multiple-file-submissions) |
22
 | New issue observed in track | [Good first patches](#good-first-patches) |
22
 | New issue observed in track | [Good first patches](#good-first-patches) |
23
 | "Good first patch" issue completed | [Good first patches](#good-first-patches) |
23
 | "Good first patch" issue completed | [Good first patches](#good-first-patches) |
46
 ### Adhere to best practices
46
 ### Adhere to best practices
47
 
47
 
48
 > Ensure that all Java code adheres to the best practices listed below:
48
 > Ensure that all Java code adheres to the best practices listed below:
49
-> - minimize the accessibility of classes and members ([Effective Java, item 13](http://jtechies.blogspot.com/2012/07/item-13-minimize-accessibility-of.html))
49
+> - Minimize the accessibility of classes and members ([Effective Java, item 13](http://jtechies.blogspot.com/2012/07/item-13-minimize-accessibility-of.html))
50
+> - Always use curly brackest in if statements. This makes your code easier to maintain and easier to read ([Oracle style guide, item 7.4](http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-142311.html#431))
51
+```java
52
+// Please do this
53
+if (condition) {
54
+    doSomething();
55
+}
56
+
57
+// Please don't do this
58
+if (condition)
59
+    doSomething();
60
+
61
+if (condition) doSomething();
62
+```
63
+> - Always put opening curly bracket not on a newline ([Oracle style guide, item 7.2](http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-142311.html#431))
64
+```java
65
+// Please do this
66
+for (int i = 0; i < 10; i++) {
67
+    ...
68
+}
69
+
70
+// Please don't do this
71
+for (int i = 0; i < 10; i++)
72
+{
73
+    ...
74
+}
75
+```
50
 
76
 
51
 ### Ignore noninitial tests
77
 ### Ignore noninitial tests
52
 
78
 
74
 
100
 
75
 ### Name test class after class under test
101
 ### Name test class after class under test
76
 
102
 
77
-> If you're testing a class called `SomeClassName` then your test class should be called `SomeClassNameTest`. 
103
+> If you're testing a class called `SomeClassName` then your test class should be called `SomeClassNameTest`.
78
 
104
 
79
 > The exception to this is if the tests are split into several test classes where each test class tests different functionality. In that case each class should be named `SomeClassNameFunctionalityTest` where `Functionality` is the name of the functionality to be tested in that class. See the [clock exercise](https://github.com/exercism/java/tree/master/exercises/clock) as an example.
105
 > The exception to this is if the tests are split into several test classes where each test class tests different functionality. In that case each class should be named `SomeClassNameFunctionalityTest` where `Functionality` is the name of the functionality to be tested in that class. See the [clock exercise](https://github.com/exercism/java/tree/master/exercises/clock) as an example.
80
 
106
 
93
 > We add the file to every exercise with difficulty 5 because the structure of the track means that we don't know which exercise will be the first one without starter implementation that a user will be faced with.
119
 > We add the file to every exercise with difficulty 5 because the structure of the track means that we don't know which exercise will be the first one without starter implementation that a user will be faced with.
94
 
120
 
95
 References: [[1](https://github.com/exercism/java/issues/1075)]
121
 References: [[1](https://github.com/exercism/java/issues/1075)]
122
+
123
+### Reference tutorial in the first exercises
124
+
125
+> The hello world exercise has an extensive tutorial on how to solve exercism exercises.
126
+> This tutorial would probably be useful to have as a reference when solving some of the other earlier exercises as well.
127
+> Therefore any exercise with difficulty less than 3 should have a hints.md file which references [the hello world tutorial](https://github.com/exercism/java/blob/master/exercises/hello-world/TUTORIAL.md).
128
+
129
+References: [[1](https://github.com/exercism/java/issues/1389)]
130
+
131
+### Avoid returning null
132
+
133
+> The [canonical data](https://github.com/exercism/problem-specifications/tree/master/exercises) for each exercise intentionally doesn't deal with error handling.
134
+> When an error has occured or a method can't return anything, the canonical data will just mark that as `"expected": null`.
135
+> This is because error handling varies from language to language, so the canonical data is leaving it up to each language track to decide how to deal with those situations.
136
+> It doesn't mean that the method needs to return `null`.
137
+
138
+> In Java it's considered bad practice to return `null`.
139
+> If you return `null` then the user of the method has to remember to check for `null` and they have to look at the implementation of the method to find out that this is necessary.
140
+
141
+> It's considered best practice to deal with errors and unexpected circumstances by throwing exceptions.
142
+> If you throw an exception then you force the user to deal with the problem.
143
+> You can either define your own exception (see [the triangle exercise](https://github.com/exercism/java/blob/master/exercises/triangle/.meta/src/reference/java/TriangleException.java) for an example) or use a predefined one (see [the collatz-conjecture exercise](https://github.com/exercism/java/blob/master/exercises/collatz-conjecture/src/test/java/CollatzCalculatorTest.java) for an example).
144
+
145
+> Another option is to use [Optionals](https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html).
146
+> This can be more suitable if the case you want to deal with isn't an exceptional occurence, but rather an expected scenario, e.g. a search method not finding what it was searching for.
147
+> See [the word-search exercise](https://github.com/exercism/java/blob/master/exercises/word-search/src/test/java/WordSearcherTest.java) for an example where `Optional` is used.
148
+
149
+References: [[1](https://www.codebyamir.com/blog/stop-returning-null-in-java)]
150
+
151
+### Use ExceptedException
152
+
153
+> Some exercises expect exceptions to be thrown in the tests.
154
+> The exercises on this track are all using JUnit's [`ExpectedException`](http://junit.org/junit4/javadoc/4.12/org/junit/rules/ExpectedException.html) `@Rule` feature to support that instead of `@Test(expected = SomeException.class)`.
155
+> `ExpectedException` is more powerful than using the `@Test` annotation, since with `ExpectedException` you can also inspect the exception's error message and other properties.
156
+> To be consistent, please use `ExpectedException` whenever you expect an exception to be thrown.
157
+
158
+> See [the triangle tests](https://github.com/exercism/java/blob/master/exercises/triangle/src/test/java/TriangleTest.java) for an example of where `ExpectedException` is used.
159
+
160
+References: [[1](https://github.com/junit-team/junit4/wiki/Exception-testing)]

+ 74
- 8
config.json Visa fil

197
         "loops",
197
         "loops",
198
         "strings"
198
         "strings"
199
       ],
199
       ],
200
-      "unlocked_by": "rna-transcription",
200
+      "unlocked_by": "two-fer",
201
       "uuid": "331073b3-bd1a-4868-b767-a64ce9fd9d97"
201
       "uuid": "331073b3-bd1a-4868-b767-a64ce9fd9d97"
202
     },
202
     },
203
     {
203
     {
398
     {
398
     {
399
       "core": false,
399
       "core": false,
400
       "difficulty": 4,
400
       "difficulty": 4,
401
+      "slug": "error-handling",
402
+      "topics": [
403
+        "exception_handling",
404
+        "optional_values"
405
+      ],
406
+      "unlocked_by": "triangle",
407
+      "uuid": "846ae792-7ca7-43e1-b523-bb1ec9fa08eb"
408
+    },
409
+    {
410
+      "core": false,
411
+      "difficulty": 4,
401
       "slug": "diamond",
412
       "slug": "diamond",
402
       "topics": [
413
       "topics": [
403
         "arrays",
414
         "arrays",
423
       "uuid": "c3e89c7c-3a8a-4ddc-b653-9b0ff9e1d7d8"
434
       "uuid": "c3e89c7c-3a8a-4ddc-b653-9b0ff9e1d7d8"
424
     },
435
     },
425
     {
436
     {
437
+      "core": false,
438
+      "difficulty": 4,
439
+      "slug": "variable-length-quantity",
440
+      "topics": [
441
+        "bitwise_operations",
442
+        "conditionals",
443
+        "exception_handling",
444
+        "lists",
445
+        "loops",
446
+        "transforming"
447
+      ],
448
+      "unlocked_by": "secret-handshake",
449
+      "uuid": "d8a2c7ba-2040-4cfe-ab15-f90b3b61dd89"
450
+    },
451
+    {
426
       "core": true,
452
       "core": true,
427
       "difficulty": 5,
453
       "difficulty": 5,
428
       "slug": "flatten-array",
454
       "slug": "flatten-array",
615
     {
641
     {
616
       "core": false,
642
       "core": false,
617
       "difficulty": 5,
643
       "difficulty": 5,
618
-      "slug": "two-bucket",
644
+      "slug": "grep",
619
       "topics": [
645
       "topics": [
620
-        "algorithms",
621
-        "loops",
622
-        "conditionals",
623
-        "mathematics"
646
+        "pattern_matching",
647
+        "strings",
648
+        "files",
649
+        "filtering",
650
+        "searching"
624
       ],
651
       ],
625
-      "unlocked_by": "triangle",
626
-      "uuid": "210bf628-b385-443b-8329-3483cc6e8d7e"
652
+      "unlocked_by": "robot-name",
653
+      "uuid": "9c15ddab-7b52-43d4-b38c-0bf635b363c3"
627
     },
654
     },
628
     {
655
     {
629
       "core": false,
656
       "core": false,
914
     {
941
     {
915
       "core": false,
942
       "core": false,
916
       "difficulty": 7,
943
       "difficulty": 7,
944
+      "slug": "two-bucket",
945
+      "topics": [
946
+        "algorithms",
947
+        "loops",
948
+        "conditionals",
949
+        "mathematics"
950
+      ],
951
+      "unlocked_by": "triangle",
952
+      "uuid": "210bf628-b385-443b-8329-3483cc6e8d7e"
953
+    },
954
+    {
955
+      "core": false,
956
+      "difficulty": 7,
917
       "slug": "anagram",
957
       "slug": "anagram",
918
       "topics": [
958
       "topics": [
919
         "arrays",
959
         "arrays",
1065
     },
1105
     },
1066
     {
1106
     {
1067
       "core": false,
1107
       "core": false,
1108
+      "difficulty": 7,
1109
+      "slug": "go-counting",
1110
+      "topics": [
1111
+        "algorithms",
1112
+        "loops",
1113
+        "conditionals",
1114
+        "games"
1115
+      ],
1116
+      "unlocked_by": "scrabble-score",
1117
+      "uuid": "2e760ae2-fadd-4d31-9639-c4554e2826e9"
1118
+    },
1119
+    {
1120
+      "core": false,
1121
+      "difficulty": 7,
1122
+      "slug": "dominoes",
1123
+      "topics": [
1124
+        "games",
1125
+        "algorithms",
1126
+        "lists",
1127
+        "exception_handling"
1128
+      ],
1129
+      "unlocked_by": "scrabble-score",
1130
+      "uuid": "8e3cb20e-623b-4b4d-8a91-d1a51c0911b5"
1131
+    },
1132
+    {
1133
+      "core": false,
1068
       "difficulty": 8,
1134
       "difficulty": 8,
1069
       "slug": "ocr-numbers",
1135
       "slug": "ocr-numbers",
1070
       "topics": [
1136
       "topics": [

+ 10
- 10
exercises/acronym/src/test/java/AcronymTest.java Visa fil

7
 
7
 
8
     @Test
8
     @Test
9
     public void basic() {
9
     public void basic() {
10
-        final String phrase = "Portable Network Graphics";
11
-        final String expected = "PNG";
10
+        String phrase = "Portable Network Graphics";
11
+        String expected = "PNG";
12
         assertEquals(expected, new Acronym(phrase).get());
12
         assertEquals(expected, new Acronym(phrase).get());
13
     }
13
     }
14
 
14
 
15
     @Ignore("Remove to run test")
15
     @Ignore("Remove to run test")
16
     @Test
16
     @Test
17
     public void lowercaseWords() {
17
     public void lowercaseWords() {
18
-        final String phrase = "Ruby on Rails";
19
-        final String expected = "ROR";
18
+        String phrase = "Ruby on Rails";
19
+        String expected = "ROR";
20
         assertEquals(expected, new Acronym(phrase).get());
20
         assertEquals(expected, new Acronym(phrase).get());
21
     }
21
     }
22
 
22
 
23
     @Ignore("Remove to run test")
23
     @Ignore("Remove to run test")
24
     @Test
24
     @Test
25
     public void punctuation() {
25
     public void punctuation() {
26
-        final String phrase = "First In, First Out";
27
-        final String expected = "FIFO";
26
+        String phrase = "First In, First Out";
27
+        String expected = "FIFO";
28
         assertEquals(expected, new Acronym(phrase).get());
28
         assertEquals(expected, new Acronym(phrase).get());
29
     }
29
     }
30
 
30
 
31
     @Ignore("Remove to run test")
31
     @Ignore("Remove to run test")
32
     @Test
32
     @Test
33
     public void NonAcronymAllCapsWord() {
33
     public void NonAcronymAllCapsWord() {
34
-        final String phrase = "GNU Image Manipulation Program";
35
-        final String expected = "GIMP";
34
+        String phrase = "GNU Image Manipulation Program";
35
+        String expected = "GIMP";
36
         assertEquals(expected, new Acronym(phrase).get());
36
         assertEquals(expected, new Acronym(phrase).get());
37
     }
37
     }
38
 
38
 
39
     @Ignore("Remove to run test")
39
     @Ignore("Remove to run test")
40
     @Test
40
     @Test
41
     public void punctuationWithoutWhitespace() {
41
     public void punctuationWithoutWhitespace() {
42
-        final String phrase = "Complementary metal-oxide semiconductor";
43
-        final String expected = "CMOS";
42
+        String phrase = "Complementary metal-oxide semiconductor";
43
+        String expected = "CMOS";
44
         assertEquals(expected, new Acronym(phrase).get());
44
         assertEquals(expected, new Acronym(phrase).get());
45
     }
45
     }
46
 
46
 

+ 1
- 1
exercises/all-your-base/.meta/version Visa fil

1
-2.1.0
1
+2.3.0

+ 40
- 40
exercises/all-your-base/src/test/java/BaseConverterTest.java Visa fil

14
 
14
 
15
     @Test
15
     @Test
16
     public void testSingleBitOneToDecimal() {
16
     public void testSingleBitOneToDecimal() {
17
-        final BaseConverter baseConverter = new BaseConverter(2, new int[]{1});
17
+         BaseConverter baseConverter = new BaseConverter(2, new int[]{1});
18
 
18
 
19
-        final int[] expectedDigits = new int[]{1};
20
-        final int[] actualDigits = baseConverter.convertToBase(10);
19
+         int[] expectedDigits = new int[]{1};
20
+         int[] actualDigits = baseConverter.convertToBase(10);
21
 
21
 
22
         assertArrayEquals(
22
         assertArrayEquals(
23
                 String.format(
23
                 String.format(
31
     @Ignore("Remove to run test")
31
     @Ignore("Remove to run test")
32
     @Test
32
     @Test
33
     public void testBinaryToSingleDecimal() {
33
     public void testBinaryToSingleDecimal() {
34
-        final BaseConverter baseConverter = new BaseConverter(2, new int[]{1, 0, 1});
34
+         BaseConverter baseConverter = new BaseConverter(2, new int[]{1, 0, 1});
35
 
35
 
36
-        final int[] expectedDigits = new int[]{5};
37
-        final int[] actualDigits = baseConverter.convertToBase(10);
36
+         int[] expectedDigits = new int[]{5};
37
+         int[] actualDigits = baseConverter.convertToBase(10);
38
 
38
 
39
         assertArrayEquals(
39
         assertArrayEquals(
40
                 String.format(
40
                 String.format(
48
     @Ignore("Remove to run test")
48
     @Ignore("Remove to run test")
49
     @Test
49
     @Test
50
     public void testSingleDecimalToBinary() {
50
     public void testSingleDecimalToBinary() {
51
-        final BaseConverter baseConverter = new BaseConverter(10, new int[]{5});
51
+         BaseConverter baseConverter = new BaseConverter(10, new int[]{5});
52
 
52
 
53
-        final int[] expectedDigits = new int[]{1, 0, 1};
54
-        final int[] actualDigits = baseConverter.convertToBase(2);
53
+         int[] expectedDigits = new int[]{1, 0, 1};
54
+         int[] actualDigits = baseConverter.convertToBase(2);
55
 
55
 
56
         assertArrayEquals(
56
         assertArrayEquals(
57
                 String.format(
57
                 String.format(
65
     @Ignore("Remove to run test")
65
     @Ignore("Remove to run test")
66
     @Test
66
     @Test
67
     public void testBinaryToMultipleDecimal() {
67
     public void testBinaryToMultipleDecimal() {
68
-        final BaseConverter baseConverter = new BaseConverter(2, new int[]{1, 0, 1, 0, 1, 0});
68
+         BaseConverter baseConverter = new BaseConverter(2, new int[]{1, 0, 1, 0, 1, 0});
69
 
69
 
70
-        final int[] expectedDigits = new int[]{4, 2};
71
-        final int[] actualDigits = baseConverter.convertToBase(10);
70
+         int[] expectedDigits = new int[]{4, 2};
71
+         int[] actualDigits = baseConverter.convertToBase(10);
72
 
72
 
73
         assertArrayEquals(
73
         assertArrayEquals(
74
                 String.format(
74
                 String.format(
82
     @Ignore("Remove to run test")
82
     @Ignore("Remove to run test")
83
     @Test
83
     @Test
84
     public void testDecimalToBinary() {
84
     public void testDecimalToBinary() {
85
-        final BaseConverter baseConverter = new BaseConverter(10, new int[]{4, 2});
85
+         BaseConverter baseConverter = new BaseConverter(10, new int[]{4, 2});
86
 
86
 
87
-        final int[] expectedDigits = new int[]{1, 0, 1, 0, 1, 0};
88
-        final int[] actualDigits = baseConverter.convertToBase(2);
87
+         int[] expectedDigits = new int[]{1, 0, 1, 0, 1, 0};
88
+         int[] actualDigits = baseConverter.convertToBase(2);
89
 
89
 
90
         assertArrayEquals(
90
         assertArrayEquals(
91
                 String.format(
91
                 String.format(
99
     @Ignore("Remove to run test")
99
     @Ignore("Remove to run test")
100
     @Test
100
     @Test
101
     public void testTrinaryToHexadecimal() {
101
     public void testTrinaryToHexadecimal() {
102
-        final BaseConverter baseConverter = new BaseConverter(3, new int[]{1, 1, 2, 0});
102
+         BaseConverter baseConverter = new BaseConverter(3, new int[]{1, 1, 2, 0});
103
 
103
 
104
-        final int[] expectedDigits = new int[]{2, 10};
105
-        final int[] actualDigits = baseConverter.convertToBase(16);
104
+         int[] expectedDigits = new int[]{2, 10};
105
+         int[] actualDigits = baseConverter.convertToBase(16);
106
 
106
 
107
         assertArrayEquals(
107
         assertArrayEquals(
108
                 String.format(
108
                 String.format(
116
     @Ignore("Remove to run test")
116
     @Ignore("Remove to run test")
117
     @Test
117
     @Test
118
     public void testHexadecimalToTrinary() {
118
     public void testHexadecimalToTrinary() {
119
-        final BaseConverter baseConverter = new BaseConverter(16, new int[]{2, 10});
119
+         BaseConverter baseConverter = new BaseConverter(16, new int[]{2, 10});
120
 
120
 
121
-        final int[] expectedDigits = new int[]{1, 1, 2, 0};
122
-        final int[] actualDigits = baseConverter.convertToBase(3);
121
+         int[] expectedDigits = new int[]{1, 1, 2, 0};
122
+         int[] actualDigits = baseConverter.convertToBase(3);
123
 
123
 
124
         assertArrayEquals(
124
         assertArrayEquals(
125
                 String.format(
125
                 String.format(
133
     @Ignore("Remove to run test")
133
     @Ignore("Remove to run test")
134
     @Test
134
     @Test
135
     public void test15BitInteger() {
135
     public void test15BitInteger() {
136
-        final BaseConverter baseConverter = new BaseConverter(97, new int[]{3, 46, 60});
136
+         BaseConverter baseConverter = new BaseConverter(97, new int[]{3, 46, 60});
137
 
137
 
138
-        final int[] expectedDigits = new int[]{6, 10, 45};
139
-        final int[] actualDigits = baseConverter.convertToBase(73);
138
+         int[] expectedDigits = new int[]{6, 10, 45};
139
+         int[] actualDigits = baseConverter.convertToBase(73);
140
 
140
 
141
         assertArrayEquals(
141
         assertArrayEquals(
142
                 String.format(
142
                 String.format(
150
     @Ignore("Remove to run test")
150
     @Ignore("Remove to run test")
151
     @Test
151
     @Test
152
     public void testEmptyDigits() {
152
     public void testEmptyDigits() {
153
-        final BaseConverter baseConverter = new BaseConverter(2, new int[]{});
153
+         BaseConverter baseConverter = new BaseConverter(2, new int[]{});
154
 
154
 
155
-        final int[] expectedDigits = new int[]{0};
156
-        final int[] actualDigits = baseConverter.convertToBase(10);
155
+         int[] expectedDigits = new int[]{0};
156
+         int[] actualDigits = baseConverter.convertToBase(10);
157
 
157
 
158
         assertArrayEquals(
158
         assertArrayEquals(
159
             String.format(
159
             String.format(
167
     @Ignore("Remove to run test")
167
     @Ignore("Remove to run test")
168
     @Test
168
     @Test
169
     public void testSingleZero() {
169
     public void testSingleZero() {
170
-        final BaseConverter baseConverter = new BaseConverter(10, new int[]{0});
170
+         BaseConverter baseConverter = new BaseConverter(10, new int[]{0});
171
 
171
 
172
-        final int[] expectedDigits = new int[]{0};
173
-        final int[] actualDigits = baseConverter.convertToBase(2);
172
+         int[] expectedDigits = new int[]{0};
173
+         int[] actualDigits = baseConverter.convertToBase(2);
174
 
174
 
175
         assertArrayEquals(
175
         assertArrayEquals(
176
                 String.format(
176
                 String.format(
184
     @Ignore("Remove to run test")
184
     @Ignore("Remove to run test")
185
     @Test
185
     @Test
186
     public void testMultipleZeros() {
186
     public void testMultipleZeros() {
187
-        final BaseConverter baseConverter = new BaseConverter(10, new int[]{0, 0, 0});
187
+         BaseConverter baseConverter = new BaseConverter(10, new int[]{0, 0, 0});
188
 
188
 
189
-        final int[] expectedDigits = new int[]{0};
190
-        final int[] actualDigits = baseConverter.convertToBase(2);
189
+         int[] expectedDigits = new int[]{0};
190
+         int[] actualDigits = baseConverter.convertToBase(2);
191
 
191
 
192
         assertArrayEquals(
192
         assertArrayEquals(
193
             String.format(
193
             String.format(
201
     @Ignore("Remove to run test")
201
     @Ignore("Remove to run test")
202
     @Test
202
     @Test
203
     public void testLeadingZeros() {
203
     public void testLeadingZeros() {
204
-        final BaseConverter baseConverter = new BaseConverter(7, new int[]{0, 6, 0});
204
+         BaseConverter baseConverter = new BaseConverter(7, new int[]{0, 6, 0});
205
 
205
 
206
-        final int[] expectedDigits = new int[]{4, 2};
207
-        final int[] actualDigits = baseConverter.convertToBase(10);
206
+         int[] expectedDigits = new int[]{4, 2};
207
+         int[] actualDigits = baseConverter.convertToBase(10);
208
 
208
 
209
         assertArrayEquals(
209
         assertArrayEquals(
210
             String.format(
210
             String.format(
221
         expectedException.expect(IllegalArgumentException.class);
221
         expectedException.expect(IllegalArgumentException.class);
222
         expectedException.expectMessage("Bases must be at least 2.");
222
         expectedException.expectMessage("Bases must be at least 2.");
223
 
223
 
224
-        new BaseConverter(1, new int[]{});
224
+        new BaseConverter(1, new int[]{1});
225
     }
225
     }
226
 
226
 
227
     @Ignore("Remove to run test")
227
     @Ignore("Remove to run test")
263
     @Ignore("Remove to run test")
263
     @Ignore("Remove to run test")
264
     @Test
264
     @Test
265
     public void testSecondBaseIsOne() {
265
     public void testSecondBaseIsOne() {
266
-        final BaseConverter baseConverter = new BaseConverter(2, new int[]{1, 0, 1, 0, 1, 0});
266
+         BaseConverter baseConverter = new BaseConverter(2, new int[]{1, 0, 1, 0, 1, 0});
267
 
267
 
268
         expectedException.expect(IllegalArgumentException.class);
268
         expectedException.expect(IllegalArgumentException.class);
269
         expectedException.expectMessage("Bases must be at least 2.");
269
         expectedException.expectMessage("Bases must be at least 2.");
274
     @Ignore("Remove to run test")
274
     @Ignore("Remove to run test")
275
     @Test
275
     @Test
276
     public void testSecondBaseIsZero() {
276
     public void testSecondBaseIsZero() {
277
-        final BaseConverter baseConverter = new BaseConverter(10, new int[]{7});
277
+         BaseConverter baseConverter = new BaseConverter(10, new int[]{7});
278
 
278
 
279
         expectedException.expect(IllegalArgumentException.class);
279
         expectedException.expect(IllegalArgumentException.class);
280
         expectedException.expectMessage("Bases must be at least 2.");
280
         expectedException.expectMessage("Bases must be at least 2.");
285
     @Ignore("Remove to run test")
285
     @Ignore("Remove to run test")
286
     @Test
286
     @Test
287
     public void testSecondBaseIsNegative() {
287
     public void testSecondBaseIsNegative() {
288
-        final BaseConverter baseConverter = new BaseConverter(2, new int[]{1});
288
+         BaseConverter baseConverter = new BaseConverter(2, new int[]{1});
289
 
289
 
290
         expectedException.expect(IllegalArgumentException.class);
290
         expectedException.expect(IllegalArgumentException.class);
291
         expectedException.expectMessage("Bases must be at least 2.");
291
         expectedException.expectMessage("Bases must be at least 2.");

+ 1
- 0
exercises/alphametics/.meta/version Visa fil

1
+1.2.0

+ 1
- 0
exercises/binary-search-tree/.meta/version Visa fil

1
+1.0.0

+ 25
- 10
exercises/binary-search-tree/src/test/java/BinarySearchTreeTest.java Visa fil

95
         );
95
         );
96
 
96
 
97
         List<Character> treeData = Collections.unmodifiableList(
97
         List<Character> treeData = Collections.unmodifiableList(
98
-                Arrays.asList('4', '2', '6', '1', '3', '7', '5')
98
+                Arrays.asList('4', '2', '6', '1', '3', '5', '7')
99
         );
99
         );
100
         treeData.forEach(binarySearchTree::insert);
100
         treeData.forEach(binarySearchTree::insert);
101
 
101
 
108
     public void sortsSingleElement() {
108
     public void sortsSingleElement() {
109
         BinarySearchTree<String> binarySearchTree = new BinarySearchTree<>();
109
         BinarySearchTree<String> binarySearchTree = new BinarySearchTree<>();
110
         List<String> expected = Collections.unmodifiableList(
110
         List<String> expected = Collections.unmodifiableList(
111
-                Collections.singletonList("4")
111
+                Collections.singletonList("2")
112
         );
112
         );
113
 
113
 
114
-        binarySearchTree.insert("4");
114
+        binarySearchTree.insert("2");
115
 
115
 
116
         List<String> actual = binarySearchTree.getAsSortedList();
116
         List<String> actual = binarySearchTree.getAsSortedList();
117
         assertEquals(expected, actual);
117
         assertEquals(expected, actual);
122
     public void sortsCollectionOfTwoIfSecondInsertedIsSmallerThanFirst() {
122
     public void sortsCollectionOfTwoIfSecondInsertedIsSmallerThanFirst() {
123
         BinarySearchTree<Integer> binarySearchTree = new BinarySearchTree<>();
123
         BinarySearchTree<Integer> binarySearchTree = new BinarySearchTree<>();
124
         List<Integer> expected = Collections.unmodifiableList(
124
         List<Integer> expected = Collections.unmodifiableList(
125
-                Arrays.asList(2, 4)
125
+                Arrays.asList(1, 2)
126
         );
126
         );
127
 
127
 
128
-        binarySearchTree.insert(4);
129
         binarySearchTree.insert(2);
128
         binarySearchTree.insert(2);
129
+        binarySearchTree.insert(1);
130
 
130
 
131
         List<Integer> actual = binarySearchTree.getAsSortedList();
131
         List<Integer> actual = binarySearchTree.getAsSortedList();
132
         assertEquals(expected, actual);
132
         assertEquals(expected, actual);
133
     }
133
     }
134
+    
135
+    @Ignore("Remove to run test")
136
+    @Test
137
+    public void sortsCollectionOfTwoIfSecondNumberisSameAsFirst() {
138
+        BinarySearchTree<Character> binarySearchTree = new BinarySearchTree<>();
139
+        List<Character> expected = Collections.unmodifiableList(
140
+                Arrays.asList('2', '2')
141
+        );
142
+
143
+        binarySearchTree.insert('2');
144
+        binarySearchTree.insert('2');
145
+
146
+        List<Character> actual = binarySearchTree.getAsSortedList();
147
+        assertEquals(expected, actual);
148
+    }
134
 
149
 
135
     @Ignore("Remove to run test")
150
     @Ignore("Remove to run test")
136
     @Test
151
     @Test
137
     public void sortsCollectionOfTwoIfSecondInsertedIsBiggerThanFirst() {
152
     public void sortsCollectionOfTwoIfSecondInsertedIsBiggerThanFirst() {
138
         BinarySearchTree<Character> binarySearchTree = new BinarySearchTree<>();
153
         BinarySearchTree<Character> binarySearchTree = new BinarySearchTree<>();
139
         List<Character> expected = Collections.unmodifiableList(
154
         List<Character> expected = Collections.unmodifiableList(
140
-                Arrays.asList('4', '5')
155
+                Arrays.asList('2', '3')
141
         );
156
         );
142
 
157
 
143
-        binarySearchTree.insert('4');
144
-        binarySearchTree.insert('5');
158
+        binarySearchTree.insert('2');
159
+        binarySearchTree.insert('3');
145
 
160
 
146
         List<Character> actual = binarySearchTree.getAsSortedList();
161
         List<Character> actual = binarySearchTree.getAsSortedList();
147
         assertEquals(expected, actual);
162
         assertEquals(expected, actual);
152
     public void iteratesOverComplexTree() {
167
     public void iteratesOverComplexTree() {
153
         BinarySearchTree<String> binarySearchTree = new BinarySearchTree<>();
168
         BinarySearchTree<String> binarySearchTree = new BinarySearchTree<>();
154
         List<String> expected = Collections.unmodifiableList(
169
         List<String> expected = Collections.unmodifiableList(
155
-                Arrays.asList("1", "2", "3", "4", "5", "6", "7")
170
+                Arrays.asList("1", "2", "3", "5", "6", "7")
156
         );
171
         );
157
 
172
 
158
         List<String> treeData = Collections.unmodifiableList(
173
         List<String> treeData = Collections.unmodifiableList(
159
-                Arrays.asList("4", "2", "1", "3", "6", "7", "5")
174
+                Arrays.asList("2", "1", "3", "6", "7", "5")
160
         );
175
         );
161
         treeData.forEach(binarySearchTree::insert);
176
         treeData.forEach(binarySearchTree::insert);
162
 
177
 

+ 1
- 1
exercises/book-store/.meta/version Visa fil

1
-1.2.0
1
+1.3.0

+ 1
- 1
exercises/bowling/.meta/version Visa fil

1
-1.1.0
1
+1.2.0

+ 30
- 5
exercises/bowling/src/test/java/BowlingTest.java Visa fil

199
 
199
 
200
         game.score();
200
         game.score();
201
     }
201
     }
202
-    
202
+
203
     @Ignore("Remove to run test")
203
     @Ignore("Remove to run test")
204
     @Test
204
     @Test
205
     public void twoBonusRollsAfterAStrikeInTheLastFrameCanNotScoreMoreThan10Points() {
205
     public void twoBonusRollsAfterAStrikeInTheLastFrameCanNotScoreMoreThan10Points() {
222
 
222
 
223
         assertEquals(26, game.score());
223
         assertEquals(26, game.score());
224
     }
224
     }
225
-    
225
+
226
     @Ignore("Remove to run test")
226
     @Ignore("Remove to run test")
227
     @Test
227
     @Test
228
     public void theSecondBonusRollsAfterAStrikeInTheLastFrameCanNotBeAStrikeIfTheFirstOneIsNotAStrike() {
228
     public void theSecondBonusRollsAfterAStrikeInTheLastFrameCanNotBeAStrikeIfTheFirstOneIsNotAStrike() {
235
 
235
 
236
         game.score();
236
         game.score();
237
     }
237
     }
238
-    
238
+
239
     @Ignore("Remove to run test")
239
     @Ignore("Remove to run test")
240
     @Test
240
     @Test
241
     public void secondBonusRollAfterAStrikeInTheLastFrameCanNotScoreMoreThan10Points() {
241
     public void secondBonusRollAfterAStrikeInTheLastFrameCanNotScoreMoreThan10Points() {
248
 
248
 
249
         game.score();
249
         game.score();
250
     }
250
     }
251
-    
251
+
252
     @Ignore("Remove to run test")
252
     @Ignore("Remove to run test")
253
     @Test
253
     @Test
254
     public void anUnstartedGameCanNotBeScored() {
254
     public void anUnstartedGameCanNotBeScored() {
327
         game.score();
327
         game.score();
328
     }
328
     }
329
 
329
 
330
-}
330
+    @Ignore("Remove to run test")
331
+    @Test
332
+    public void canNotRollAfterBonusRollForSpare() {
333
+        int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 3, 2, 2};
334
+
335
+        playGame(rolls);
336
+
337
+        expectedException.expect(IllegalStateException.class);
338
+        expectedException.expectMessage("Cannot roll after game is over");
339
+
340
+        game.score();
341
+    }
342
+
343
+    @Ignore("Remove to run test")
344
+    @Test
345
+    public void canNotRollAfterBonusRollForStrike() {
346
+        int[] rolls = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 3, 2, 2};
347
+
348
+        playGame(rolls);
349
+
350
+        expectedException.expect(IllegalStateException.class);
351
+        expectedException.expectMessage("Cannot roll after game is over");
352
+
353
+        game.score();
354
+    }
355
+}

+ 14
- 14
exercises/bracket-push/src/test/java/BracketCheckerTest.java Visa fil

8
 
8
 
9
     @Test
9
     @Test
10
     public void testPairedSquareBrackets() {
10
     public void testPairedSquareBrackets() {
11
-        final BracketChecker bracketChecker = new BracketChecker("[]");
11
+        BracketChecker bracketChecker = new BracketChecker("[]");
12
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
12
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
13
     }
13
     }
14
 
14
 
15
     @Ignore("Remove to run test")
15
     @Ignore("Remove to run test")
16
     @Test
16
     @Test
17
     public void testEmptyString() {
17
     public void testEmptyString() {
18
-        final BracketChecker bracketChecker = new BracketChecker("");
18
+        BracketChecker bracketChecker = new BracketChecker("");
19
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
19
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
20
     }
20
     }
21
 
21
 
22
     @Ignore("Remove to run test")
22
     @Ignore("Remove to run test")
23
     @Test
23
     @Test
24
     public void testUnpairedBrackets() {
24
     public void testUnpairedBrackets() {
25
-        final BracketChecker bracketChecker = new BracketChecker("[[");
25
+        BracketChecker bracketChecker = new BracketChecker("[[");
26
         assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
26
         assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
27
     }
27
     }
28
 
28
 
29
     @Ignore("Remove to run test")
29
     @Ignore("Remove to run test")
30
     @Test
30
     @Test
31
     public void testIncorrectlyOrderedBrackets() {
31
     public void testIncorrectlyOrderedBrackets() {
32
-        final BracketChecker bracketChecker = new BracketChecker("}{");
32
+        BracketChecker bracketChecker = new BracketChecker("}{");
33
         assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
33
         assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
34
     }
34
     }
35
 
35
 
36
     @Ignore("Remove to run test")
36
     @Ignore("Remove to run test")
37
     @Test
37
     @Test
38
     public void testSingleOpenBracketWithIncorrectClosingBracket() {
38
     public void testSingleOpenBracketWithIncorrectClosingBracket() {
39
-        final BracketChecker bracketChecker = new BracketChecker("{]");
39
+        BracketChecker bracketChecker = new BracketChecker("{]");
40
         assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
40
         assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
41
     }
41
     }
42
 
42
 
43
     @Ignore("Remove to run test")
43
     @Ignore("Remove to run test")
44
     @Test
44
     @Test
45
     public void testPairedBracketsWithWhitespace() {
45
     public void testPairedBracketsWithWhitespace() {
46
-        final BracketChecker bracketChecker = new BracketChecker("{ }");
46
+        BracketChecker bracketChecker = new BracketChecker("{ }");
47
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
47
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
48
     }
48
     }
49
 
49
 
50
     @Ignore("Remove to run test")
50
     @Ignore("Remove to run test")
51
     @Test
51
     @Test
52
     public void testSimpleNestedBrackets() {
52
     public void testSimpleNestedBrackets() {
53
-        final BracketChecker bracketChecker = new BracketChecker("{[]}");
53
+        BracketChecker bracketChecker = new BracketChecker("{[]}");
54
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
54
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
55
     }
55
     }
56
 
56
 
57
     @Ignore("Remove to run test")
57
     @Ignore("Remove to run test")
58
     @Test
58
     @Test
59
     public void testSeveralPairedBrackets() {
59
     public void testSeveralPairedBrackets() {
60
-        final BracketChecker bracketChecker = new BracketChecker("{}[]");
60
+        BracketChecker bracketChecker = new BracketChecker("{}[]");
61
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
61
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
62
     }
62
     }
63
 
63
 
64
     @Ignore("Remove to run test")
64
     @Ignore("Remove to run test")
65
     @Test
65
     @Test
66
     public void testPairedAndNestedBrackets() {
66
     public void testPairedAndNestedBrackets() {
67
-        final BracketChecker bracketChecker = new BracketChecker("([{}({}[])])");
67
+        BracketChecker bracketChecker = new BracketChecker("([{}({}[])])");
68
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
68
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
69
     }
69
     }
70
 
70
 
71
     @Ignore("Remove to run test")
71
     @Ignore("Remove to run test")
72
     @Test
72
     @Test
73
     public void testUnopenedClosingBracket() {
73
     public void testUnopenedClosingBracket() {
74
-        final BracketChecker bracketChecker = new BracketChecker("{[)][]}");
74
+        BracketChecker bracketChecker = new BracketChecker("{[)][]}");
75
         assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
75
         assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
76
     }
76
     }
77
 
77
 
78
     @Ignore("Remove to run test")
78
     @Ignore("Remove to run test")
79
     @Test
79
     @Test
80
     public void testUnpairedAndNestedBracket() {
80
     public void testUnpairedAndNestedBracket() {
81
-        final BracketChecker bracketChecker = new BracketChecker("([{])");
81
+        BracketChecker bracketChecker = new BracketChecker("([{])");
82
         assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
82
         assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
83
     }
83
     }
84
 
84
 
85
     @Ignore("Remove to run test")
85
     @Ignore("Remove to run test")
86
     @Test
86
     @Test
87
     public void testPairedAndIncorrectlyNestedBrackets() {
87
     public void testPairedAndIncorrectlyNestedBrackets() {
88
-        final BracketChecker bracketChecker = new BracketChecker("[({]})");
88
+        BracketChecker bracketChecker = new BracketChecker("[({]})");
89
         assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
89
         assertFalse(bracketChecker.areBracketsMatchedAndNestedCorrectly());
90
     }
90
     }
91
 
91
 
92
     @Ignore("Remove to run test")
92
     @Ignore("Remove to run test")
93
     @Test
93
     @Test
94
     public void testValidMathExpression() {
94
     public void testValidMathExpression() {
95
-        final BracketChecker bracketChecker = new BracketChecker("(((185 + 223.85) * 15) - 543)/2");
95
+        BracketChecker bracketChecker = new BracketChecker("(((185 + 223.85) * 15) - 543)/2");
96
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
96
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
97
     }
97
     }
98
 
98
 
99
     @Ignore("Remove to run test")
99
     @Ignore("Remove to run test")
100
     @Test
100
     @Test
101
     public void testValidComplexLaTeXExpression() {
101
     public void testValidComplexLaTeXExpression() {
102
-        final BracketChecker bracketChecker = new BracketChecker(
102
+        BracketChecker bracketChecker = new BracketChecker(
103
                 "\\left(\\begin{array}{cc} \\frac{1}{3} & x\\\\ \\mathrm{e}^{x} &... x^2 \\end{array}\\right)");
103
                 "\\left(\\begin{array}{cc} \\frac{1}{3} & x\\\\ \\mathrm{e}^{x} &... x^2 \\end{array}\\right)");
104
 
104
 
105
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());
105
         assertTrue(bracketChecker.areBracketsMatchedAndNestedCorrectly());

+ 1
- 1
exercises/change/.meta/version Visa fil

1
-1.1.0
1
+1.2.0

+ 1
- 1
exercises/circular-buffer/.meta/version Visa fil

1
-1.0.1
1
+1.1.0

+ 1
- 1
exercises/clock/.meta/version Visa fil

1
-1.0.1
1
+2.2.1

+ 1
- 1
exercises/collatz-conjecture/.meta/version Visa fil

1
-1.1.1
1
+1.2.0

+ 1
- 1
exercises/complex-numbers/.meta/version Visa fil

1
-1.0.0
1
+1.3.0

+ 56
- 48
exercises/complex-numbers/src/test/java/ComplexNumberTest.java Visa fil

23
     // Tests
23
     // Tests
24
 
24
 
25
     @Test
25
     @Test
26
+    public void testRealPartOfPurelyRealNumber() {
27
+        double expected = 1.0;
28
+        double actual = new ComplexNumber(1.0, 0).getReal();
29
+        assertDoublesEqual(expected, actual, "real");
30
+    }
31
+
32
+    @Ignore("Remove to run test")
33
+    @Test
34
+    public void testRealPartOfPurelyImaginaryNumber() {
35
+        double expected = 0.0;
36
+        double actual = new ComplexNumber(0, 1.0).getReal();
37
+        assertDoublesEqual(expected, actual, "real");
38
+    }
39
+
40
+    @Ignore("Remove to run test")
41
+    @Test
42
+    public void testRealPartOfNumberWithRealAndImaginaryParts() {
43
+        double expected = 1.0;
44
+        double actual = new ComplexNumber(1.0, 2.0).getReal();
45
+        assertDoublesEqual(expected, actual, "real");
46
+    }
47
+
48
+    @Ignore("Remove to run test")
49
+    @Test
50
+    public void testImaginaryPartOfPurelyRealNumber() {
51
+        double expected = 0.0;
52
+        double actual = new ComplexNumber(1.0, 0).getImag();
53
+        assertDoublesEqual(expected, actual, "imaginary");
54
+    }
55
+
56
+    @Ignore("Remove to run test")
57
+    @Test
58
+    public void testImaginaryPartOfPurelyImaginaryNumber() {
59
+        double expected = 1.0;
60
+        double actual = new ComplexNumber(0, 1.0).getImag();
61
+        assertDoublesEqual(expected, actual, "imaginary");
62
+    }
63
+
64
+    @Ignore("Remove to run test")
65
+    @Test
66
+    public void testImaginaryPartOfNumberWithRealAndImaginaryParts() {
67
+        double expected = 2.0;
68
+        double actual = new ComplexNumber(1.0, 2.0).getImag();
69
+        assertDoublesEqual(expected, actual, "imaginary");
70
+    }
71
+
72
+    @Ignore("Remove to run test")
73
+    @Test
26
     public void testImaginaryUnitExhibitsDefiningProperty() {
74
     public void testImaginaryUnitExhibitsDefiningProperty() {
27
         ComplexNumber expected = new ComplexNumber(-1.0, 0);
75
         ComplexNumber expected = new ComplexNumber(-1.0, 0);
28
         ComplexNumber actual = new ComplexNumber(0, 1.0).times(new ComplexNumber(0, 1.0));
76
         ComplexNumber actual = new ComplexNumber(0, 1.0).times(new ComplexNumber(0, 1.0));
191
 
239
 
192
     @Ignore("Remove to run test")
240
     @Ignore("Remove to run test")
193
     @Test
241
     @Test
194
-    public void testRealPartOfPurelyRealNumber() {
195
-        double expected = 1.0;
196
-        double actual = new ComplexNumber(1.0, 0).getReal();
197
-        assertDoublesEqual(expected, actual, "real");
198
-    }
199
-
200
-    @Ignore("Remove to run test")
201
-    @Test
202
-    public void testRealPartOfPurelyImaginaryNumber() {
203
-        double expected = 0.0;
204
-        double actual = new ComplexNumber(0, 1.0).getReal();
205
-        assertDoublesEqual(expected, actual, "real");
206
-    }
207
-
208
-    @Ignore("Remove to run test")
209
-    @Test
210
-    public void testRealPartOfNumberWithRealAndImaginaryParts() {
211
-        double expected = 1.0;
212
-        double actual = new ComplexNumber(1.0, 2.0).getReal();
213
-        assertDoublesEqual(expected, actual, "real");
214
-    }
215
-
216
-    @Ignore("Remove to run test")
217
-    @Test
218
-    public void testImaginaryPartOfPurelyRealNumber() {
219
-        double expected = 0.0;
220
-        double actual = new ComplexNumber(1.0, 0).getImag();
221
-        assertDoublesEqual(expected, actual, "imaginary");
222
-    }
223
-
224
-    @Ignore("Remove to run test")
225
-    @Test
226
-    public void testImaginaryPartOfPurelyImaginaryNumber() {
227
-        double expected = 1.0;
228
-        double actual = new ComplexNumber(0, 1.0).getImag();
229
-        assertDoublesEqual(expected, actual, "imaginary");
230
-    }
231
-
232
-    @Ignore("Remove to run test")
233
-    @Test
234
-    public void testImaginaryPartOfNumberWithRealAndImaginaryParts() {
235
-        double expected = 2.0;
236
-        double actual = new ComplexNumber(1.0, 2.0).getImag();
237
-        assertDoublesEqual(expected, actual, "imaginary");
238
-    }
239
-
240
-    @Ignore("Remove to run test")
241
-    @Test
242
     public void testExponentialOfPurelyImaginaryNumber() {
242
     public void testExponentialOfPurelyImaginaryNumber() {
243
         ComplexNumber expected = new ComplexNumber(-1.0, 0);
243
         ComplexNumber expected = new ComplexNumber(-1.0, 0);
244
         ComplexNumber actual = new ComplexNumber(0, Math.PI).exponentialOf();
244
         ComplexNumber actual = new ComplexNumber(0, Math.PI).exponentialOf();
261
         assertComplexNumbersEqual(expected, actual);
261
         assertComplexNumbersEqual(expected, actual);
262
     }
262
     }
263
 
263
 
264
+    @Ignore("Remove to run test")
265
+    @Test
266
+    public void testExponentialOfNumberWithRealAndImaginaryParts() {
267
+        ComplexNumber expected = new ComplexNumber(-2.0, 0);
268
+        ComplexNumber actual = new ComplexNumber(Math.log(2.0), Math.PI).exponentialOf();
269
+        assertComplexNumbersEqual(expected, actual);
270
+    }
271
+
264
 }
272
 }

+ 1
- 1
exercises/crypto-square/.meta/version Visa fil

1
-3.1.0
1
+3.2.0

+ 4
- 5
exercises/crypto-square/README.md Visa fil

45
 imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau
45
 imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau
46
 ```
46
 ```
47
 
47
 
48
-Output the encoded text in chunks.  Phrases that fill perfect rectangles
49
-`(r X c)` should be output `c` chunks of `r` length, separated by spaces.
50
-Phrases that do not fill perfect rectangles will have `n` empty spaces.
51
-Those spaces should be distributed evenly, added to the end of the last
52
-`n` chunks.
48
+Output the encoded text in chunks that fill perfect rectangles `(r X c)`,
49
+with `c` chunks of `r` length, separated by spaces. For phrases that are
50
+`n` characters short of the perfect rectangle, pad each of the last `n`
51
+chunks with a single trailing space.
53
 
52
 
54
 ```text
53
 ```text
55
 imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn  sseoau 
54
 imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn  sseoau 

+ 1
- 1
exercises/custom-set/.meta/version Visa fil

1
-1.1.0
1
+1.3.0

+ 18
- 18
exercises/difference-of-squares/src/test/java/DifferenceOfSquaresCalculatorTest.java Visa fil

15
 
15
 
16
     @Test
16
     @Test
17
     public void testSquareOfSumUpToOne() {
17
     public void testSquareOfSumUpToOne() {
18
-        final int expected = 1;
19
-        final int actual = calculator.computeSquareOfSumTo(1);
18
+        int expected = 1;
19
+        int actual = calculator.computeSquareOfSumTo(1);
20
         assertEquals(expected, actual);
20
         assertEquals(expected, actual);
21
     }
21
     }
22
 
22
 
23
     @Ignore("Remove to run test")
23
     @Ignore("Remove to run test")
24
     @Test
24
     @Test
25
     public void testSquareOfSumUpToFive() {
25
     public void testSquareOfSumUpToFive() {
26
-        final int expected = 225;
27
-        final int actual = calculator.computeSquareOfSumTo(5);
26
+        int expected = 225;
27
+        int actual = calculator.computeSquareOfSumTo(5);
28
         assertEquals(expected, actual);
28
         assertEquals(expected, actual);
29
     }
29
     }
30
 
30
 
31
     @Ignore("Remove to run test")
31
     @Ignore("Remove to run test")
32
     @Test
32
     @Test
33
     public void testSquareOfSumUpToHundred() {
33
     public void testSquareOfSumUpToHundred() {
34
-        final int expected = 25502500;
35
-        final int actual = calculator.computeSquareOfSumTo(100);
34
+        int expected = 25502500;
35
+        int actual = calculator.computeSquareOfSumTo(100);
36
         assertEquals(expected, actual);
36
         assertEquals(expected, actual);
37
     }
37
     }
38
 
38
 
39
     @Ignore("Remove to run test")
39
     @Ignore("Remove to run test")
40
     @Test
40
     @Test
41
     public void testSumOfSquaresUpToOne() {
41
     public void testSumOfSquaresUpToOne() {
42
-        final int expected = 1;
43
-        final int actual = calculator.computeSumOfSquaresTo(1);
42
+        int expected = 1;
43
+        int actual = calculator.computeSumOfSquaresTo(1);
44
         assertEquals(expected, actual);
44
         assertEquals(expected, actual);
45
     }
45
     }
46
 
46
 
47
     @Ignore("Remove to run test")
47
     @Ignore("Remove to run test")
48
     @Test
48
     @Test
49
     public void testSumOfSquaresUpToFive() {
49
     public void testSumOfSquaresUpToFive() {
50
-        final int expected = 55;
51
-        final int actual = calculator.computeSumOfSquaresTo(5);
50
+        int expected = 55;
51
+        int actual = calculator.computeSumOfSquaresTo(5);
52
         assertEquals(expected, actual);
52
         assertEquals(expected, actual);
53
     }
53
     }
54
 
54
 
55
     @Ignore("Remove to run test")
55
     @Ignore("Remove to run test")
56
     @Test
56
     @Test
57
     public void testSumOfSquaresUpToHundred() {
57
     public void testSumOfSquaresUpToHundred() {
58
-        final int expected = 338350;
59
-        final int actual = calculator.computeSumOfSquaresTo(100);
58
+        int expected = 338350;
59
+        int actual = calculator.computeSumOfSquaresTo(100);
60
         assertEquals(expected, actual);
60
         assertEquals(expected, actual);
61
     }
61
     }
62
 
62
 
63
     @Ignore("Remove to run test")
63
     @Ignore("Remove to run test")
64
     @Test
64
     @Test
65
     public void testDifferenceOfSquaresUpToOne() {
65
     public void testDifferenceOfSquaresUpToOne() {
66
-        final int expected = 0;
67
-        final int actual = calculator.computeDifferenceOfSquares(1);
66
+        int expected = 0;
67
+        int actual = calculator.computeDifferenceOfSquares(1);
68
         assertEquals(expected, actual);
68
         assertEquals(expected, actual);
69
     }
69
     }
70
 
70
 
71
     @Ignore("Remove to run test")
71
     @Ignore("Remove to run test")
72
     @Test
72
     @Test
73
     public void testDifferenceOfSquaresUpToFive() {
73
     public void testDifferenceOfSquaresUpToFive() {
74
-        final int expected = 170;
75
-        final int actual = calculator.computeDifferenceOfSquares(5);
74
+        int expected = 170;
75
+        int actual = calculator.computeDifferenceOfSquares(5);
76
         assertEquals(expected, actual);
76
         assertEquals(expected, actual);
77
     }
77
     }
78
 
78
 
79
     @Ignore("Remove to run test")
79
     @Ignore("Remove to run test")
80
     @Test
80
     @Test
81
     public void testDifferenceOfSquaresUpToHundred() {
81
     public void testDifferenceOfSquaresUpToHundred() {
82
-        final int expected = 25164150;
83
-        final int actual = calculator.computeDifferenceOfSquares(100);
82
+        int expected = 25164150;
83
+        int actual = calculator.computeDifferenceOfSquares(100);
84
         assertEquals(expected, actual);
84
         assertEquals(expected, actual);
85
     }
85
     }
86
 
86
 

+ 5
- 0
exercises/dominoes/.meta/src/reference/java/ChainNotFoundException.java Visa fil

1
+class ChainNotFoundException extends Exception {
2
+	public ChainNotFoundException(String message) {
3
+		super(message);
4
+	}
5
+}

+ 30
- 0
exercises/dominoes/.meta/src/reference/java/Domino.java Visa fil

1
+import java.util.Objects;
2
+
3
+class Domino {
4
+    private int left;
5
+    private int right;
6
+    Domino(int left, int right) {
7
+        this.left = left;
8
+        this.right = right;
9
+    }
10
+    
11
+    int getLeft() {
12
+    	return this.left;
13
+    }
14
+    
15
+    int getRight() {
16
+    	return this.right;
17
+    }
18
+    
19
+    @Override
20
+    public boolean equals(Object o) {
21
+    	Domino otherDomino = (Domino) o;
22
+    	return (this.getLeft() == otherDomino.getLeft() && this.getRight() == otherDomino.getRight()) ||
23
+    			(this.getLeft() == otherDomino.getRight() && this.getRight() == otherDomino.getLeft());
24
+    }
25
+    
26
+    @Override
27
+    public int hashCode() {
28
+    	return Objects.hash(left, right);
29
+    }
30
+}

+ 67
- 0
exercises/dominoes/.meta/src/reference/java/Dominoes.java Visa fil

1
+import java.util.ArrayList;
2
+import java.util.Arrays;
3
+import java.util.List;
4
+
5
+class Dominoes {
6
+	
7
+	List<Domino> formChain(List<Domino> inputDominoes) throws ChainNotFoundException {
8
+		if (inputDominoes.size() == 0) {
9
+			return inputDominoes;
10
+		} else {
11
+			return formPartialChain(new ArrayList<Domino>(), inputDominoes);
12
+		}
13
+	}
14
+	
15
+	private boolean isValidChain(ArrayList<Domino> chain) {
16
+		return isValidPartialChain(chain) && (chain.get(0).getLeft() == chain.get(chain.size() - 1).getRight());
17
+	}
18
+	
19
+	private boolean isValidPartialChain(ArrayList<Domino> chain) {
20
+		for (int i = 0; i < chain.size() - 1; i++) {
21
+			if (chain.get(i).getRight() != chain.get(i+1).getLeft()) {
22
+				return false;
23
+			}
24
+		}
25
+		
26
+		return true;
27
+	}
28
+	
29
+	ArrayList<Domino> formPartialChain(ArrayList<Domino> current, List<Domino> remaining) throws ChainNotFoundException {
30
+		if (remaining.size() == 0) {
31
+			if (isValidChain(current)) {
32
+				return current;
33
+			} else {
34
+				throw new ChainNotFoundException("No domino chain found.");
35
+			}
36
+		}
37
+		
38
+		for (int i = 0; i < remaining.size(); i++) {
39
+			ArrayList<Domino> newRemaining = new ArrayList<Domino>(remaining);
40
+			newRemaining.remove(i);
41
+			
42
+			ArrayList<Domino> newChainA = new ArrayList<Domino>(current);
43
+			newChainA.add(remaining.get(i));
44
+			
45
+			ArrayList<Domino> newChainB = new ArrayList<Domino>(current);
46
+			newChainB.add(new Domino(remaining.get(i).getRight(), remaining.get(i).getLeft()));
47
+			
48
+			if (isValidPartialChain(newChainA)) {
49
+				try {
50
+					return formPartialChain(newChainA, newRemaining);
51
+				} catch (ChainNotFoundException e) {
52
+					//This path does not have a valid chain
53
+				}
54
+			}
55
+			
56
+			if (isValidPartialChain(newChainB)) {
57
+				try {
58
+					return formPartialChain(newChainB, newRemaining);
59
+				} catch (ChainNotFoundException e) {
60
+					//This path doesn't have a valid chain
61
+				}
62
+			}
63
+		}
64
+		
65
+		throw new ChainNotFoundException("No domino chain found.");
66
+	}
67
+}

+ 2
- 0
exercises/dominoes/.meta/version Visa fil

1
+2.1.0
2
+

+ 29
- 0
exercises/dominoes/README.md Visa fil

1
+# Dominoes
2
+
3
+Make a chain of dominoes.
4
+
5
+Compute a way to order a given set of dominoes in such a way that they form a
6
+correct domino chain (the dots on one half of a stone match the dots on the
7
+neighbouring half of an adjacent stone) and that dots on the halfs of the stones
8
+which don't have a neighbour (the first and last stone) match each other.
9
+
10
+For example given the stones `[2|1]`, `[2|3]` and `[1|3]` you should compute something
11
+like `[1|2] [2|3] [3|1]` or `[3|2] [2|1] [1|3]` or `[1|3] [3|2] [2|1]` etc, where the first and last numbers are the same.
12
+
13
+For stones `[1|2]`, `[4|1]` and `[2|3]` the resulting chain is not valid: `[4|1] [1|2] [2|3]`'s first and last numbers are not the same. 4 != 3
14
+
15
+Some test cases may use duplicate stones in a chain solution, assume that multiple Domino sets are being used.
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
+## Submitting Incomplete Solutions
28
+
29
+It's possible to submit an incomplete solution so you can see how others have completed the exercise.

+ 18
- 0
exercises/dominoes/build.gradle Visa fil

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
+}

+ 5
- 0
exercises/dominoes/src/main/java/ChainNotFoundException.java Visa fil

1
+class ChainNotFoundException extends Exception {
2
+	public ChainNotFoundException(String message) {
3
+		super(message);
4
+	}
5
+}

+ 30
- 0
exercises/dominoes/src/main/java/Domino.java Visa fil

1
+import java.util.Objects;
2
+
3
+class Domino {
4
+    private int left;
5
+    private int right;
6
+    Domino(int left, int right) {
7
+        this.left = left;
8
+        this.right = right;
9
+    }
10
+    
11
+    int getLeft() {
12
+    	return this.left;
13
+    }
14
+    
15
+    int getRight() {
16
+    	return this.right;
17
+    }
18
+    
19
+    @Override
20
+    public boolean equals(Object o) {
21
+    	Domino otherDomino = (Domino) o;
22
+    	return (this.getLeft() == otherDomino.getLeft() && this.getRight() == otherDomino.getRight()) ||
23
+    			(this.getLeft() == otherDomino.getRight() && this.getRight() == otherDomino.getLeft());
24
+    }
25
+    
26
+    @Override
27
+    public int hashCode() {
28
+    	return Objects.hash(left, right);
29
+    }
30
+}

+ 230
- 0
exercises/dominoes/src/test/java/DominoesTest.java Visa fil

1
+import org.junit.Ignore;
2
+import org.junit.Test;
3
+
4
+import java.util.List;
5
+import java.util.ArrayList;
6
+import java.util.Arrays;
7
+import java.util.Collections;
8
+
9
+import static org.junit.Assert.assertEquals;
10
+import static org.junit.Assert.assertNull;
11
+
12
+import org.junit.Rule;
13
+import org.junit.rules.ExpectedException;
14
+
15
+public class DominoesTest {
16
+	
17
+	@Rule
18
+	public ExpectedException expectedException = ExpectedException.none(); 
19
+	
20
+	@Test
21
+	public void emtpyInputEmptyOutputTest() throws ChainNotFoundException {
22
+		Dominoes dominoes = new Dominoes();
23
+		
24
+		List<Domino> dominoesList = new ArrayList<>();
25
+		
26
+		List<Domino> chain = dominoes.formChain(dominoesList);
27
+		
28
+		assertEquals("The output list should be empty.", 0, chain.size());
29
+	}
30
+	
31
+	@Ignore("Remove to run test")
32
+	@Test
33
+	public void singletonInputSingletonOutput() throws ChainNotFoundException {
34
+		Dominoes dominoes = new Dominoes();
35
+		
36
+		Domino[] dominoesArray = {new Domino(1, 1)};
37
+		List<Domino> dominoesList = Arrays.asList(dominoesArray);
38
+		
39
+		List<Domino> chain = dominoes.formChain(dominoesList);
40
+		
41
+		assertValidChain(dominoesList, chain);
42
+	}
43
+	
44
+	@Ignore("Remove to run test")
45
+	@Test
46
+	public void singletonCantBeChainedTest() throws ChainNotFoundException {
47
+		Dominoes dominoes = new Dominoes();
48
+		
49
+		Domino[] dominoesArray = {new Domino(1, 2)};
50
+		List<Domino> dominoesList = Arrays.asList(dominoesArray);
51
+		
52
+		expectedException.expect(ChainNotFoundException.class);
53
+		expectedException.expectMessage("No domino chain found.");
54
+		
55
+		dominoes.formChain(dominoesList);
56
+	}
57
+	
58
+	@Ignore("Remove to run test")
59
+	@Test
60
+	public void threeElementsTest() throws ChainNotFoundException {
61
+		Dominoes dominoes = new Dominoes();
62
+		
63
+		Domino[] dominoesArray = {new Domino(1, 2), new Domino(3, 1), new Domino(2, 3)};
64
+		List<Domino> dominoesList = Arrays.asList(dominoesArray);
65
+		
66
+		List<Domino> chain = dominoes.formChain(dominoesList);
67
+		
68
+		assertValidChain(dominoesList, chain);
69
+	}
70
+	
71
+	@Ignore("Remove to run test")
72
+	@Test
73
+	public void canReverseDominoesTest() throws ChainNotFoundException {
74
+		Dominoes dominoes = new Dominoes();
75
+		
76
+		Domino[] dominoesArray = {new Domino(1, 2), new Domino(1, 3), new Domino(2, 3)};
77
+		List<Domino> dominoesList = Arrays.asList(dominoesArray);
78
+		
79
+		List<Domino> chain = dominoes.formChain(dominoesList);
80
+		
81
+		assertValidChain(dominoesList, chain);
82
+	}
83
+	
84
+	@Ignore("Remove to run test")
85
+	@Test
86
+	public void cantBeChainedTest() throws ChainNotFoundException {
87
+		Dominoes dominoes = new Dominoes();
88
+		
89
+		Domino[] dominoesArray = {new Domino(1, 2), new Domino(4, 1), new Domino(2, 3)};
90
+		List<Domino> dominoesList = Arrays.asList(dominoesArray);
91
+		
92
+		expectedException.expect(ChainNotFoundException.class);
93
+		expectedException.expectMessage("No domino chain found.");
94
+		
95
+		dominoes.formChain(dominoesList);
96
+	}
97
+	
98
+	@Ignore("Remove to run test")
99
+	@Test
100
+	public void disconnectedSimpleTest() throws ChainNotFoundException {
101
+		Dominoes dominoes = new Dominoes();
102
+		
103
+		Domino[] dominoesArray = {new Domino(1, 1), new Domino(2, 2)};
104
+		List<Domino> dominoesList = Arrays.asList(dominoesArray);
105
+		
106
+		expectedException.expect(ChainNotFoundException.class);
107
+		expectedException.expectMessage("No domino chain found.");
108
+		
109
+		dominoes.formChain(dominoesList);
110
+	}
111
+	
112
+	@Ignore("Remove to run test")
113
+	@Test
114
+	public void disconnectedDoubleLoopTest() throws ChainNotFoundException {
115
+		Dominoes dominoes = new Dominoes();
116
+		
117
+		Domino[] dominoesArray = {new Domino(1, 2), new Domino(2, 1), new Domino(3, 4), new Domino(4, 3)};
118
+		List<Domino> dominoesList = Arrays.asList(dominoesArray);
119
+		
120
+		expectedException.expect(ChainNotFoundException.class);
121
+		expectedException.expectMessage("No domino chain found.");
122
+		
123
+		dominoes.formChain(dominoesList);
124
+	}
125
+	
126
+	@Ignore("Remove to run test")
127
+	@Test
128
+	public void disconnectedSingleIsolatedTest() throws ChainNotFoundException {
129
+		Dominoes dominoes = new Dominoes();
130
+		
131
+		Domino[] dominoesArray = {new Domino(1, 2), new Domino(2, 3), new Domino(3, 1), new Domino(4, 4)};
132
+		List<Domino> dominoesList = Arrays.asList(dominoesArray);
133
+		
134
+		expectedException.expect(ChainNotFoundException.class);
135
+		expectedException.expectMessage("No domino chain found.");
136
+		
137
+		dominoes.formChain(dominoesList);
138
+	}
139
+	
140
+	@Ignore("Remove to run test")
141
+	@Test
142
+	public void needBacktrackTest() throws ChainNotFoundException {
143
+		Dominoes dominoes = new Dominoes();
144
+		
145
+		Domino[] dominoesArray = {new Domino(1, 2), new Domino(2, 3), new Domino(3, 1), new Domino(2, 4), new Domino(4, 2)};
146
+		List<Domino> dominoesList = Arrays.asList(dominoesArray);
147
+		
148
+		List<Domino> chain = dominoes.formChain(dominoesList);
149
+		
150
+		assertValidChain(dominoesList, chain);
151
+	}
152
+	
153
+	@Ignore("Remove to run test")
154
+	@Test
155
+	public void separateLoopsTest() throws ChainNotFoundException {
156
+		Dominoes dominoes = new Dominoes();
157
+		
158
+		Domino[] dominoesArray = {new Domino(1, 2), new Domino(2, 3), new Domino(3, 1),
159
+				new Domino(1, 1), new Domino(2, 2), new Domino(3, 3)};
160
+		List<Domino> dominoesList = Arrays.asList(dominoesArray);
161
+		
162
+		List<Domino> chain = dominoes.formChain(dominoesList);
163
+		
164
+		assertValidChain(dominoesList, chain);
165
+	}
166
+	
167
+	@Ignore("Remove to run test")
168
+	@Test
169
+	public void nineElementsTest() throws ChainNotFoundException {
170
+		Dominoes dominoes = new Dominoes();
171
+		Domino[] dominoesArray = {new Domino(1, 2), new Domino(5, 3), new Domino(3, 1),
172
+				new Domino(1, 2), new Domino(2, 4), new Domino(1, 6),
173
+				new Domino(2, 3), new Domino(3, 4), new Domino(5, 6)};
174
+		List<Domino> dominoesList = Arrays.asList(dominoesArray);
175
+		
176
+		List<Domino> chain = dominoes.formChain(dominoesList);
177
+		
178
+		assertValidChain(dominoesList, chain);
179
+	}
180
+	
181
+	private void assertValidChain(List<Domino> inputDominoes, List<Domino> outputDominoes) {
182
+		assertSameDominoes(inputDominoes, outputDominoes);
183
+		assertEndDominoesMatch(outputDominoes);
184
+		assertConsecutiveDominoes(outputDominoes);
185
+	}
186
+	
187
+	private void assertEndDominoesMatch(List<Domino> outputDominoes) {
188
+		int leftValueOfFirstDomino = outputDominoes.get(0).getLeft();
189
+		int rightValueOfLastDomino = outputDominoes.get(outputDominoes.size() - 1).getRight();
190
+		String errorMessage = "The left value of the first domino ("
191
+		    + leftValueOfFirstDomino
192
+		    + ") needs to match the right value of the last domino ("
193
+		    + rightValueOfLastDomino
194
+		    + ").";
195
+		
196
+		assertEquals(errorMessage, leftValueOfFirstDomino, rightValueOfLastDomino);
197
+	}
198
+	
199
+	private void assertSameDominoes(List<Domino> inputDominoes, List<Domino> outputDominoes) {
200
+		String errorMessage = "The number of dominoes in the input list (" + inputDominoes.size()
201
+				+ ") needs to match the number of dominoes in the output chain (" + outputDominoes.size() + ")";
202
+		
203
+		assertEquals(errorMessage, inputDominoes.size(), outputDominoes.size());
204
+		
205
+		for (Domino domino : inputDominoes) {
206
+			int inputFrequency = Collections.frequency(inputDominoes, domino);
207
+			int outputFrequency = Collections.frequency(outputDominoes, domino);
208
+			
209
+			String frequencyErrorMessage = "The frequency of domino (" + domino.getLeft() + ", " + domino.getRight() + ")"
210
+					+ " in the input is (" + inputFrequency + "), but (" + outputFrequency + ") in the output.";
211
+					
212
+			assertEquals(frequencyErrorMessage, inputFrequency, outputFrequency);
213
+		}
214
+	}
215
+	
216
+	private void assertConsecutiveDominoes(List<Domino> dominoes) {
217
+		for (int i = 0; i < dominoes.size() - 1; i++) {
218
+			
219
+			int rightValueOfIthDomino = dominoes.get(i).getRight();
220
+			int leftValueOfNextDomino = dominoes.get(i+1).getLeft();
221
+			String errorMessage = "The right value of domino number " + i + " ("
222
+			    + rightValueOfIthDomino
223
+			    + ") needs to match the left value of domino number " + (i+1) + " ("
224
+			    + leftValueOfNextDomino
225
+			    + ").";
226
+			
227
+			assertEquals(errorMessage, dominoes.get(i).getRight(), dominoes.get(i+1).getLeft());
228
+		}
229
+	}
230
+}

+ 35
- 0
exercises/error-handling/.meta/hints.md Visa fil

1
+This exercise requires you to handle exceptions. An [exception](https://docs.oracle.com/javase/tutorial/essential/exceptions/definition.html) is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.
2
+
3
+In Java, there are two types of exceptions: checked and unchecked exceptions.
4
+
5
+- [Checked vs Unchecked Exceptions in Java](https://www.geeksforgeeks.org/checked-vs-unchecked-exceptions-in-java/)
6
+
7
+- [Unchecked Exceptions — The Controversy](https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html)
8
+
9
+## Checked exceptions
10
+
11
+Checked exceptions are the exceptions that are checked at [compile time](https://en.wikipedia.org/wiki/Compile_time).
12
+
13
+### Practical implications
14
+
15
+You have to declare them in the [method signature](https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html) of any method that can [throw](https://docs.oracle.com/javase/tutorial/essential/exceptions/throwing.html) a checked exception and handle or rethrow them when calling any method that can throw a checked exception.
16
+
17
+This is because checked exceptions are meant to be handled at runtime, i.e. they are errors you can recover from.
18
+
19
+### Examples of where they are used
20
+
21
+They're often used when a method can't return any valid result, for example a search method which hasn't found the item it was searching for.
22
+
23
+It's an alternative to returning null or a error code. A checked exception is better than those alternatives because it forces the user of the method to consider the error case.
24
+
25
+## Unchecked exceptions
26
+
27
+Unchecked exceptions are the exceptions that are not checked at [compile time](https://en.wikipedia.org/wiki/Compile_time).
28
+
29
+### Practical implications
30
+
31
+You don't have to declare them in the [method signature](https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html) of methods that can [throw](https://docs.oracle.com/javase/tutorial/essential/exceptions/throwing.html) an unchecked exception and handle or rethrow them when calling any method that can throw an unchecked exception.
32
+
33
+### Examples of where they are used
34
+
35
+Unchecked exceptions are mean to be used for any error than can't be handled at runtime, e.g. running out of memory.

+ 11
- 0
exercises/error-handling/.meta/src/reference/java/CustomCheckedException.java Visa fil

1
+class CustomCheckedException extends Exception {
2
+
3
+    CustomCheckedException() {
4
+        super();
5
+    }
6
+
7
+    CustomCheckedException(String message) {
8
+        super(message);
9
+    }
10
+
11
+}

+ 11
- 0
exercises/error-handling/.meta/src/reference/java/CustomUncheckedException.java Visa fil

1
+class CustomUncheckedException extends RuntimeException {
2
+
3
+    CustomUncheckedException() {
4
+        super();
5
+    }
6
+
7
+    CustomUncheckedException(String message) {
8
+        super(message);
9
+    }
10
+
11
+}

+ 63
- 0
exercises/error-handling/.meta/src/reference/java/ErrorHandling.java Visa fil

1
+import java.io.IOException;
2
+import java.util.Optional;
3
+
4
+class ErrorHandling {
5
+
6
+    void handleErrorByThrowingIllegalArgumentException() {
7
+        throw new IllegalArgumentException();
8
+    }
9
+
10
+    void handleErrorByThrowingIllegalArgumentExceptionWithDetailMessage(String message) {
11
+        throw new IllegalArgumentException(message);
12
+    }
13
+
14
+    void handleErrorByThrowingAnyCheckedException() throws IOException {
15
+        throw new IOException();
16
+    }
17
+
18
+    void handleErrorByThrowingAnyCheckedExceptionWithDetailMessage(String message) throws IOException {
19
+        throw new IOException(message);
20
+    }
21
+
22
+    void handleErrorByThrowingAnyUncheckedException() {
23
+        throw new NullPointerException();
24
+    }
25
+
26
+    void handleErrorByThrowingAnyUncheckedExceptionWithDetailMessage(String message) {
27
+        throw new NullPointerException(message);
28
+    }
29
+
30
+    void handleErrorByThrowingCustomCheckedException() throws CustomCheckedException {
31
+        throw new CustomCheckedException();
32
+    }
33
+
34
+    void handleErrorByThrowingCustomCheckedExceptionWithDetailMessage(String message) throws CustomCheckedException {
35
+        throw new CustomCheckedException(message);
36
+    }
37
+
38
+    void handleErrorByThrowingCustomUncheckedException() {
39
+        throw new CustomUncheckedException();
40
+    }
41
+
42
+    void handleErrorByThrowingCustomUncheckedExceptionWithDetailMessage(String message) {
43
+        throw new CustomUncheckedException(message);
44
+    }
45
+
46
+    Optional<Integer> handleErrorByReturningOptionalInstance(String integer) {
47
+        if (tryParseInt(integer)) {
48
+            return Optional.of(Integer.parseInt(integer));
49
+        } else {
50
+            return Optional.empty();
51
+        }
52
+    }
53
+
54
+    private boolean tryParseInt(String integer) {
55
+        try {
56
+            Integer.parseInt(integer);
57
+            return true;
58
+        } catch (NumberFormatException e) {
59
+            return false;
60
+        }
61
+    }
62
+
63
+}

+ 62
- 0
exercises/error-handling/README.md Visa fil

1
+# Error Handling
2
+
3
+Implement various kinds of error handling and resource management.
4
+
5
+An important point of programming is how to handle errors and close
6
+resources even if errors occur.
7
+
8
+This exercise requires you to handle various errors. Because error handling
9
+is rather programming language specific you'll have to refer to the tests
10
+for your track to see what's exactly required.
11
+
12
+# Java Tips
13
+
14
+This exercise requires you to handle exceptions. An [exception](https://docs.oracle.com/javase/tutorial/essential/exceptions/definition.html) is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions.
15
+
16
+In Java, there are two types of exceptions: checked and unchecked exceptions.
17
+
18
+- [Checked vs Unchecked Exceptions in Java](https://www.geeksforgeeks.org/checked-vs-unchecked-exceptions-in-java/)
19
+
20
+- [Unchecked Exceptions — The Controversy](https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html)
21
+
22
+## Checked exceptions
23
+
24
+Checked exceptions are the exceptions that are checked at [compile time](https://en.wikipedia.org/wiki/Compile_time).
25
+
26
+### Practical implications
27
+
28
+You have to declare them in the [method signature](https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html) of any method that can [throw](https://docs.oracle.com/javase/tutorial/essential/exceptions/throwing.html) a checked exception and handle or rethrow them when calling any method that can throw a checked exception.
29
+
30
+This is because checked exceptions are meant to be handled at runtime, i.e. they are errors you can recover from.
31
+
32
+### Examples of where they are used
33
+
34
+They're often used when a method can't return any valid result, for example a search method which hasn't found the item it was searching for.
35
+
36
+It's an alternative to returning null or a error code. A checked exception is better than those alternatives because it forces the user of the method to consider the error case.
37
+
38
+## Unchecked exceptions
39
+
40
+Unchecked exceptions are the exceptions that are not checked at [compile time](https://en.wikipedia.org/wiki/Compile_time).
41
+
42
+### Practical implications
43
+
44
+You don't have to declare them in the [method signature](https://docs.oracle.com/javase/tutorial/java/javaOO/methods.html) of methods that can [throw](https://docs.oracle.com/javase/tutorial/essential/exceptions/throwing.html) an unchecked exception and handle or rethrow them when calling any method that can throw an unchecked exception.
45
+
46
+### Examples of where they are used
47
+
48
+Unchecked exceptions are mean to be used for any error than can't be handled at runtime, e.g. running out of memory.
49
+
50
+# Running the tests
51
+
52
+You can run all the tests for an exercise by entering
53
+
54
+```sh
55
+$ gradle test
56
+```
57
+
58
+in your terminal.
59
+
60
+## Submitting Incomplete Solutions
61
+
62
+It's possible to submit an incomplete solution so you can see how others have completed the exercise.

+ 18
- 0
exercises/error-handling/build.gradle Visa fil

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
+}

+ 11
- 0
exercises/error-handling/src/main/java/CustomCheckedException.java Visa fil

1
+class CustomCheckedException extends Exception {
2
+
3
+    CustomCheckedException() {
4
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
5
+    }
6
+
7
+    CustomCheckedException(String message) {
8
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
9
+    }
10
+
11
+}

+ 11
- 0
exercises/error-handling/src/main/java/CustomUncheckedException.java Visa fil

1
+class CustomUncheckedException extends RuntimeException {
2
+
3
+    CustomUncheckedException() {
4
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
5
+    }
6
+
7
+    CustomUncheckedException(String message) {
8
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
9
+    }
10
+
11
+}

+ 49
- 0
exercises/error-handling/src/main/java/ErrorHandling.java Visa fil

1
+import java.util.Optional;
2
+
3
+class ErrorHandling {
4
+
5
+    void handleErrorByThrowingIllegalArgumentException() {
6
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
7
+    }
8
+
9
+    void handleErrorByThrowingIllegalArgumentExceptionWithDetailMessage(String message) {
10
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
11
+    }
12
+
13
+    void handleErrorByThrowingAnyCheckedException() {
14
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
15
+    }
16
+
17
+    void handleErrorByThrowingAnyCheckedExceptionWithDetailMessage(String message) {
18
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
19
+    }
20
+
21
+    void handleErrorByThrowingAnyUncheckedException() {
22
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
23
+    }
24
+
25
+    void handleErrorByThrowingAnyUncheckedExceptionWithDetailMessage(String message) {
26
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
27
+    }
28
+
29
+    void handleErrorByThrowingCustomCheckedException() {
30
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
31
+    }
32
+
33
+    void handleErrorByThrowingCustomCheckedExceptionWithDetailMessage(String message) {
34
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
35
+    }
36
+
37
+    void handleErrorByThrowingCustomUncheckedException() {
38
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
39
+    }
40
+
41
+    void handleErrorByThrowingCustomUncheckedExceptionWithDetailMessage(String message) {
42
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
43
+    }
44
+
45
+    Optional<Integer> handleErrorByReturningOptionalInstance(String integer) {
46
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
47
+    }
48
+
49
+}

+ 116
- 0
exercises/error-handling/src/test/java/ErrorHandlingTest.java Visa fil

1
+import org.junit.Before;
2
+import org.junit.Ignore;
3
+import org.junit.Rule;
4
+import org.junit.Test;
5
+import org.junit.rules.ExpectedException;
6
+
7
+import static org.junit.Assert.assertEquals;
8
+import static org.junit.Assert.assertFalse;
9
+import static org.junit.Assert.assertTrue;
10
+
11
+import java.util.Optional;
12
+
13
+public class ErrorHandlingTest {
14
+
15
+    private ErrorHandling errorHandling;
16
+
17
+    @Rule
18
+    public ExpectedException thrown = ExpectedException.none();
19
+
20
+    @Before
21
+    public void setUp() {
22
+        errorHandling = new ErrorHandling();
23
+    }
24
+
25
+    @Test
26
+    public void testThrowIllegalArgumentException() {
27
+        thrown.expect(IllegalArgumentException.class);
28
+        errorHandling.handleErrorByThrowingIllegalArgumentException();
29
+    }
30
+
31
+    @Ignore("Remove to run test")
32
+    @Test
33
+    public void testThrowIllegalArgumentExceptionWithDetailMessage() {
34
+        thrown.expect(IllegalArgumentException.class);
35
+        thrown.expectMessage("This is the detail message.");
36
+        errorHandling.handleErrorByThrowingIllegalArgumentExceptionWithDetailMessage("This is the detail message.");
37
+    }
38
+
39
+    @Ignore("Remove to run test")
40
+    @Test
41
+    public void testThrowAnyCheckedException() {
42
+        try {
43
+            errorHandling.handleErrorByThrowingAnyCheckedException();
44
+        } catch (Exception e) {
45
+            assertFalse(e instanceof RuntimeException);
46
+        }
47
+    }
48
+
49
+    @Ignore("Remove to run test")
50
+    @Test
51
+    public void testThrowAnyCheckedExceptionWithDetailMessage() {
52
+        try {
53
+            errorHandling.handleErrorByThrowingAnyCheckedExceptionWithDetailMessage("This is the detail message.");
54
+        } catch (Exception e) {
55
+            assertFalse(e instanceof RuntimeException);
56
+            assertEquals("This is the detail message.", e.getMessage());
57
+        }
58
+    }
59
+
60
+    @Ignore("Remove to run test")
61
+    @Test
62
+    public void testThrowAnyUncheckedException() {
63
+        thrown.expect(RuntimeException.class);
64
+        errorHandling.handleErrorByThrowingAnyUncheckedException();
65
+    }
66
+
67
+    @Ignore("Remove to run test")
68
+    @Test
69
+    public void testThrowAnyUncheckedExceptionWithDetailMessage() {
70
+        thrown.expect(RuntimeException.class);
71
+        thrown.expectMessage("This is the detail message.");
72
+        errorHandling.handleErrorByThrowingAnyUncheckedExceptionWithDetailMessage("This is the detail message.");
73
+    }
74
+
75
+    @Ignore("Remove to run test")
76
+    @Test
77
+    public void testThrowCustomCheckedException() throws CustomCheckedException {
78
+        thrown.expect(CustomCheckedException.class);
79
+        errorHandling.handleErrorByThrowingCustomCheckedException();
80
+    }
81
+
82
+    @Ignore("Remove to run test")
83
+    @Test
84
+    public void testThrowCustomCheckedExceptionWithDetailMessage() throws CustomCheckedException {
85
+        thrown.expect(CustomCheckedException.class);
86
+        thrown.expectMessage("This is the detail message.");
87
+        errorHandling.handleErrorByThrowingCustomCheckedExceptionWithDetailMessage("This is the detail message.");
88
+    }
89
+
90
+    @Ignore("Remove to run test")
91
+    @Test
92
+    public void testThrowCustomUncheckedException() {
93
+        thrown.expect(CustomUncheckedException.class);
94
+        errorHandling.handleErrorByThrowingCustomUncheckedException();
95
+    }
96
+
97
+    @Ignore("Remove to run test")
98
+    @Test
99
+    public void testThrowCustomUncheckedExceptionWithDetailMessage() {
100
+        thrown.expect(CustomUncheckedException.class);
101
+        thrown.expectMessage("This is the detail message.");
102
+        errorHandling.handleErrorByThrowingCustomUncheckedExceptionWithDetailMessage("This is the detail message.");
103
+    }
104
+
105
+    @Ignore("Remove to run test")
106
+    @Test
107
+    public void testReturnOptionalInstance() {
108
+        Optional<Integer> successfulResult = errorHandling.handleErrorByReturningOptionalInstance("1");
109
+        assertTrue(successfulResult.isPresent());
110
+        assertEquals(1, (int) successfulResult.get());
111
+
112
+        Optional<Integer> failureResult = errorHandling.handleErrorByReturningOptionalInstance("a");
113
+        assertFalse(failureResult.isPresent());
114
+    }
115
+
116
+}

+ 1
- 1
exercises/flatten-array/.meta/version Visa fil

1
-1.1.0
1
+1.2.0

+ 1
- 1
exercises/forth/.meta/version Visa fil

1
-1.4.0
1
+1.5.0

+ 152
- 0
exercises/go-counting/.meta/src/reference/java/GoCounting.java Visa fil

1
+import java.awt.Point;
2
+import java.util.ArrayList;
3
+import java.util.HashMap;
4
+import java.util.HashSet;
5
+import java.util.Set;
6
+
7
+class GoCounting {
8
+	private Player[][] board;
9
+	
10
+	GoCounting (String boardString) {
11
+		String[] lines = boardString.split("\n");
12
+		
13
+		board = new Player[lines[0].length()][lines.length];
14
+		
15
+		for (int i = 0; i < lines.length; i++) {
16
+			for (int j = 0; j < lines[i].length(); j++) {
17
+				if (lines[i].charAt(j) == 'B') {
18
+					board[j][i] = Player.BLACK;
19
+				} else if (lines[i].charAt(j) == 'W') {
20
+					board[j][i] = Player.WHITE;
21
+				} else {
22
+					board[j][i] = Player.NONE;
23
+				}
24
+			}
25
+		}
26
+	}
27
+	
28
+	private ArrayList<Point> getAdjacent(Point p) {
29
+		ArrayList<Point> adjacent = new ArrayList<>();
30
+		if (p.x > 0) {
31
+			adjacent.add(new Point(p.x - 1, p.y));
32
+		}
33
+		if (p.x < board.length - 1) {
34
+			adjacent.add(new Point(p.x + 1, p.y)); 
35
+		}
36
+		if (p.y > 0) {
37
+			adjacent.add(new Point(p.x, p.y - 1));
38
+		}
39
+		if (p.y < board[0].length - 1) {
40
+			adjacent.add(new Point(p.x, p.y + 1));
41
+		}
42
+		return adjacent;
43
+	}
44
+	
45
+	Player getTerritoryOwner(int x, int y) {
46
+		
47
+		if (x < 0 || x >= board.length || y < 0 || y >= board[0].length) {
48
+			throw new IllegalArgumentException("Invalid coordinate");
49
+		}
50
+		
51
+		if (board[x][y] == Player.BLACK || board[x][y] == Player.WHITE) {
52
+			return Player.NONE;
53
+		}
54
+		
55
+		ArrayList<Point> visited = new ArrayList<>();
56
+		ArrayList<Point> edges = new ArrayList<>();
57
+		ArrayList<Point> territory = new ArrayList<>();
58
+		
59
+		ArrayList<Point> tovisit = new ArrayList<>();
60
+		
61
+		tovisit.add(new Point(x, y));
62
+		
63
+		while (tovisit.size() > 0) {
64
+			Point current = tovisit.remove(0);
65
+			
66
+			if (board[current.x][current.y] == Player.NONE) {
67
+				visited.add(current);
68
+				territory.add(current);
69
+				
70
+				ArrayList<Point> adjacent = getAdjacent(current);
71
+				
72
+				for (Point p : adjacent) {
73
+					if (!visited.contains(p) && !tovisit.contains(p)) {
74
+						tovisit.add(p);
75
+					}
76
+				}
77
+			} else {
78
+				edges.add(current);
79
+			}
80
+		}
81
+		
82
+		if (edges.size() == 0) {
83
+			return Player.NONE;
84
+		}
85
+		
86
+		Player owner = board[edges.get(0).x][edges.get(0).y];
87
+		for (int i = 0; i < edges.size(); i++) {
88
+			if (owner != board[edges.get(i).x][edges.get(i).y]) {
89
+				owner = Player.NONE;
90
+			}
91
+		}
92
+		
93
+		return owner;
94
+	}
95
+	
96
+	Set<Point> getTerritory(int x, int y) {
97
+		
98
+		if (x < 0 || x >= board.length || y < 0 || y >= board[0].length) {
99
+			throw new IllegalArgumentException("Invalid coordinate");
100
+		}
101
+		
102
+		ArrayList<Point> visited = new ArrayList<>();
103
+		HashSet<Point> territory = new HashSet<>();
104
+		
105
+		ArrayList<Point> tovisit = new ArrayList<>();
106
+		
107
+		tovisit.add(new Point(x, y));
108
+		
109
+		while (tovisit.size() > 0) {
110
+			Point current = tovisit.remove(0);
111
+			
112
+			if (board[current.x][current.y] == Player.NONE) {
113
+				visited.add(current);
114
+				territory.add(current);
115
+				
116
+				ArrayList<Point> adjacent = getAdjacent(current);
117
+				
118
+				for (Point p : adjacent) {
119
+					if (!visited.contains(p) && !tovisit.contains(p)) {
120
+						tovisit.add(p);
121
+					}
122
+				}
123
+			}
124
+		}
125
+		
126
+		return territory;
127
+	}
128
+	
129
+	HashMap<String, Set<Point>> getTerritories() {
130
+		HashMap<String, Set<Point>> territories = new HashMap<String, Set<Point>>();
131
+		
132
+		territories.put("WHITE", new HashSet<Point>());
133
+		territories.put("BLACK", new HashSet<Point>());
134
+		territories.put("NONE", new HashSet<Point>());
135
+		
136
+		for (int i = 0; i < board[0].length; i++) {
137
+			for (int j = 0; j < board.length; j++) {
138
+				if (board[j][i] == Player.NONE) {
139
+					if (getTerritoryOwner(j, i) == Player.NONE) {
140
+						territories.get("NONE").add(new Point(j, i));
141
+					} else if (getTerritoryOwner(j, i) == Player.BLACK) {
142
+						territories.get("BLACK").add(new Point(j, i));
143
+					} else {
144
+						territories.get("WHITE").add(new Point(j, i));
145
+					}
146
+				}
147
+			}
148
+		}
149
+		
150
+		return territories;
151
+	}
152
+}

+ 3
- 0
exercises/go-counting/.meta/src/reference/java/Player.java Visa fil

1
+enum Player {
2
+    NONE, BLACK, WHITE
3
+}

+ 2
- 0
exercises/go-counting/.meta/version Visa fil

1
+1.0.0
2
+

+ 50
- 0
exercises/go-counting/README.md Visa fil

1
+# Go Counting
2
+
3
+Count the scored points on a Go board.
4
+
5
+In the game of go (also known as baduk, igo, cờ vây and wéiqí) points
6
+are gained by completely encircling empty intersections with your
7
+stones. The encircled intersections of a player are known as its
8
+territory.
9
+
10
+Write a function that determines the territory of each player. You may
11
+assume that any stones that have been stranded in enemy territory have
12
+already been taken off the board.
13
+
14
+Write a function that determines the territory which includes a specified coordinate.
15
+
16
+Multiple empty intersections may be encircled at once and for encircling
17
+only horizontal and vertical neighbours count. In the following diagram
18
+the stones which matter are marked "O" and the stones that don't are
19
+marked "I" (ignored).  Empty spaces represent empty intersections.
20
+
21
+```text
22
++----+
23
+|IOOI|
24
+|O  O|
25
+|O OI|
26
+|IOI |
27
++----+
28
+```
29
+
30
+To be more precise an empty intersection is part of a player's territory
31
+if all of its neighbours are either stones of that player or empty
32
+intersections that are part of that player's territory.
33
+
34
+For more information see
35
+[wikipedia](https://en.wikipedia.org/wiki/Go_%28game%29) or [Sensei's
36
+Library](http://senseis.xmp.net/).
37
+
38
+# Running the tests
39
+
40
+You can run all the tests for an exercise by entering
41
+
42
+```sh
43
+$ gradle test
44
+```
45
+
46
+in your terminal.
47
+
48
+## Submitting Incomplete Solutions
49
+
50
+It's possible to submit an incomplete solution so you can see how others have completed the exercise.

+ 18
- 0
exercises/go-counting/build.gradle Visa fil

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
exercises/go-counting/src/main/java/.keep Visa fil


+ 3
- 0
exercises/go-counting/src/main/java/Player.java Visa fil

1
+enum Player {
2
+    NONE, BLACK, WHITE
3
+}

+ 178
- 0
exercises/go-counting/src/test/java/GoCountingTest.java Visa fil

1
+import org.junit.Ignore;
2
+import org.junit.Test;
3
+
4
+import java.awt.Point;
5
+import java.util.HashMap;
6
+import java.util.HashSet;
7
+import java.util.Set;
8
+
9
+import static org.junit.Assert.assertEquals;
10
+
11
+import org.junit.Rule;
12
+import org.junit.rules.ExpectedException;
13
+
14
+public class GoCountingTest {
15
+	
16
+	@Rule
17
+	public ExpectedException expectedException = ExpectedException.none(); 
18
+	
19
+	String board5x5 = "  B  \n" +
20
+	                  " B B \n" +
21
+	                  "B W B\n" +
22
+	                  " W W \n" +
23
+	                  "  W  ";
24
+	
25
+	@Test
26
+	public void blackCorner5x5BoardTest() {
27
+		GoCounting gocounting = new GoCounting(board5x5);
28
+		
29
+		Set<Point> territory = new HashSet<>();
30
+		territory.add(new Point(0, 0));
31
+		territory.add(new Point(0, 1));
32
+		territory.add(new Point(1, 0));
33
+		
34
+		assertEquals(Player.BLACK, gocounting.getTerritoryOwner(0, 1));
35
+		assertEquals(territory, gocounting.getTerritory(0, 1));
36
+	}
37
+	
38
+	@Ignore("Remove to run test")
39
+	@Test
40
+	public void whiteCenter5x5BoardTest() {
41
+		GoCounting gocounting = new GoCounting(board5x5);
42
+		
43
+		Set<Point> territory = new HashSet<>();
44
+		territory.add(new Point(2, 3));
45
+		
46
+		assertEquals(Player.WHITE, gocounting.getTerritoryOwner(2, 3));
47
+		assertEquals(territory, gocounting.getTerritory(2, 3));
48
+	}
49
+	
50
+	@Ignore("Remove to run test")
51
+	@Test
52
+	public void openCorner5x5BoardTest() {
53
+		GoCounting gocounting = new GoCounting(board5x5);
54
+		
55
+		Set<Point> territory = new HashSet<>();
56
+		territory.add(new Point(0, 3));
57
+		territory.add(new Point(0, 4));
58
+		territory.add(new Point(1, 4));
59
+		
60
+		assertEquals(Player.NONE, gocounting.getTerritoryOwner(1, 4));
61
+		assertEquals(territory, gocounting.getTerritory(1, 4));
62
+	}
63
+	
64
+	@Ignore("Remove to run test")
65
+	@Test
66
+	public void stoneNotTerritory5x5Board() {
67
+		GoCounting gocounting = new GoCounting(board5x5);
68
+		
69
+		Set<Point> territory = new HashSet<>();
70
+		
71
+		assertEquals(Player.NONE, gocounting.getTerritoryOwner(1, 1));
72
+		assertEquals(territory, gocounting.getTerritory(1, 1));
73
+	}
74
+	
75
+	@Ignore("Remove to run test")
76
+	@Test
77
+	public void invalidXTooLow5x5Board() {
78
+		GoCounting gocounting = new GoCounting(board5x5);
79
+		
80
+		expectedException.expect(IllegalArgumentException.class);
81
+		expectedException.expectMessage("Invalid coordinate");
82
+		
83
+		gocounting.getTerritory(-1, 1);
84
+	}
85
+	
86
+	@Ignore("Remove to run test")
87
+	@Test
88
+	public void invalidXTooHigh5x5Board() {
89
+		GoCounting gocounting = new GoCounting(board5x5);
90
+		
91
+		expectedException.expect(IllegalArgumentException.class);
92
+		expectedException.expectMessage("Invalid coordinate");
93
+		
94
+		gocounting.getTerritory(5, 1);
95
+	}
96
+	
97
+	@Ignore("Remove to run test")
98
+	@Test
99
+	public void invalidYTooLow5x5Board() {
100
+		GoCounting gocounting = new GoCounting(board5x5);
101
+		
102
+		expectedException.expect(IllegalArgumentException.class);
103
+		expectedException.expectMessage("Invalid coordinate");
104
+		
105
+		gocounting.getTerritory(1, -1);
106
+	}
107
+	
108
+	@Ignore("Remove to run test")
109
+	@Test
110
+	public void invalidYTooHigh5x5Board() {
111
+		GoCounting gocounting = new GoCounting(board5x5);
112
+		
113
+		expectedException.expect(IllegalArgumentException.class);
114
+		expectedException.expectMessage("Invalid coordinate");
115
+		
116
+		gocounting.getTerritory(1, 5);
117
+	}
118
+	
119
+	@Ignore("Remove to run test")
120
+	@Test
121
+	public void oneTerritoryIsWholeBoardTest() {
122
+		GoCounting gocounting = new GoCounting(" ");
123
+		
124
+		HashMap<String, Set<Point>> territories = new HashMap<>();
125
+		Set<Point> blackTerritory = new HashSet<>();
126
+		Set<Point> whiteTerritory = new HashSet<>();
127
+		Set<Point> noneTerritory = new HashSet<>();
128
+		noneTerritory.add(new Point(0, 0));
129
+		
130
+		territories.put("BLACK", blackTerritory);
131
+		territories.put("WHITE", whiteTerritory);
132
+		territories.put("NONE", noneTerritory);
133
+		
134
+		assertEquals(territories, gocounting.getTerritories());
135
+	}
136
+	
137
+	@Ignore("Remove to run test")
138
+	@Test
139
+	public void twoTerritoryRectangularBoardTest() {
140
+		GoCounting gocounting = new GoCounting(" BW \n BW ");
141
+		
142
+		Set<Point> blackTerritory = new HashSet<>();
143
+		blackTerritory.add(new Point(0, 0));
144
+		blackTerritory.add(new Point(0, 1));
145
+		
146
+		Set<Point> whiteTerritory = new HashSet<>();
147
+		whiteTerritory.add(new Point(3, 0));
148
+		whiteTerritory.add(new Point(3, 1));
149
+		
150
+		Set<Point> noneTerritory = new HashSet<>();
151
+		
152
+		HashMap<String, Set<Point>> territories = new HashMap<>();
153
+		territories.put("BLACK", blackTerritory);
154
+		territories.put("WHITE", whiteTerritory);
155
+		territories.put("NONE", noneTerritory);
156
+		
157
+		assertEquals(territories, gocounting.getTerritories());
158
+	}
159
+	
160
+	@Ignore("Remove to run test")
161
+	@Test
162
+	public void twoRegionRectangularBoardTest() {
163
+		GoCounting gocounting = new GoCounting(" B ");
164
+		
165
+		HashMap<String, Set<Point>> territories = new HashMap<>();
166
+		Set<Point> blackTerritory = new HashSet<>();
167
+		blackTerritory.add(new Point(0, 0));
168
+		blackTerritory.add(new Point(2, 0));
169
+		Set<Point> whiteTerritory = new HashSet<>();
170
+		Set<Point> noneTerritory = new HashSet<>();
171
+		
172
+		territories.put("BLACK", blackTerritory);
173
+		territories.put("WHITE", whiteTerritory);
174
+		territories.put("NONE", noneTerritory);
175
+		
176
+		assertEquals(territories, gocounting.getTerritories());
177
+	}
178
+}

+ 58
- 0
exercises/grep/.meta/hints.md Visa fil

1
+Since this exercise has difficulty 5 it doesn't come with any starter implementation.
2
+This is so that you get to practice creating classes and methods which is an important part of programming in Java.
3
+It does mean that when you first try to run the tests, they won't compile.
4
+They will give you an error similar to:
5
+```
6
+ path-to-exercism-dir\exercism\java\name-of-exercise\src\test\java\ExerciseClassNameTest.java:14: error: cannot find symbol
7
+        ExerciseClassName exerciseClassName = new ExerciseClassName();
8
+        ^
9
+ symbol:   class ExerciseClassName
10
+ location: class ExerciseClassNameTest
11
+```
12
+This error occurs because the test refers to a class that hasn't been created yet (`ExerciseClassName`).
13
+To resolve the error you need to add a file matching the class name in the error to the `src/main/java` directory.
14
+For example, for the error above you would add a file called `ExerciseClassName.java`.
15
+
16
+When you try to run the tests again you will get slightly different errors.
17
+You might get an error similar to:
18
+```
19
+  constructor ExerciseClassName in class ExerciseClassName cannot be applied to given types;
20
+        ExerciseClassName exerciseClassName = new ExerciseClassName("some argument");
21
+                                              ^
22
+  required: no arguments
23
+  found: String
24
+  reason: actual and formal argument lists differ in length
25
+```
26
+This error means that you need to add a [constructor](https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html) to your new class.
27
+If you don't add a constructor, Java will add a default one for you.
28
+This default constructor takes no arguments.
29
+So if the tests expect your class to have a constructor which takes arguments, then you need to create this constructor yourself.
30
+In the example above you could add:
31
+```
32
+ExerciseClassName(String input) {
33
+
34
+}
35
+``` 
36
+That should make the error go away, though you might need to add some more code to your constructor to make the test pass!
37
+
38
+You might also get an error similar to:
39
+```
40
+  error: cannot find symbol
41
+        assertEquals(expectedOutput, exerciseClassName.someMethod());
42
+                                                       ^
43
+  symbol:   method someMethod()
44
+  location: variable exerciseClassName of type ExerciseClassName
45
+```
46
+This error means that you need to add a method called `someMethod` to your new class.
47
+In the example above you would add:
48
+```
49
+String someMethod() {
50
+  return "";
51
+}
52
+```
53
+Make sure the return type matches what the test is expecting.
54
+You can find out which return type it should have by looking at the type of object it's being compared to in the tests.
55
+Or you could set your method to return some random type (e.g. `void`), and run the tests again.
56
+The new error should tell you which type it's expecting.
57
+
58
+After having resolved these errors you should be ready to start making the tests pass!

+ 65
- 0
exercises/grep/.meta/src/reference/java/GrepTool.java Visa fil

1
+import java.io.IOException;
2
+import java.nio.charset.Charset;
3
+import java.nio.file.Files;
4
+import java.nio.file.Paths;
5
+import java.util.Collections;
6
+import java.util.List;
7
+import java.util.stream.Collectors;
8
+import java.util.stream.IntStream;
9
+
10
+class GrepTool {
11
+
12
+    String grep(String pattern, List<String> flags, List<String> files) {
13
+        boolean shouldAddFilenameToEachLine = files.size() > 1;
14
+        return files
15
+            .stream()
16
+            .map(file -> grepFile(pattern, flags, file, shouldAddFilenameToEachLine))
17
+            .filter(line -> !line.isEmpty())
18
+            .collect(Collectors.joining("\n"));
19
+    }
20
+
21
+    private String grepFile(String pattern, List<String> flags, String filename, boolean shouldAddFilenameToEachLine) {
22
+        List<String> lines = readFile(filename);
23
+
24
+        String matchingLines = IntStream.range(0, lines.size())
25
+            .filter(lineIndex -> lineMatchesPattern(lines.get(lineIndex), pattern, flags))
26
+            .mapToObj(lineIndex -> {
27
+                String lineWithFlagsApplied = applyFlagsToLine(lines.get(lineIndex), flags, lineIndex + 1);
28
+                return shouldAddFilenameToEachLine ? filename + ":" + lineWithFlagsApplied : lineWithFlagsApplied;
29
+            })
30
+            .collect(Collectors.joining("\n"));
31
+
32
+        boolean shouldPrintFilenameInsteadOfMatchingLines = flags.contains("-l");
33
+        return shouldPrintFilenameInsteadOfMatchingLines && !matchingLines.isEmpty() ? filename : matchingLines;
34
+    }
35
+
36
+    private boolean lineMatchesPattern(String line, String pattern, List<String> flags) {
37
+        boolean isCaseInsensitive = flags.contains("-i");
38
+        String lineToCompare = isCaseInsensitive ? line.toLowerCase() : line;
39
+        String patternToCompare = isCaseInsensitive ? pattern.toLowerCase() : pattern;
40
+
41
+        boolean shouldMatchEntireLine = flags.contains("-x");
42
+        boolean matchesPattern = shouldMatchEntireLine
43
+            ? lineToCompare.equals(patternToCompare)
44
+            : lineToCompare.contains(patternToCompare);
45
+
46
+        boolean shouldInvertMatch = flags.contains("-v");
47
+        //noinspection SimplifiableConditionalExpression
48
+        return shouldInvertMatch ? !matchesPattern : matchesPattern;
49
+    }
50
+
51
+
52
+    private String applyFlagsToLine(String line, List<String> flags, int lineNumber) {
53
+        boolean shouldAddLineNumber = flags.contains("-n");
54
+        return shouldAddLineNumber ? lineNumber + ":" + line : line;
55
+    }
56
+
57
+    private List<String> readFile(String filename) {
58
+        try {
59
+            return Files.readAllLines(Paths.get(filename), Charset.forName("UTF-8"));
60
+        } catch (IOException e) {
61
+            return Collections.emptyList();
62
+        }
63
+    }
64
+
65
+}

exercises/alphametics/.meta/src/version → exercises/grep/.meta/version Visa fil


+ 145
- 0
exercises/grep/README.md Visa fil

1
+# Grep
2
+
3
+Search a file for lines matching a regular expression pattern. Return the line
4
+number and contents of each matching line.
5
+
6
+The Unix [`grep`](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/grep.html) command can be used to search for lines in one or more files
7
+that match a user-provided search query (known as the *pattern*).
8
+
9
+The `grep` command takes three arguments:
10
+
11
+1. The pattern used to match lines in a file.
12
+2. Zero or more flags to customize the matching behavior.
13
+3. One or more files in which to search for matching lines.
14
+
15
+Your task is to implement the `grep` function, which should read the contents
16
+of the specified files, find the lines that match the specified pattern
17
+and then output those lines as a single string. Note that the lines should
18
+be output in the order in which they were found, with the first matching line
19
+in the first file being output first.
20
+
21
+As an example, suppose there is a file named "input.txt" with the following contents:
22
+
23
+```text
24
+hello
25
+world
26
+hello again
27
+```
28
+
29
+If we were to call `grep "hello" input.txt`, the returned string should be:
30
+
31
+```text
32
+hello
33
+hello again
34
+```
35
+
36
+### Flags
37
+
38
+As said earlier, the `grep` command should also support the following flags:
39
+
40
+- `-n` Print the line numbers of each matching line.
41
+- `-l` Print only the names of files that contain at least one matching line.
42
+- `-i` Match line using a case-insensitive comparison.
43
+- `-v` Invert the program -- collect all lines that fail to match the pattern.
44
+- `-x` Only match entire lines, instead of lines that contain a match.
45
+
46
+If we run `grep -n "hello" input.txt`, the `-n` flag will require the matching
47
+lines to be prefixed with its line number:
48
+
49
+```text
50
+1:hello
51
+3:hello again
52
+```
53
+
54
+And if we run `grep -i "HELLO" input.txt`, we'll do a case-insensitive match,
55
+and the output will be:
56
+
57
+```text
58
+hello
59
+hello again
60
+```
61
+
62
+The `grep` command should support multiple flags at once.
63
+
64
+For example, running `grep -l -v "hello" file1.txt file2.txt` should
65
+print the names of files that do not contain the string "hello".
66
+
67
+# Java Tips
68
+
69
+Since this exercise has difficulty 5 it doesn't come with any starter implementation.
70
+This is so that you get to practice creating classes and methods which is an important part of programming in Java.
71
+It does mean that when you first try to run the tests, they won't compile.
72
+They will give you an error similar to:
73
+```
74
+ path-to-exercism-dir\exercism\java\name-of-exercise\src\test\java\ExerciseClassNameTest.java:14: error: cannot find symbol
75
+        ExerciseClassName exerciseClassName = new ExerciseClassName();
76
+        ^
77
+ symbol:   class ExerciseClassName
78
+ location: class ExerciseClassNameTest
79
+```
80
+This error occurs because the test refers to a class that hasn't been created yet (`ExerciseClassName`).
81
+To resolve the error you need to add a file matching the class name in the error to the `src/main/java` directory.
82
+For example, for the error above you would add a file called `ExerciseClassName.java`.
83
+
84
+When you try to run the tests again you will get slightly different errors.
85
+You might get an error similar to:
86
+```
87
+  constructor ExerciseClassName in class ExerciseClassName cannot be applied to given types;
88
+        ExerciseClassName exerciseClassName = new ExerciseClassName("some argument");
89
+                                              ^
90
+  required: no arguments
91
+  found: String
92
+  reason: actual and formal argument lists differ in length
93
+```
94
+This error means that you need to add a [constructor](https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html) to your new class.
95
+If you don't add a constructor, Java will add a default one for you.
96
+This default constructor takes no arguments.
97
+So if the tests expect your class to have a constructor which takes arguments, then you need to create this constructor yourself.
98
+In the example above you could add:
99
+```
100
+ExerciseClassName(String input) {
101
+
102
+}
103
+``` 
104
+That should make the error go away, though you might need to add some more code to your constructor to make the test pass!
105
+
106
+You might also get an error similar to:
107
+```
108
+  error: cannot find symbol
109
+        assertEquals(expectedOutput, exerciseClassName.someMethod());
110
+                                                       ^
111
+  symbol:   method someMethod()
112
+  location: variable exerciseClassName of type ExerciseClassName
113
+```
114
+This error means that you need to add a method called `someMethod` to your new class.
115
+In the example above you would add:
116
+```
117
+String someMethod() {
118
+  return "";
119
+}
120
+```
121
+Make sure the return type matches what the test is expecting.
122
+You can find out which return type it should have by looking at the type of object it's being compared to in the tests.
123
+Or you could set your method to return some random type (e.g. `void`), and run the tests again.
124
+The new error should tell you which type it's expecting.
125
+
126
+After having resolved these errors you should be ready to start making the tests pass!
127
+
128
+
129
+# Running the tests
130
+
131
+You can run all the tests for an exercise by entering
132
+
133
+```sh
134
+$ gradle test
135
+```
136
+
137
+in your terminal.
138
+
139
+## Source
140
+
141
+Conversation with Nate Foster. [http://www.cs.cornell.edu/Courses/cs3110/2014sp/hw/0/ps0.pdf](http://www.cs.cornell.edu/Courses/cs3110/2014sp/hw/0/ps0.pdf)
142
+
143
+## Submitting Incomplete Solutions
144
+
145
+It's possible to submit an incomplete solution so you can see how others have completed the exercise.

+ 18
- 0
exercises/grep/build.gradle Visa fil

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
exercises/grep/src/main/java/.keep Visa fil


+ 395
- 0
exercises/grep/src/test/java/GrepToolTest.java Visa fil

1
+import org.junit.After;
2
+import org.junit.Before;
3
+import org.junit.Ignore;
4
+import org.junit.Test;
5
+
6
+import java.io.IOException;
7
+import java.nio.charset.Charset;
8
+import java.nio.file.Files;
9
+import java.nio.file.Path;
10
+import java.nio.file.Paths;
11
+import java.util.Arrays;
12
+import java.util.Collections;
13
+import java.util.List;
14
+
15
+import static org.junit.Assert.assertEquals;
16
+
17
+public class GrepToolTest {
18
+    private GrepTool grepTool;
19
+
20
+    @Before
21
+    public void setUp() throws IOException {
22
+        List<String> iliadText = Arrays.asList(
23
+            "Achilles sing, O Goddess! Peleus' son;",
24
+            "His wrath pernicious, who ten thousand woes",
25
+            "Caused to Achaia's host, sent many a soul",
26
+            "Illustrious into Ades premature,",
27
+            "And Heroes gave (so stood the will of Jove)",
28
+            "To dogs and to all ravening fowls a prey,",
29
+            "When fierce dispute had separated once",
30
+            "The noble Chief Achilles from the son",
31
+            "Of Atreus, Agamemnon, King of men."
32
+        );
33
+        writeToFile("iliad.txt", iliadText);
34
+
35
+        List<String> midsummerNightText = Arrays.asList(
36
+            "I do entreat your grace to pardon me.",
37
+            "I know not by what power I am made bold,",
38
+            "Nor how it may concern my modesty,",
39
+            "In such a presence here to plead my thoughts;",
40
+            "But I beseech your grace that I may know",
41
+            "The worst that may befall me in this case,",
42
+            "If I refuse to wed Demetrius."
43
+        );
44
+        writeToFile("midsummer-night.txt", midsummerNightText);
45
+
46
+        List<String> paradiseLostText = Arrays.asList(
47
+            "Of Mans First Disobedience, and the Fruit",
48
+            "Of that Forbidden Tree, whose mortal tast",
49
+            "Brought Death into the World, and all our woe,",
50
+            "With loss of Eden, till one greater Man",
51
+            "Restore us, and regain the blissful Seat,",
52
+            "Sing Heav'nly Muse, that on the secret top",
53
+            "Of Oreb, or of Sinai, didst inspire",
54
+            "That Shepherd, who first taught the chosen Seed"
55
+        );
56
+        writeToFile("paradise-lost.txt", paradiseLostText);
57
+
58
+        grepTool = new GrepTool();
59
+    }
60
+
61
+    @After
62
+    public void tearDown() throws IOException {
63
+        deleteFile("iliad.txt");
64
+        deleteFile("midsummer-night.txt");
65
+        deleteFile("paradise-lost.txt");
66
+    }
67
+
68
+    @Test
69
+    public void oneFileOneMatchNoFlags() {
70
+        String expected = "Of Atreus, Agamemnon, King of men.";
71
+
72
+        String actual = grepTool.grep(
73
+            "Agamemnon",
74
+            Collections.emptyList(),
75
+            Collections.singletonList("iliad.txt")
76
+        );
77
+
78
+        assertEquals(expected, actual);
79
+    }
80
+
81
+    @Ignore("Remove to run test")
82
+    @Test
83
+    public void oneFileOneMatchPrintLineNumbersFlag() {
84
+        String expected = "2:Of that Forbidden Tree, whose mortal tast";
85
+
86
+        String actual = grepTool.grep(
87
+            "Forbidden",
88
+            Collections.singletonList("-n"),
89
+            Collections.singletonList("paradise-lost.txt")
90
+        );
91
+
92
+        assertEquals(expected, actual);
93
+    }
94
+
95
+    @Ignore("Remove to run test")
96
+    @Test
97
+    public void oneFileOneMatchCaseInsensitiveFlag() {
98
+        String expected = "Of that Forbidden Tree, whose mortal tast";
99
+
100
+        String actual = grepTool.grep(
101
+            "FORBIDDEN",
102
+            Collections.singletonList("-i"),
103
+            Collections.singletonList("paradise-lost.txt")
104
+        );
105
+
106
+        assertEquals(expected, actual);
107
+    }
108
+
109
+    @Ignore("Remove to run test")
110
+    @Test
111
+    public void oneFileOneMatchPrintFileNamesFlag() {
112
+        String expected = "paradise-lost.txt";
113
+
114
+        String actual = grepTool.grep(
115
+            "Forbidden",
116
+            Collections.singletonList("-l"),
117
+            Collections.singletonList("paradise-lost.txt")
118
+        );
119
+
120
+        assertEquals(expected, actual);
121
+    }
122
+
123
+    @Ignore("Remove to run test")
124
+    @Test
125
+    public void oneFileOneMatchEntireLinesFlag() {
126
+        String expected = "With loss of Eden, till one greater Man";
127
+
128
+        String actual = grepTool.grep(
129
+            "With loss of Eden, till one greater Man",
130
+            Collections.singletonList("-x"),
131
+            Collections.singletonList("paradise-lost.txt")
132
+        );
133
+
134
+        assertEquals(expected, actual);
135
+    }
136
+
137
+    @Ignore("Remove to run test")
138
+    @Test
139
+    public void oneFileOneMatchMultipleFlags() {
140
+        String expected = "9:Of Atreus, Agamemnon, King of men.";
141
+
142
+        String actual = grepTool.grep(
143
+            "OF ATREUS, Agamemnon, KIng of MEN.",
144
+            Arrays.asList("-n", "-i", "-x"),
145
+            Collections.singletonList("iliad.txt")
146
+        );
147
+
148
+        assertEquals(expected, actual);
149
+    }
150
+
151
+    @Ignore("Remove to run test")
152
+    @Test
153
+    public void oneFileSeveralMatchesNoFlags() {
154
+        String expected = "Nor how it may concern my modesty,\n"
155
+            + "But I beseech your grace that I may know\n"
156
+            + "The worst that may befall me in this case,";
157
+
158
+        String actual = grepTool.grep(
159
+            "may",
160
+            Collections.emptyList(),
161
+            Collections.singletonList("midsummer-night.txt")
162
+        );
163
+
164
+        assertEquals(expected, actual);
165
+    }
166
+
167
+    @Ignore("Remove to run test")
168
+    @Test
169
+    public void oneFileSeveralMatchesPrintLineNumbersFlag() {
170
+        String expected = "3:Nor how it may concern my modesty,\n"
171
+            + "5:But I beseech your grace that I may know\n"
172
+            + "6:The worst that may befall me in this case,";
173
+
174
+        String actual = grepTool.grep(
175
+            "may",
176
+            Collections.singletonList("-n"),
177
+            Collections.singletonList("midsummer-night.txt")
178
+        );
179
+
180
+        assertEquals(expected, actual);
181
+    }
182
+
183
+    @Ignore("Remove to run test")
184
+    @Test
185
+    public void oneFileSeveralMatchesMatchEntireLineFlag() {
186
+        String expected = "";
187
+
188
+        String actual = grepTool.grep(
189
+            "may",
190
+            Collections.singletonList("-x"),
191
+            Collections.singletonList("midsummer-night.txt")
192
+        );
193
+
194
+        assertEquals(expected, actual);
195
+    }
196
+
197
+    @Ignore("Remove to run test")
198
+    @Test
199
+    public void oneFileSeveralMatchesCaseInsensitiveFlag() {
200
+        String expected = "Achilles sing, O Goddess! Peleus' son;\n"
201
+            + "The noble Chief Achilles from the son";
202
+
203
+        String actual = grepTool.grep(
204
+            "ACHILLES",
205
+            Collections.singletonList("-i"),
206
+            Collections.singletonList("iliad.txt")
207
+        );
208
+
209
+        assertEquals(expected, actual);
210
+    }
211
+
212
+    @Ignore("Remove to run test")
213
+    @Test
214
+    public void oneFileSeveralMatchesInvertedFlag() {
215
+        String expected = "Brought Death into the World, and all our woe,\n"
216
+            + "With loss of Eden, till one greater Man\n"
217
+            + "Restore us, and regain the blissful Seat,\n"
218
+            + "Sing Heav'nly Muse, that on the secret top\n"
219
+            + "That Shepherd, who first taught the chosen Seed";
220
+
221
+        String actual = grepTool.grep(
222
+            "Of",
223
+            Collections.singletonList("-v"),
224
+            Collections.singletonList("paradise-lost.txt")
225
+        );
226
+
227
+        assertEquals(expected, actual);
228
+    }
229
+
230
+    @Ignore("Remove to run test")
231
+    @Test
232
+    public void oneFileNoMatchesVariousFlags() {
233
+        String expected = "";
234
+
235
+        String actual = grepTool.grep(
236
+            "Gandalf",
237
+            Arrays.asList("-n", "-l", "-x", "-i"),
238
+            Collections.singletonList("iliad.txt")
239
+        );
240
+
241
+        assertEquals(expected, actual);
242
+    }
243
+
244
+    @Ignore("Remove to run test")
245
+    @Test
246
+    public void multipleFilesOneMatchNoFlags() {
247
+        String expected = "iliad.txt:Of Atreus, Agamemnon, King of men.";
248
+
249
+        String actual = grepTool.grep(
250
+            "Agamemnon",
251
+            Collections.emptyList(),
252
+            Arrays.asList("iliad.txt", "midsummer-night.txt", "paradise-lost.txt")
253
+        );
254
+
255
+        assertEquals(expected, actual);
256
+    }
257
+
258
+    @Ignore("Remove to run test")
259
+    @Test
260
+    public void multipleFilesSeveralMatchesNoFlags() {
261
+        String expected = "midsummer-night.txt:Nor how it may concern my modesty,\n"
262
+            + "midsummer-night.txt:But I beseech your grace that I may know\n"
263
+            + "midsummer-night.txt:The worst that may befall me in this case,";
264
+
265
+        String actual = grepTool.grep(
266
+            "may",
267
+            Collections.emptyList(),
268
+            Arrays.asList("iliad.txt", "midsummer-night.txt", "paradise-lost.txt")
269
+        );
270
+
271
+        assertEquals(expected, actual);
272
+    }
273
+
274
+    @Ignore("Remove to run test")
275
+    @Test
276
+    public void multipleFilesSeveralMatchesPrintLineNumbersFlag() {
277
+        String expected = "midsummer-night.txt:5:But I beseech your grace that I may know\n"
278
+            + "midsummer-night.txt:6:The worst that may befall me in this case,\n"
279
+            + "paradise-lost.txt:2:Of that Forbidden Tree, whose mortal tast\n"
280
+            + "paradise-lost.txt:6:Sing Heav'nly Muse, that on the secret top";
281
+
282
+        String actual = grepTool.grep(
283
+            "that",
284
+            Collections.singletonList("-n"),
285
+            Arrays.asList("iliad.txt", "midsummer-night.txt", "paradise-lost.txt")
286
+        );
287
+
288
+        assertEquals(expected, actual);
289
+    }
290
+
291
+    @Ignore("Remove to run test")
292
+    @Test
293
+    public void multipleFilesOneMatchPrintFileNamesFlag() {
294
+        String expected = "iliad.txt\n"
295
+            + "paradise-lost.txt";
296
+
297
+        String actual = grepTool.grep(
298
+            "who",
299
+            Collections.singletonList("-l"),
300
+            Arrays.asList("iliad.txt", "midsummer-night.txt", "paradise-lost.txt")
301
+        );
302
+
303
+        assertEquals(expected, actual);
304
+    }
305
+
306
+    @Ignore("Remove to run test")
307
+    @Test
308
+    public void multipleFilesSeveralMatchesCaseInsensitiveFlag() {
309
+        String expected = "iliad.txt:Caused to Achaia's host, sent many a soul\n"
310
+            + "iliad.txt:Illustrious into Ades premature,\n"
311
+            + "iliad.txt:And Heroes gave (so stood the will of Jove)\n"
312
+            + "iliad.txt:To dogs and to all ravening fowls a prey,\n"
313
+            + "midsummer-night.txt:I do entreat your grace to pardon me.\n"
314
+            + "midsummer-night.txt:In such a presence here to plead my thoughts;\n"
315
+            + "midsummer-night.txt:If I refuse to wed Demetrius.\n"
316
+            + "paradise-lost.txt:Brought Death into the World, and all our woe,\n"
317
+            + "paradise-lost.txt:Restore us, and regain the blissful Seat,\n"
318
+            + "paradise-lost.txt:Sing Heav'nly Muse, that on the secret top";
319
+
320
+        String actual = grepTool.grep(
321
+            "TO",
322
+            Collections.singletonList("-i"),
323
+            Arrays.asList("iliad.txt", "midsummer-night.txt", "paradise-lost.txt")
324
+        );
325
+
326
+        assertEquals(expected, actual);
327
+    }
328
+
329
+    @Ignore("Remove to run test")
330
+    @Test
331
+    public void multipleFilesSeveralMatchesInvertedFlag() {
332
+        String expected = "iliad.txt:Achilles sing, O Goddess! Peleus' son;\n"
333
+            + "iliad.txt:The noble Chief Achilles from the son\n"
334
+            + "midsummer-night.txt:If I refuse to wed Demetrius.";
335
+
336
+        String actual = grepTool.grep(
337
+            "a",
338
+            Collections.singletonList("-v"),
339
+            Arrays.asList("iliad.txt", "midsummer-night.txt", "paradise-lost.txt")
340
+        );
341
+
342
+        assertEquals(expected, actual);
343
+    }
344
+
345
+    @Ignore("Remove to run test")
346
+    @Test
347
+    public void multipleFilesOneMatchEntireLinesFlag() {
348
+        String expected = "midsummer-night.txt:But I beseech your grace that I may know";
349
+
350
+        String actual = grepTool.grep(
351
+            "But I beseech your grace that I may know",
352
+            Collections.singletonList("-x"),
353
+            Arrays.asList("iliad.txt", "midsummer-night.txt", "paradise-lost.txt")
354
+        );
355
+
356
+        assertEquals(expected, actual);
357
+    }
358
+
359
+    @Ignore("Remove to run test")
360
+    @Test
361
+    public void multipleFilesOneMatchMultipleFlags() {
362
+        String expected = "paradise-lost.txt:4:With loss of Eden, till one greater Man";
363
+
364
+        String actual = grepTool.grep(
365
+            "WITH LOSS OF EDEN, TILL ONE GREATER MAN",
366
+            Arrays.asList("-n", "-i", "-x"),
367
+            Arrays.asList("iliad.txt", "midsummer-night.txt", "paradise-lost.txt")
368
+        );
369
+
370
+        assertEquals(expected, actual);
371
+    }
372
+
373
+    @Ignore("Remove to run test")
374
+    @Test
375
+    public void multipleFilesNoMatchesVariousFlags() {
376
+        String expected = "";
377
+
378
+        String actual = grepTool.grep(
379
+            "Frodo",
380
+            Arrays.asList("-n", "-l", "-i", "-x"),
381
+            Arrays.asList("iliad.txt", "midsummer-night.txt", "paradise-lost.txt")
382
+        );
383
+
384
+        assertEquals(expected, actual);
385
+    }
386
+
387
+    private void writeToFile(String filename, List<String> contents) throws IOException {
388
+        Path file = Paths.get(filename);
389
+        Files.write(file, contents, Charset.forName("UTF-8"));
390
+    }
391
+
392
+    private void deleteFile(String filename) throws IOException {
393
+        Files.deleteIfExists(Paths.get(filename));
394
+    }
395
+}

+ 2
- 2
exercises/house/.meta/src/reference/java/House.java Visa fil

33
         verse.append("This is the " + CHARACTERS[verseNumber - 1]);
33
         verse.append("This is the " + CHARACTERS[verseNumber - 1]);
34
 
34
 
35
         for (int i = verseNumber - 2; i >= 0; i--) {
35
         for (int i = verseNumber - 2; i >= 0; i--) {
36
-            verse.append("\nthat " + ACTIONS[i] + " the " + CHARACTERS[i]);
36
+            verse.append(" that " + ACTIONS[i] + " the " + CHARACTERS[i]);
37
         }
37
         }
38
 
38
 
39
         return verse.toString();
39
         return verse.toString();
46
             verses[i - startVerse] = verse(i);
46
             verses[i - startVerse] = verse(i);
47
         }
47
         }
48
 
48
 
49
-        return String.join("\n\n", verses);
49
+        return String.join("\n", verses);
50
     }
50
     }
51
 
51
 
52
     String sing() {
52
     String sing() {

+ 1
- 1
exercises/house/.meta/version Visa fil

1
-2.0.0
1
+2.2.0

+ 157
- 172
exercises/house/src/test/java/HouseTest.java Visa fil

25
     @Test
25
     @Test
26
     public void verseTwo() {
26
     public void verseTwo() {
27
         String expected =
27
         String expected =
28
-                "This is the malt\n" +
28
+                "This is the malt " +
29
                 "that lay in the house that Jack built.";
29
                 "that lay in the house that Jack built.";
30
         int verse = 2;
30
         int verse = 2;
31
 
31
 
36
     @Test
36
     @Test
37
     public void verseThree() {
37
     public void verseThree() {
38
         String expected =
38
         String expected =
39
-                "This is the rat\n" +
40
-                "that ate the malt\n" +
39
+                "This is the rat " +
40
+                "that ate the malt " +
41
                 "that lay in the house that Jack built.";
41
                 "that lay in the house that Jack built.";
42
         int verse = 3;
42
         int verse = 3;
43
 
43
 
48
     @Test
48
     @Test
49
     public void verseFour() {
49
     public void verseFour() {
50
         String expected =
50
         String expected =
51
-                "This is the cat\n" +
52
-                "that killed the rat\n" +
53
-                "that ate the malt\n" +
51
+                "This is the cat " +
52
+                "that killed the rat " +
53
+                "that ate the malt " +
54
                 "that lay in the house that Jack built.";
54
                 "that lay in the house that Jack built.";
55
         int verse = 4;
55
         int verse = 4;
56
 
56
 
61
     @Test
61
     @Test
62
     public void verseFive() {
62
     public void verseFive() {
63
         String expected =
63
         String expected =
64
-                "This is the dog\n" +
65
-                "that worried the cat\n" +
66
-                "that killed the rat\n" +
67
-                "that ate the malt\n" +
64
+                "This is the dog " +
65
+                "that worried the cat " +
66
+                "that killed the rat " +
67
+                "that ate the malt " +
68
                 "that lay in the house that Jack built.";
68
                 "that lay in the house that Jack built.";
69
         int verse = 5;
69
         int verse = 5;
70
 
70
 
75
     @Test
75
     @Test
76
     public void verseSix() {
76
     public void verseSix() {
77
         String expected =
77
         String expected =
78
-                "This is the cow with the crumpled horn\n" +
79
-                "that tossed the dog\n" +
80
-                "that worried the cat\n" +
81
-                "that killed the rat\n" +
82
-                "that ate the malt\n" +
78
+                "This is the cow with the crumpled horn " +
79
+                "that tossed the dog " +
80
+                "that worried the cat " +
81
+                "that killed the rat " +
82
+                "that ate the malt " +
83
                 "that lay in the house that Jack built.";
83
                 "that lay in the house that Jack built.";
84
         int verse = 6;
84
         int verse = 6;
85
 
85
 
90
     @Test
90
     @Test
91
     public void verseSeven() {
91
     public void verseSeven() {
92
         String expected =
92
         String expected =
93
-                "This is the maiden all forlorn\n" +
94
-                "that milked the cow with the crumpled horn\n" +
95
-                "that tossed the dog\n" +
96
-                "that worried the cat\n" +
97
-                "that killed the rat\n" +
98
-                "that ate the malt\n" +
93
+                "This is the maiden all forlorn " +
94
+                "that milked the cow with the crumpled horn " +
95
+                "that tossed the dog " +
96
+                "that worried the cat " +
97
+                "that killed the rat " +
98
+                "that ate the malt " +
99
                 "that lay in the house that Jack built.";
99
                 "that lay in the house that Jack built.";
100
         int verse = 7;
100
         int verse = 7;
101
 
101
 
106
     @Test
106
     @Test
107
     public void verseEight() {
107
     public void verseEight() {
108
         String expected =
108
         String expected =
109
-                "This is the man all tattered and torn\n" +
110
-                "that kissed the maiden all forlorn\n" +
111
-                "that milked the cow with the crumpled horn\n" +
112
-                "that tossed the dog\n" +
113
-                "that worried the cat\n" +
114
-                "that killed the rat\n" +
115
-                "that ate the malt\n" +
109
+                "This is the man all tattered and torn " +
110
+                "that kissed the maiden all forlorn " +
111
+                "that milked the cow with the crumpled horn " +
112
+                "that tossed the dog " +
113
+                "that worried the cat " +
114
+                "that killed the rat " +
115
+                "that ate the malt " +
116
                 "that lay in the house that Jack built.";
116
                 "that lay in the house that Jack built.";
117
         int verse = 8;
117
         int verse = 8;
118
 
118
 
123
     @Test
123
     @Test
124
     public void verseNine() {
124
     public void verseNine() {
125
         String expected =
125
         String expected =
126
-                "This is the priest all shaven and shorn\n" +
127
-                "that married the man all tattered and torn\n" +
128
-                "that kissed the maiden all forlorn\n" +
129
-                "that milked the cow with the crumpled horn\n" +
130
-                "that tossed the dog\n" +
131
-                "that worried the cat\n" +
132
-                "that killed the rat\n" +
133
-                "that ate the malt\n" +
126
+                "This is the priest all shaven and shorn " +
127
+                "that married the man all tattered and torn " +
128
+                "that kissed the maiden all forlorn " +
129
+                "that milked the cow with the crumpled horn " +
130
+                "that tossed the dog " +
131
+                "that worried the cat " +
132
+                "that killed the rat " +
133
+                "that ate the malt " +
134
                 "that lay in the house that Jack built.";
134
                 "that lay in the house that Jack built.";
135
         int verse = 9;
135
         int verse = 9;
136
 
136
 
141
     @Test
141
     @Test
142
     public void verse10() {
142
     public void verse10() {
143
         String expected =
143
         String expected =
144
-                "This is the rooster that crowed in the morn\n" +
145
-                "that woke the priest all shaven and shorn\n" +
146
-                "that married the man all tattered and torn\n" +
147
-                "that kissed the maiden all forlorn\n" +
148
-                "that milked the cow with the crumpled horn\n" +
149
-                "that tossed the dog\n" +
150
-                "that worried the cat\n" +
151
-                "that killed the rat\n" +
152
-                "that ate the malt\n" +
144
+                "This is the rooster that crowed in the morn " +
145
+                "that woke the priest all shaven and shorn " +
146
+                "that married the man all tattered and torn " +
147
+                "that kissed the maiden all forlorn " +
148
+                "that milked the cow with the crumpled horn " +
149
+                "that tossed the dog " +
150
+                "that worried the cat " +
151
+                "that killed the rat " +
152
+                "that ate the malt " +
153
                 "that lay in the house that Jack built.";
153
                 "that lay in the house that Jack built.";
154
         int verse = 10;
154
         int verse = 10;
155
 
155
 
160
     @Test
160
     @Test
161
     public void verse11() {
161
     public void verse11() {
162
         String expected =
162
         String expected =
163
-                "This is the farmer sowing his corn\n" +
164
-                "that kept the rooster that crowed in the morn\n" +
165
-                "that woke the priest all shaven and shorn\n" +
166
-                "that married the man all tattered and torn\n" +
167
-                "that kissed the maiden all forlorn\n" +
168
-                "that milked the cow with the crumpled horn\n" +
169
-                "that tossed the dog\n" +
170
-                "that worried the cat\n" +
171
-                "that killed the rat\n" +
172
-                "that ate the malt\n" +
163
+                "This is the farmer sowing his corn " +
164
+                "that kept the rooster that crowed in the morn " +
165
+                "that woke the priest all shaven and shorn " +
166
+                "that married the man all tattered and torn " +
167
+                "that kissed the maiden all forlorn " +
168
+                "that milked the cow with the crumpled horn " +
169
+                "that tossed the dog " +
170
+                "that worried the cat " +
171
+                "that killed the rat " +
172
+                "that ate the malt " +
173
                 "that lay in the house that Jack built.";
173
                 "that lay in the house that Jack built.";
174
         int verse = 11;
174
         int verse = 11;
175
 
175
 
180
     @Test
180
     @Test
181
     public void verse12() {
181
     public void verse12() {
182
         String expected =
182
         String expected =
183
-                "This is the horse and the hound and the horn\n" +
184
-                "that belonged to the farmer sowing his corn\n" +
185
-                "that kept the rooster that crowed in the morn\n" +
186
-                "that woke the priest all shaven and shorn\n" +
187
-                "that married the man all tattered and torn\n" +
188
-                "that kissed the maiden all forlorn\n" +
189
-                "that milked the cow with the crumpled horn\n" +
190
-                "that tossed the dog\n" +
191
-                "that worried the cat\n" +
192
-                "that killed the rat\n" +
193
-                "that ate the malt\n" +
183
+                "This is the horse and the hound and the horn " +
184
+                "that belonged to the farmer sowing his corn " +
185
+                "that kept the rooster that crowed in the morn " +
186
+                "that woke the priest all shaven and shorn " +
187
+                "that married the man all tattered and torn " +
188
+                "that kissed the maiden all forlorn " +
189
+                "that milked the cow with the crumpled horn " +
190
+                "that tossed the dog " +
191
+                "that worried the cat " +
192
+                "that killed the rat " +
193
+                "that ate the malt " +
194
                 "that lay in the house that Jack built.";
194
                 "that lay in the house that Jack built.";
195
         int verse = 12;
195
         int verse = 12;
196
 
196
 
201
     @Test
201
     @Test
202
     public void multipleVerses() {
202
     public void multipleVerses() {
203
         String expected =
203
         String expected =
204
-                "This is the cat\n" +
205
-                "that killed the rat\n" +
206
-                "that ate the malt\n" +
204
+                "This is the cat " +
205
+                "that killed the rat " +
206
+                "that ate the malt " +
207
                 "that lay in the house that Jack built.\n" +
207
                 "that lay in the house that Jack built.\n" +
208
-                "\n" +
209
-                "This is the dog\n" +
210
-                "that worried the cat\n" +
211
-                "that killed the rat\n" +
212
-                "that ate the malt\n" +
208
+                "This is the dog " +
209
+                "that worried the cat " +
210
+                "that killed the rat " +
211
+                "that ate the malt " +
213
                 "that lay in the house that Jack built.\n" +
212
                 "that lay in the house that Jack built.\n" +
214
-                "\n" +
215
-                "This is the cow with the crumpled horn\n" +
216
-                "that tossed the dog\n" +
217
-                "that worried the cat\n" +
218
-                "that killed the rat\n" +
219
-                "that ate the malt\n" +
213
+                "This is the cow with the crumpled horn " +
214
+                "that tossed the dog " +
215
+                "that worried the cat " +
216
+                "that killed the rat " +
217
+                "that ate the malt " +
220
                 "that lay in the house that Jack built.\n" +
218
                 "that lay in the house that Jack built.\n" +
221
-                "\n" +
222
-                "This is the maiden all forlorn\n" +
223
-                "that milked the cow with the crumpled horn\n" +
224
-                "that tossed the dog\n" +
225
-                "that worried the cat\n" +
226
-                "that killed the rat\n" +
227
-                "that ate the malt\n" +
219
+                "This is the maiden all forlorn " +
220
+                "that milked the cow with the crumpled horn " +
221
+                "that tossed the dog " +
222
+                "that worried the cat " +
223
+                "that killed the rat " +
224
+                "that ate the malt " +
228
                 "that lay in the house that Jack built.\n" +
225
                 "that lay in the house that Jack built.\n" +
229
-                "\n" +
230
-                "This is the man all tattered and torn\n" +
231
-                "that kissed the maiden all forlorn\n" +
232
-                "that milked the cow with the crumpled horn\n" +
233
-                "that tossed the dog\n" +
234
-                "that worried the cat\n" +
235
-                "that killed the rat\n" +
236
-                "that ate the malt\n" +
226
+                "This is the man all tattered and torn " +
227
+                "that kissed the maiden all forlorn " +
228
+                "that milked the cow with the crumpled horn " +
229
+                "that tossed the dog " +
230
+                "that worried the cat " +
231
+                "that killed the rat " +
232
+                "that ate the malt " +
237
                 "that lay in the house that Jack built.";
233
                 "that lay in the house that Jack built.";
238
 
234
 
239
         int startVerse = 4;
235
         int startVerse = 4;
247
     public void wholeRhyme() {
243
     public void wholeRhyme() {
248
         String expected =
244
         String expected =
249
                 "This is the house that Jack built.\n" +
245
                 "This is the house that Jack built.\n" +
250
-                "\n" +
251
-                "This is the malt\n" +
246
+                "This is the malt " +
252
                 "that lay in the house that Jack built.\n" +
247
                 "that lay in the house that Jack built.\n" +
253
-                "\n" +
254
-                "This is the rat\n" +
255
-                "that ate the malt\n" +
248
+                "This is the rat " +
249
+                "that ate the malt " +
256
                 "that lay in the house that Jack built.\n" +
250
                 "that lay in the house that Jack built.\n" +
257
-                "\n" +
258
-                "This is the cat\n" +
259
-                "that killed the rat\n" +
260
-                "that ate the malt\n" +
251
+                "This is the cat " +
252
+                "that killed the rat " +
253
+                "that ate the malt " +
261
                 "that lay in the house that Jack built.\n" +
254
                 "that lay in the house that Jack built.\n" +
262
-                "\n" +
263
-                "This is the dog\n" +
264
-                "that worried the cat\n" +
265
-                "that killed the rat\n" +
266
-                "that ate the malt\n" +
255
+                "This is the dog " +
256
+                "that worried the cat " +
257
+                "that killed the rat " +
258
+                "that ate the malt " +
267
                 "that lay in the house that Jack built.\n" +
259
                 "that lay in the house that Jack built.\n" +
268
-                "\n" +
269
-                "This is the cow with the crumpled horn\n" +
270
-                "that tossed the dog\n" +
271
-                "that worried the cat\n" +
272
-                "that killed the rat\n" +
273
-                "that ate the malt\n" +
260
+                "This is the cow with the crumpled horn " +
261
+                "that tossed the dog " +
262
+                "that worried the cat " +
263
+                "that killed the rat " +
264
+                "that ate the malt " +
274
                 "that lay in the house that Jack built.\n" +
265
                 "that lay in the house that Jack built.\n" +
275
-                "\n" +
276
-                "This is the maiden all forlorn\n" +
277
-                "that milked the cow with the crumpled horn\n" +
278
-                "that tossed the dog\n" +
279
-                "that worried the cat\n" +
280
-                "that killed the rat\n" +
281
-                "that ate the malt\n" +
266
+                "This is the maiden all forlorn " +
267
+                "that milked the cow with the crumpled horn " +
268
+                "that tossed the dog " +
269
+                "that worried the cat " +
270
+                "that killed the rat " +
271
+                "that ate the malt " +
282
                 "that lay in the house that Jack built.\n" +
272
                 "that lay in the house that Jack built.\n" +
283
-                "\n" +
284
-                "This is the man all tattered and torn\n" +
285
-                "that kissed the maiden all forlorn\n" +
286
-                "that milked the cow with the crumpled horn\n" +
287
-                "that tossed the dog\n" +
288
-                "that worried the cat\n" +
289
-                "that killed the rat\n" +
290
-                "that ate the malt\n" +
273
+                "This is the man all tattered and torn " +
274
+                "that kissed the maiden all forlorn " +
275
+                "that milked the cow with the crumpled horn " +
276
+                "that tossed the dog " +
277
+                "that worried the cat " +
278
+                "that killed the rat " +
279
+                "that ate the malt " +
291
                 "that lay in the house that Jack built.\n" +
280
                 "that lay in the house that Jack built.\n" +
292
-                "\n" +
293
-                "This is the priest all shaven and shorn\n" +
294
-                "that married the man all tattered and torn\n" +
295
-                "that kissed the maiden all forlorn\n" +
296
-                "that milked the cow with the crumpled horn\n" +
297
-                "that tossed the dog\n" +
298
-                "that worried the cat\n" +
299
-                "that killed the rat\n" +
300
-                "that ate the malt\n" +
281
+                "This is the priest all shaven and shorn " +
282
+                "that married the man all tattered and torn " +
283
+                "that kissed the maiden all forlorn " +
284
+                "that milked the cow with the crumpled horn " +
285
+                "that tossed the dog " +
286
+                "that worried the cat " +
287
+                "that killed the rat " +
288
+                "that ate the malt " +
301
                 "that lay in the house that Jack built.\n" +
289
                 "that lay in the house that Jack built.\n" +
302
-                "\n" +
303
-                "This is the rooster that crowed in the morn\n" +
304
-                "that woke the priest all shaven and shorn\n" +
305
-                "that married the man all tattered and torn\n" +
306
-                "that kissed the maiden all forlorn\n" +
307
-                "that milked the cow with the crumpled horn\n" +
308
-                "that tossed the dog\n" +
309
-                "that worried the cat\n" +
310
-                "that killed the rat\n" +
311
-                "that ate the malt\n" +
290
+                "This is the rooster that crowed in the morn " +
291
+                "that woke the priest all shaven and shorn " +
292
+                "that married the man all tattered and torn " +
293
+                "that kissed the maiden all forlorn " +
294
+                "that milked the cow with the crumpled horn " +
295
+                "that tossed the dog " +
296
+                "that worried the cat " +
297
+                "that killed the rat " +
298
+                "that ate the malt " +
312
                 "that lay in the house that Jack built.\n" +
299
                 "that lay in the house that Jack built.\n" +
313
-                "\n" +
314
-                "This is the farmer sowing his corn\n" +
315
-                "that kept the rooster that crowed in the morn\n" +
316
-                "that woke the priest all shaven and shorn\n" +
317
-                "that married the man all tattered and torn\n" +
318
-                "that kissed the maiden all forlorn\n" +
319
-                "that milked the cow with the crumpled horn\n" +
320
-                "that tossed the dog\n" +
321
-                "that worried the cat\n" +
322
-                "that killed the rat\n" +
323
-                "that ate the malt\n" +
300
+                "This is the farmer sowing his corn " +
301
+                "that kept the rooster that crowed in the morn " +
302
+                "that woke the priest all shaven and shorn " +
303
+                "that married the man all tattered and torn " +
304
+                "that kissed the maiden all forlorn " +
305
+                "that milked the cow with the crumpled horn " +
306
+                "that tossed the dog " +
307
+                "that worried the cat " +
308
+                "that killed the rat " +
309
+                "that ate the malt " +
324
                 "that lay in the house that Jack built.\n" +
310
                 "that lay in the house that Jack built.\n" +
325
-                "\n" +
326
-                "This is the horse and the hound and the horn\n" +
327
-                "that belonged to the farmer sowing his corn\n" +
328
-                "that kept the rooster that crowed in the morn\n" +
329
-                "that woke the priest all shaven and shorn\n" +
330
-                "that married the man all tattered and torn\n" +
331
-                "that kissed the maiden all forlorn\n" +
332
-                "that milked the cow with the crumpled horn\n" +
333
-                "that tossed the dog\n" +
334
-                "that worried the cat\n" +
335
-                "that killed the rat\n" +
336
-                "that ate the malt\n" +
311
+                "This is the horse and the hound and the horn " +
312
+                "that belonged to the farmer sowing his corn " +
313
+                "that kept the rooster that crowed in the morn " +
314
+                "that woke the priest all shaven and shorn " +
315
+                "that married the man all tattered and torn " +
316
+                "that kissed the maiden all forlorn " +
317
+                "that milked the cow with the crumpled horn " +
318
+                "that tossed the dog " +
319
+                "that worried the cat " +
320
+                "that killed the rat " +
321
+                "that ate the malt " +
337
                 "that lay in the house that Jack built.";
322
                 "that lay in the house that Jack built.";
338
 
323
 
339
         assertEquals(expected, house.sing());
324
         assertEquals(expected, house.sing());

+ 1
- 1
exercises/isogram/.meta/version Visa fil

1
-1.2.0
1
+1.3.0

+ 36
- 36
exercises/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java Visa fil

12
 
12
 
13
     @Test
13
     @Test
14
     public void testCorrectlyCalculatesLargestProductWhenSeriesLengthEqualsStringToSearchLength() {
14
     public void testCorrectlyCalculatesLargestProductWhenSeriesLengthEqualsStringToSearchLength() {
15
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("29");
16
-        final long expectedProduct = 18;
15
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("29");
16
+        long expectedProduct = 18;
17
 
17
 
18
-        final long actualProduct = calculator.calculateLargestProductForSeriesLength(2);
18
+        long actualProduct = calculator.calculateLargestProductForSeriesLength(2);
19
 
19
 
20
         assertEquals(expectedProduct, actualProduct);
20
         assertEquals(expectedProduct, actualProduct);
21
     }
21
     }
23
     @Ignore("Remove to run test")
23
     @Ignore("Remove to run test")
24
     @Test
24
     @Test
25
     public void testCorrectlyCalculatesLargestProductOfLengthTwoWithNumbersInOrder() {
25
     public void testCorrectlyCalculatesLargestProductOfLengthTwoWithNumbersInOrder() {
26
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789");
27
-        final long expectedProduct = 72;
26
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789");
27
+        long expectedProduct = 72;
28
 
28
 
29
-        final long actualProduct = calculator.calculateLargestProductForSeriesLength(2);
29
+        long actualProduct = calculator.calculateLargestProductForSeriesLength(2);
30
 
30
 
31
         assertEquals(expectedProduct, actualProduct);
31
         assertEquals(expectedProduct, actualProduct);
32
     }
32
     }
34
     @Ignore("Remove to run test")
34
     @Ignore("Remove to run test")
35
     @Test
35
     @Test
36
     public void testCorrectlyCalculatesLargestProductOfLengthTwoWithNumbersNotInOrder() {
36
     public void testCorrectlyCalculatesLargestProductOfLengthTwoWithNumbersNotInOrder() {
37
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("576802143");
38
-        final long expectedProduct = 48;
37
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("576802143");
38
+        long expectedProduct = 48;
39
 
39
 
40
-        final long actualProduct = calculator.calculateLargestProductForSeriesLength(2);
40
+        long actualProduct = calculator.calculateLargestProductForSeriesLength(2);
41
 
41
 
42
         assertEquals(expectedProduct, actualProduct);
42
         assertEquals(expectedProduct, actualProduct);
43
     }
43
     }
45
     @Ignore("Remove to run test")
45
     @Ignore("Remove to run test")
46
     @Test
46
     @Test
47
     public void testCorrectlyCalculatesLargestProductOfLengthThreeWithNumbersInOrder() {
47
     public void testCorrectlyCalculatesLargestProductOfLengthThreeWithNumbersInOrder() {
48
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789");
49
-        final long expectedProduct = 504;
48
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789");
49
+        long expectedProduct = 504;
50
 
50
 
51
-        final long actualProduct = calculator.calculateLargestProductForSeriesLength(3);
51
+        long actualProduct = calculator.calculateLargestProductForSeriesLength(3);
52
 
52
 
53
         assertEquals(expectedProduct, actualProduct);
53
         assertEquals(expectedProduct, actualProduct);
54
     }
54
     }
56
     @Ignore("Remove to run test")
56
     @Ignore("Remove to run test")
57
     @Test
57
     @Test
58
     public void testCorrectlyCalculatesLargestProductOfLengthThreeWithNumbersNotInOrder() {
58
     public void testCorrectlyCalculatesLargestProductOfLengthThreeWithNumbersNotInOrder() {
59
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("1027839564");
60
-        final long expectedProduct = 270;
59
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("1027839564");
60
+        long expectedProduct = 270;
61
 
61
 
62
-        final long actualProduct = calculator.calculateLargestProductForSeriesLength(3);
62
+        long actualProduct = calculator.calculateLargestProductForSeriesLength(3);
63
 
63
 
64
         assertEquals(expectedProduct, actualProduct);
64
         assertEquals(expectedProduct, actualProduct);
65
     }
65
     }
67
     @Ignore("Remove to run test")
67
     @Ignore("Remove to run test")
68
     @Test
68
     @Test
69
     public void testCorrectlyCalculatesLargestProductOfLengthFiveWithNumbersInOrder() {
69
     public void testCorrectlyCalculatesLargestProductOfLengthFiveWithNumbersInOrder() {
70
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789");
71
-        final long expectedProduct = 15120;
70
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0123456789");
71
+        long expectedProduct = 15120;
72
 
72
 
73
-        final long actualProduct = calculator.calculateLargestProductForSeriesLength(5);
73
+        long actualProduct = calculator.calculateLargestProductForSeriesLength(5);
74
 
74
 
75
         assertEquals(expectedProduct, actualProduct);
75
         assertEquals(expectedProduct, actualProduct);
76
     }
76
     }
78
     @Ignore("Remove to run test")
78
     @Ignore("Remove to run test")
79
     @Test
79
     @Test
80
     public void testCorrectlyCalculatesLargestProductInLongStringToSearchV1() {
80
     public void testCorrectlyCalculatesLargestProductInLongStringToSearchV1() {
81
-        final LargestSeriesProductCalculator calculator
81
+        LargestSeriesProductCalculator calculator
82
                 = new LargestSeriesProductCalculator("73167176531330624919225119674426574742355349194934");
82
                 = new LargestSeriesProductCalculator("73167176531330624919225119674426574742355349194934");
83
 
83
 
84
-        final long expectedProduct = 23520;
84
+        long expectedProduct = 23520;
85
 
85
 
86
-        final long actualProduct = calculator.calculateLargestProductForSeriesLength(6);
86
+        long actualProduct = calculator.calculateLargestProductForSeriesLength(6);
87
 
87
 
88
         assertEquals(expectedProduct, actualProduct);
88
         assertEquals(expectedProduct, actualProduct);
89
     }
89
     }
91
     @Ignore("Remove to run test")
91
     @Ignore("Remove to run test")
92
     @Test
92
     @Test
93
     public void testCorrectlyCalculatesLargestProductOfZeroIfAllDigitsAreZeroes() {
93
     public void testCorrectlyCalculatesLargestProductOfZeroIfAllDigitsAreZeroes() {
94
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0000");
95
-        final long expectedProduct = 0;
94
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("0000");
95
+        long expectedProduct = 0;
96
 
96
 
97
-        final long actualProduct = calculator.calculateLargestProductForSeriesLength(2);
97
+        long actualProduct = calculator.calculateLargestProductForSeriesLength(2);
98
 
98
 
99
         assertEquals(expectedProduct, actualProduct);
99
         assertEquals(expectedProduct, actualProduct);
100
     }
100
     }
102
     @Ignore("Remove to run test")
102
     @Ignore("Remove to run test")
103
     @Test
103
     @Test
104
     public void testCorrectlyCalculatesLargestProductOfZeroIfAllSeriesOfGivenLengthContainZero() {
104
     public void testCorrectlyCalculatesLargestProductOfZeroIfAllSeriesOfGivenLengthContainZero() {
105
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("99099");
106
-        final long expectedProduct = 0;
105
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("99099");
106
+        long expectedProduct = 0;
107
 
107
 
108
-        final long actualProduct = calculator.calculateLargestProductForSeriesLength(3);
108
+        long actualProduct = calculator.calculateLargestProductForSeriesLength(3);
109
 
109
 
110
         assertEquals(expectedProduct, actualProduct);
110
         assertEquals(expectedProduct, actualProduct);
111
     }
111
     }
113
     @Ignore("Remove to run test")
113
     @Ignore("Remove to run test")
114
     @Test
114
     @Test
115
     public void testSeriesLengthLongerThanLengthOfStringToTestIsRejected() {
115
     public void testSeriesLengthLongerThanLengthOfStringToTestIsRejected() {
116
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("123");
116
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("123");
117
 
117
 
118
         expectedException.expect(IllegalArgumentException.class);
118
         expectedException.expect(IllegalArgumentException.class);
119
         expectedException.expectMessage(
119
         expectedException.expectMessage(
125
     @Ignore("Remove to run test")
125
     @Ignore("Remove to run test")
126
     @Test
126
     @Test
127
     public void testCorrectlyCalculatesLargestProductOfLength0ForEmptyStringToSearch() {
127
     public void testCorrectlyCalculatesLargestProductOfLength0ForEmptyStringToSearch() {
128
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("");
129
-        final long expectedProduct = 1;
128
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("");
129
+        long expectedProduct = 1;
130
 
130
 
131
-        final long actualProduct = calculator.calculateLargestProductForSeriesLength(0);
131
+        long actualProduct = calculator.calculateLargestProductForSeriesLength(0);
132
 
132
 
133
         assertEquals(expectedProduct, actualProduct);
133
         assertEquals(expectedProduct, actualProduct);
134
     }
134
     }
136
     @Ignore("Remove to run test")
136
     @Ignore("Remove to run test")
137
     @Test
137
     @Test
138
     public void testCorrectlyCalculatesLargestProductOfLength0ForNonEmptyStringToSearch() {
138
     public void testCorrectlyCalculatesLargestProductOfLength0ForNonEmptyStringToSearch() {
139
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("123");
140
-        final long expectedProduct = 1;
139
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("123");
140
+        long expectedProduct = 1;
141
 
141
 
142
-        final long actualProduct = calculator.calculateLargestProductForSeriesLength(0);
142
+        long actualProduct = calculator.calculateLargestProductForSeriesLength(0);
143
 
143
 
144
         assertEquals(expectedProduct, actualProduct);
144
         assertEquals(expectedProduct, actualProduct);
145
     }
145
     }
147
     @Ignore("Remove to run test")
147
     @Ignore("Remove to run test")
148
     @Test
148
     @Test
149
     public void testEmptyStringToSearchAndSeriesOfNonZeroLengthIsRejected() {
149
     public void testEmptyStringToSearchAndSeriesOfNonZeroLengthIsRejected() {
150
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("");
150
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("");
151
 
151
 
152
         expectedException.expect(IllegalArgumentException.class);
152
         expectedException.expect(IllegalArgumentException.class);
153
         expectedException.expectMessage(
153
         expectedException.expectMessage(
168
     @Ignore("Remove to run test")
168
     @Ignore("Remove to run test")
169
     @Test
169
     @Test
170
     public void testNegativeSeriesLengthIsRejected() {
170
     public void testNegativeSeriesLengthIsRejected() {
171
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("12345");
171
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("12345");
172
 
172
 
173
         expectedException.expect(IllegalArgumentException.class);
173
         expectedException.expect(IllegalArgumentException.class);
174
         expectedException.expectMessage("Series length must be non-negative.");
174
         expectedException.expectMessage("Series length must be non-negative.");

+ 1
- 1
exercises/list-ops/.meta/version Visa fil

1
-2.0.0
1
+2.2.0

+ 1
- 1
exercises/markdown/.meta/version Visa fil

1
-1.1.0
1
+1.2.0

+ 1
- 1
exercises/minesweeper/.meta/version Visa fil

1
-1.0.0
1
+1.1.0

+ 36
- 36
exercises/minesweeper/src/test/java/MinesweeperBoardTest.java Visa fil

11
 
11
 
12
     @Test
12
     @Test
13
     public void testInputBoardWithNoRowsAndNoColumns() {
13
     public void testInputBoardWithNoRowsAndNoColumns() {
14
-        final List<String> inputBoard = Collections.emptyList();
15
-        final List<String> expectedNumberedBoard = Collections.emptyList();
16
-        final List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
14
+        List<String> inputBoard = Collections.emptyList();
15
+        List<String> expectedNumberedBoard = Collections.emptyList();
16
+        List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
17
 
17
 
18
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
18
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
19
     }
19
     }
21
     @Ignore("Remove to run test")
21
     @Ignore("Remove to run test")
22
     @Test
22
     @Test
23
     public void testInputBoardWithOneRowAndNoColumns() {
23
     public void testInputBoardWithOneRowAndNoColumns() {
24
-        final List<String> inputBoard = Collections.singletonList("");
25
-        final List<String> expectedNumberedBoard = Collections.singletonList("");
26
-        final List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
24
+        List<String> inputBoard = Collections.singletonList("");
25
+        List<String> expectedNumberedBoard = Collections.singletonList("");
26
+        List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
27
 
27
 
28
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
28
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
29
     }
29
     }
31
     @Ignore("Remove to run test")
31
     @Ignore("Remove to run test")
32
     @Test
32
     @Test
33
     public void testInputBoardWithNoMines() {
33
     public void testInputBoardWithNoMines() {
34
-        final List<String> inputBoard = Arrays.asList(
34
+        List<String> inputBoard = Arrays.asList(
35
                 "   ",
35
                 "   ",
36
                 "   ",
36
                 "   ",
37
                 "   "
37
                 "   "
38
         );
38
         );
39
 
39
 
40
-        final List<String> expectedNumberedBoard = Arrays.asList(
40
+        List<String> expectedNumberedBoard = Arrays.asList(
41
                 "   ",
41
                 "   ",
42
                 "   ",
42
                 "   ",
43
                 "   "
43
                 "   "
44
         );
44
         );
45
 
45
 
46
-        final List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
46
+        List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
47
 
47
 
48
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
48
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
49
     }
49
     }
51
     @Ignore("Remove to run test")
51
     @Ignore("Remove to run test")
52
     @Test
52
     @Test
53
     public void testInputBoardWithOnlyMines() {
53
     public void testInputBoardWithOnlyMines() {
54
-        final List<String> inputBoard = Arrays.asList(
54
+        List<String> inputBoard = Arrays.asList(
55
                 "***",
55
                 "***",
56
                 "***",
56
                 "***",
57
                 "***"
57
                 "***"
58
         );
58
         );
59
 
59
 
60
-        final List<String> expectedNumberedBoard = Arrays.asList(
60
+        List<String> expectedNumberedBoard = Arrays.asList(
61
                 "***",
61
                 "***",
62
                 "***",
62
                 "***",
63
                 "***"
63
                 "***"
64
         );
64
         );
65
 
65
 
66
-        final List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
66
+        List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
67
 
67
 
68
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
68
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
69
     }
69
     }
71
     @Ignore("Remove to run test")
71
     @Ignore("Remove to run test")
72
     @Test
72
     @Test
73
     public void testInputBoardWithSingleMineAtCenter() {
73
     public void testInputBoardWithSingleMineAtCenter() {
74
-        final List<String> inputBoard = Arrays.asList(
74
+        List<String> inputBoard = Arrays.asList(
75
                 "   ",
75
                 "   ",
76
                 " * ",
76
                 " * ",
77
                 "   "
77
                 "   "
78
         );
78
         );
79
 
79
 
80
-        final List<String> expectedNumberedBoard = Arrays.asList(
80
+        List<String> expectedNumberedBoard = Arrays.asList(
81
                 "111",
81
                 "111",
82
                 "1*1",
82
                 "1*1",
83
                 "111"
83
                 "111"
84
         );
84
         );
85
 
85
 
86
-        final List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
86
+        List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
87
 
87
 
88
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
88
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
89
     }
89
     }
91
     @Ignore("Remove to run test")
91
     @Ignore("Remove to run test")
92
     @Test
92
     @Test
93
     public void testInputBoardWithMinesAroundPerimeter() {
93
     public void testInputBoardWithMinesAroundPerimeter() {
94
-        final List<String> inputBoard = Arrays.asList(
94
+        List<String> inputBoard = Arrays.asList(
95
                 "***",
95
                 "***",
96
                 "* *",
96
                 "* *",
97
                 "***"
97
                 "***"
98
         );
98
         );
99
 
99
 
100
-        final List<String> expectedNumberedBoard = Arrays.asList(
100
+        List<String> expectedNumberedBoard = Arrays.asList(
101
                 "***",
101
                 "***",
102
                 "*8*",
102
                 "*8*",
103
                 "***"
103
                 "***"
104
         );
104
         );
105
 
105
 
106
-        final List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
106
+        List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
107
 
107
 
108
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
108
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
109
     }
109
     }
111
     @Ignore("Remove to run test")
111
     @Ignore("Remove to run test")
112
     @Test
112
     @Test
113
     public void testInputBoardWithSingleRowAndTwoMines() {
113
     public void testInputBoardWithSingleRowAndTwoMines() {
114
-        final List<String> inputBoard = Collections.singletonList(
114
+        List<String> inputBoard = Collections.singletonList(
115
                 " * * "
115
                 " * * "
116
         );
116
         );
117
 
117
 
118
-        final List<String> expectedNumberedBoard = Collections.singletonList(
118
+        List<String> expectedNumberedBoard = Collections.singletonList(
119
                 "1*2*1"
119
                 "1*2*1"
120
         );
120
         );
121
 
121
 
122
-        final List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
122
+        List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
123
 
123
 
124
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
124
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
125
     }
125
     }
127
     @Ignore("Remove to run test")
127
     @Ignore("Remove to run test")
128
     @Test
128
     @Test
129
     public void testInputBoardWithSingleRowAndTwoMinesAtEdges() {
129
     public void testInputBoardWithSingleRowAndTwoMinesAtEdges() {
130
-        final List<String> inputBoard = Collections.singletonList(
130
+        List<String> inputBoard = Collections.singletonList(
131
                 "*   *"
131
                 "*   *"
132
         );
132
         );
133
 
133
 
134
-        final List<String> expectedNumberedBoard = Collections.singletonList(
134
+        List<String> expectedNumberedBoard = Collections.singletonList(
135
                 "*1 1*"
135
                 "*1 1*"
136
         );
136
         );
137
 
137
 
138
-        final List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
138
+        List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
139
 
139
 
140
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
140
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
141
     }
141
     }
143
     @Ignore("Remove to run test")
143
     @Ignore("Remove to run test")
144
     @Test
144
     @Test
145
     public void testInputBoardWithSingleColumnAndTwoMines() {
145
     public void testInputBoardWithSingleColumnAndTwoMines() {
146
-        final List<String> inputBoard = Arrays.asList(
146
+        List<String> inputBoard = Arrays.asList(
147
                 " ",
147
                 " ",
148
                 "*",
148
                 "*",
149
                 " ",
149
                 " ",
151
                 " "
151
                 " "
152
         );
152
         );
153
 
153
 
154
-        final List<String> expectedNumberedBoard = Arrays.asList(
154
+        List<String> expectedNumberedBoard = Arrays.asList(
155
                 "1",
155
                 "1",
156
                 "*",
156
                 "*",
157
                 "2",
157
                 "2",
159
                 "1"
159
                 "1"
160
         );
160
         );
161
 
161
 
162
-        final List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
162
+        List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
163
 
163
 
164
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
164
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
165
     }
165
     }
167
     @Ignore("Remove to run test")
167
     @Ignore("Remove to run test")
168
     @Test
168
     @Test
169
     public void testInputBoardWithSingleColumnAndTwoMinesAtEdges() {
169
     public void testInputBoardWithSingleColumnAndTwoMinesAtEdges() {
170
-        final List<String> inputBoard = Arrays.asList(
170
+        List<String> inputBoard = Arrays.asList(
171
                 "*",
171
                 "*",
172
                 " ",
172
                 " ",
173
                 " ",
173
                 " ",
175
                 "*"
175
                 "*"
176
         );
176
         );
177
 
177
 
178
-        final List<String> expectedNumberedBoard = Arrays.asList(
178
+        List<String> expectedNumberedBoard = Arrays.asList(
179
                 "*",
179
                 "*",
180
                 "1",
180
                 "1",
181
                 " ",
181
                 " ",
183
                 "*"
183
                 "*"
184
         );
184
         );
185
 
185
 
186
-        final List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
186
+        List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
187
 
187
 
188
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
188
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
189
     }
189
     }
191
     @Ignore("Remove to run test")
191
     @Ignore("Remove to run test")
192
     @Test
192
     @Test
193
     public void testInputBoardWithMinesInCross() {
193
     public void testInputBoardWithMinesInCross() {
194
-        final List<String> inputBoard = Arrays.asList(
194
+        List<String> inputBoard = Arrays.asList(
195
                 "  *  ",
195
                 "  *  ",
196
                 "  *  ",
196
                 "  *  ",
197
                 "*****",
197
                 "*****",
199
                 "  *  "
199
                 "  *  "
200
         );
200
         );
201
 
201
 
202
-        final List<String> expectedNumberedBoard = Arrays.asList(
202
+        List<String> expectedNumberedBoard = Arrays.asList(
203
                 " 2*2 ",
203
                 " 2*2 ",
204
                 "25*52",
204
                 "25*52",
205
                 "*****",
205
                 "*****",
207
                 " 2*2 "
207
                 " 2*2 "
208
         );
208
         );
209
 
209
 
210
-        final List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
210
+        List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
211
 
211
 
212
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
212
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
213
     }
213
     }
215
     @Ignore("Remove to run test")
215
     @Ignore("Remove to run test")
216
     @Test
216
     @Test
217
     public void testLargeInputBoard() {
217
     public void testLargeInputBoard() {
218
-        final List<String> inputBoard = Arrays.asList(
218
+        List<String> inputBoard = Arrays.asList(
219
                 " *  * ",
219
                 " *  * ",
220
                 "  *   ",
220
                 "  *   ",
221
                 "    * ",
221
                 "    * ",
224
                 "      "
224
                 "      "
225
         );
225
         );
226
 
226
 
227
-        final List<String> expectedNumberedBoard = Arrays.asList(
227
+        List<String> expectedNumberedBoard = Arrays.asList(
228
                 "1*22*1",
228
                 "1*22*1",
229
                 "12*322",
229
                 "12*322",
230
                 " 123*2",
230
                 " 123*2",
233
                 "111111"
233
                 "111111"
234
         );
234
         );
235
 
235
 
236
-        final List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
236
+        List<String> actualNumberedBoard = new MinesweeperBoard(inputBoard).withNumbers();
237
 
237
 
238
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
238
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
239
     }
239
     }

+ 1
- 1
exercises/nth-prime/.meta/version Visa fil

1
-2.0.0
1
+2.1.0

+ 1
- 1
exercises/ocr-numbers/.meta/version Visa fil

1
-1.0.0
1
+1.1.0

+ 1
- 1
exercises/perfect-numbers/.meta/version Visa fil

1
-1.0.1
1
+1.1.0

+ 14
- 14
exercises/phone-number/src/test/java/PhoneNumberTest.java Visa fil

6
 import static org.junit.Assert.assertEquals;
6
 import static org.junit.Assert.assertEquals;
7
 
7
 
8
 public class PhoneNumberTest {
8
 public class PhoneNumberTest {
9
-    private final static String wrongLengthExceptionMessage = "Number must be 10 or 11 digits";
10
-    private final static String numberIs11DigitsButDoesNotStartWith1ExceptionMessage =
9
+    private static String wrongLengthExceptionMessage = "Number must be 10 or 11 digits";
10
+    private static String numberIs11DigitsButDoesNotStartWith1ExceptionMessage =
11
             "Can only have 11 digits if number starts with '1'";
11
             "Can only have 11 digits if number starts with '1'";
12
-    private final static String illegalCharacterExceptionMessage =
12
+    private static String illegalCharacterExceptionMessage =
13
             "Illegal character in phone number. Only digits, spaces, parentheses, hyphens or dots accepted.";
13
             "Illegal character in phone number. Only digits, spaces, parentheses, hyphens or dots accepted.";
14
-    private final static String illegalAreaOrExchangeCodeMessage =
14
+    private static String illegalAreaOrExchangeCodeMessage =
15
             "Illegal Area Or Exchange Code. Only 2-9 are valid digits";
15
             "Illegal Area Or Exchange Code. Only 2-9 are valid digits";
16
 
16
 
17
     @Rule
17
     @Rule
19
 
19
 
20
     @Test
20
     @Test
21
     public void cleansTheNumber() {
21
     public void cleansTheNumber() {
22
-        final String expectedNumber = "2234567890";
23
-        final String actualNumber = new PhoneNumber("(223) 456-7890").getNumber();
22
+        String expectedNumber = "2234567890";
23
+        String actualNumber = new PhoneNumber("(223) 456-7890").getNumber();
24
 
24
 
25
         assertEquals(
25
         assertEquals(
26
                 expectedNumber, actualNumber
26
                 expectedNumber, actualNumber
30
     @Ignore("Remove to run test")
30
     @Ignore("Remove to run test")
31
     @Test
31
     @Test
32
     public void cleansNumbersWithDots() {
32
     public void cleansNumbersWithDots() {
33
-        final String expectedNumber = "2234567890";
34
-        final String actualNumber = new PhoneNumber("223.456.7890").getNumber();
33
+        String expectedNumber = "2234567890";
34
+        String actualNumber = new PhoneNumber("223.456.7890").getNumber();
35
 
35
 
36
         assertEquals(
36
         assertEquals(
37
                 expectedNumber, actualNumber
37
                 expectedNumber, actualNumber
41
     @Ignore("Remove to run test")
41
     @Ignore("Remove to run test")
42
     @Test
42
     @Test
43
     public void cleansNumbersWithMultipleSpaces() {
43
     public void cleansNumbersWithMultipleSpaces() {
44
-        final String expectedNumber = "2234567890";
45
-        final String actualNumber = new PhoneNumber("223 456   7890   ").getNumber();
44
+        String expectedNumber = "2234567890";
45
+        String actualNumber = new PhoneNumber("223 456   7890   ").getNumber();
46
 
46
 
47
         assertEquals(
47
         assertEquals(
48
                 expectedNumber, actualNumber
48
                 expectedNumber, actualNumber
68
     @Ignore("Remove to run test")
68
     @Ignore("Remove to run test")
69
     @Test
69
     @Test
70
     public void validWhen11DigitsAndStartingWith1() {
70
     public void validWhen11DigitsAndStartingWith1() {
71
-        final String expectedNumber = "2234567890";
72
-        final String actualNumber = new PhoneNumber("12234567890").getNumber();
71
+        String expectedNumber = "2234567890";
72
+        String actualNumber = new PhoneNumber("12234567890").getNumber();
73
 
73
 
74
         assertEquals(
74
         assertEquals(
75
                 expectedNumber, actualNumber
75
                 expectedNumber, actualNumber
79
     @Ignore("Remove to run test")
79
     @Ignore("Remove to run test")
80
     @Test
80
     @Test
81
     public void validWhen11DigitsAndStartingWith1EvenWithPunctuation() {
81
     public void validWhen11DigitsAndStartingWith1EvenWithPunctuation() {
82
-        final String expectedNumber = "2234567890";
83
-        final String actualNumber = new PhoneNumber("+1 (223) 456-7890").getNumber();
82
+        String expectedNumber = "2234567890";
83
+        String actualNumber = new PhoneNumber("+1 (223) 456-7890").getNumber();
84
 
84
 
85
         assertEquals(
85
         assertEquals(
86
                 expectedNumber, actualNumber
86
                 expectedNumber, actualNumber

+ 4
- 4
exercises/pig-latin/README.md Visa fil

7
 quickly it's really difficult for non-children (and non-native speakers)
7
 quickly it's really difficult for non-children (and non-native speakers)
8
 to understand.
8
 to understand.
9
 
9
 
10
-- **Rule 1**: If a word begins with a vowel sound, add an "ay" sound to
11
-  the end of the word.
12
-- **Rule 2**: If a word begins with a consonant sound, move it to the
13
-  end of the word, and then add an "ay" sound to the end of the word.
10
+- **Rule 1**: If a word begins with a vowel sound, add an "ay" sound to the end of the word. Please note that "xr" and "yt" at the beginning of a word make vowel sounds (e.g. "xray" -> "xrayay", "yttria" -> "yttriaay").
11
+- **Rule 2**: If a word begins with a consonant sound, move it to the end of the word and then add an "ay" sound to the end of the word. Consonant sounds can be made up of multiple consonants, a.k.a. a consonant cluster (e.g. "chair" -> "airchay").
12
+- **Rule 3**: If a word starts with a consonant sound followed by "qu", move it to the end of the word, and then add an "ay" sound to the end of the word (e.g. "square" -> "aresquay").
13
+- **Rule 4**: If a word contains a "y" after a consonant cluster or as the second letter in a two letter word it makes a vowel sound (e.g. "rhythm" -> "ythmrhay", "my" -> "ymay").
14
 
14
 
15
 There are a few more rules for edge cases, and there are regional
15
 There are a few more rules for edge cases, and there are regional
16
 variants too.
16
 variants too.

+ 5
- 2
exercises/poker/.meta/src/reference/java/Card.java Visa fil

16
     }
16
     }
17
 
17
 
18
     private int parseRank(String card) {
18
     private int parseRank(String card) {
19
-        return "..23456789TJQKA".indexOf(card.charAt(0));
19
+    	if (card.substring(0, 2).equals("10")) {
20
+    		return 10;
21
+    	}
22
+    	return "..23456789TJQKA".indexOf(card.charAt(0));
20
     }
23
     }
21
 
24
 
22
     private int parseSuit(String card) {
25
     private int parseSuit(String card) {
23
-        return ".HSDC".indexOf(card.charAt(1));
26
+        return ".HSDC".indexOf(card.charAt(card.length() - 1));
24
     }
27
     }
25
 }
28
 }

+ 51
- 12
exercises/poker/.meta/src/reference/java/Hand.java Visa fil

38
         }
38
         }
39
         return frequencyMap;
39
         return frequencyMap;
40
     }
40
     }
41
-
41
+    
42
     private int scoreHand(List<Card> cards) {
42
     private int scoreHand(List<Card> cards) {
43
-        List<Card> cardsByRank = cards
44
-                .stream()
43
+        List<Card> cardsByRank = cards.stream()
45
                 .sorted(Comparator.comparing(Card::getRank))
44
                 .sorted(Comparator.comparing(Card::getRank))
46
                 .unordered()
45
                 .unordered()
47
                 .collect(Collectors.toList());
46
                 .collect(Collectors.toList());
63
                 .stream()
62
                 .stream()
64
                 .map(Map.Entry::getValue)
63
                 .map(Map.Entry::getValue)
65
                 .collect(Collectors.toList());
64
                 .collect(Collectors.toList());
66
-        List<Integer> suits = cards.stream().map(Card::getSuit).collect(Collectors.toList());
65
+        List<Integer> suits = cards
66
+                .stream()
67
+                .map(Card::getSuit)
68
+                .collect(Collectors.toList());
67
 
69
 
68
         return calculatedScore(frequencyMap, cardsByRank, ranks, rankCounts, suits);
70
         return calculatedScore(frequencyMap, cardsByRank, ranks, rankCounts, suits);
69
     }
71
     }
74
             ranks = Arrays.asList(5, 4, 3, 2, 1);
76
             ranks = Arrays.asList(5, 4, 3, 2, 1);
75
         }
77
         }
76
 
78
 
77
-        boolean flush = suits.stream().distinct().count() == 1;
78
-        boolean straight = ranks.stream().distinct().count() == 5 && ranks.get(0) - ranks.get(4) == 4;
79
+        boolean flush = suits
80
+                .stream()
81
+                .distinct()
82
+                .count() == 1;
83
+        boolean straight = ranks.stream().distinct().count() == 5 
84
+            && ranks.get(0) - ranks.get(4) == 4;
85
+        
79
         Iterator<Integer> iteratorOverFrequencies = frequencyMap.keySet().iterator();
86
         Iterator<Integer> iteratorOverFrequencies = frequencyMap.keySet().iterator();
87
+        
80
         int highestFrequency = iteratorOverFrequencies.next();
88
         int highestFrequency = iteratorOverFrequencies.next();
81
 
89
 
82
         if (straight && flush) {
90
         if (straight && flush) {
86
             return 700 + cardsByRank.get(0).getRank();
94
             return 700 + cardsByRank.get(0).getRank();
87
         }
95
         }
88
         if (rankCounts.equals(Arrays.asList(3, 2))) {
96
         if (rankCounts.equals(Arrays.asList(3, 2))) {
89
-            return 600 + cardsByRank.get(0).getRank();
97
+            int triplet = 0;
98
+            int pair = 0;
99
+            for (Integer key : frequencyMap.keySet()) {
100
+                if (frequencyMap.get(key) == 2) {
101
+                    pair = (int) key;
102
+                }
103
+                if (frequencyMap.get(key) == 3) {
104
+                    triplet = 3 * (int) key;
105
+                }
106
+            }
107
+            return 600 + 3 * triplet + pair;
90
         }
108
         }
91
         if (flush) {
109
         if (flush) {
92
             return 500 + highestFrequency;
110
             return 500 + highestFrequency;
93
         }
111
         }
94
         if (straight) {
112
         if (straight) {
95
-            return 400 + highestFrequency;
113
+            int maxValue = Collections.max(ranks);
114
+            return 400 + maxValue;
96
         }
115
         }
97
         if (rankCounts.equals(Arrays.asList(3, 1, 1))) {
116
         if (rankCounts.equals(Arrays.asList(3, 1, 1))) {
98
-            return 300 + cardsByRank.get(0).getRank();
117
+            List<Integer> uniqueCards = new ArrayList<Integer>();
118
+            int triplet = 0;
119
+            for (Integer key : frequencyMap.keySet()) {
120
+                if (frequencyMap.get(key) == 1) {
121
+                    uniqueCards.add((int) key);
122
+                }
123
+                if (frequencyMap.get(key) == 3) {
124
+                    triplet = 3 * (int) key;
125
+                }
126
+            }
127
+            return 300 + triplet + Collections.max(uniqueCards);
99
         }
128
         }
100
         if (rankCounts.equals(Arrays.asList(2, 2, 1))) {
129
         if (rankCounts.equals(Arrays.asList(2, 2, 1))) {
101
-            return 200 + Math.max(highestFrequency, iteratorOverFrequencies.next());
130
+            int productsOfFrequencyAndValue = 0;
131
+            for (Integer key : frequencyMap.keySet()) {
132
+                int frequencyKey = (int) key;
133
+                int frequencyValue = frequencyMap.get(key);
134
+                productsOfFrequencyAndValue += frequencyKey * frequencyValue;
135
+            }
136
+            return 200 + productsOfFrequencyAndValue + 2 * Math.max(highestFrequency, iteratorOverFrequencies.next());
102
         }
137
         }
103
         if (rankCounts.equals(Arrays.asList(2, 1, 1, 1))) {
138
         if (rankCounts.equals(Arrays.asList(2, 1, 1, 1))) {
104
             return 100 + highestFrequency;
139
             return 100 + highestFrequency;
105
         }
140
         }
106
         ranks.sort(Comparator.naturalOrder());
141
         ranks.sort(Comparator.naturalOrder());
107
-        return ranks.get(0);
142
+        int result = 0;
143
+        for (int i = 0; i < ranks.size(); i++) {
144
+            result += ranks.get(0) * (i + 1);
145
+        }
146
+        return result + ranks.get(ranks.size() - 1);
108
     }
147
     }
109
-}
148
+}               

+ 1
- 0
exercises/poker/.meta/version.txt Visa fil

1
+1.1.0

+ 143
- 66
exercises/poker/src/test/java/PokerTest.java Visa fil

2
 import org.junit.Test;
2
 import org.junit.Test;
3
 
3
 
4
 import java.util.Arrays;
4
 import java.util.Arrays;
5
+import java.util.Collections;
5
 
6
 
6
 import static org.junit.Assert.assertEquals;
7
 import static org.junit.Assert.assertEquals;
7
 
8
 
8
 public class PokerTest {
9
 public class PokerTest {
9
     @Test
10
     @Test
10
     public void oneHand() {
11
     public void oneHand() {
11
-        final String hand = "4S 5S 7H 8D JC";
12
-        assertEquals(Arrays.asList(hand), new Poker(Arrays.asList(hand)).getBestHands());
12
+        String hand = "4S 5S 7H 8D JC";
13
+        assertEquals(Collections.singletonList(hand), new Poker(Collections.singletonList(hand)).getBestHands());
14
+    }
15
+
16
+    @Ignore("Remove to run test")
17
+    @Test
18
+    public void highestCardWins() {
19
+        String highest8 = "4D 5S 6S 8D 3C";
20
+        String highest10 = "2S 4C 7S 9H 10H";
21
+        String highestJ = "3S 4S 5D 6H JH";
22
+        assertEquals(Collections.singletonList(highestJ), new Poker(Arrays.asList(highest8, highest10, highestJ)).getBestHands());
23
+    }
24
+
25
+    @Ignore("Remove to run test")
26
+    @Test
27
+    public void tieHasMultipleWinners() {
28
+        String highest8 = "4D 5S 6S 8D 3C";
29
+        String highest10 = "2S 4C 7S 9H 10H";
30
+        String highestJh = "3S 4S 5D 6H JH";
31
+        String highestJd = "3H 4H 5C 6C JD";
32
+        assertEquals(Arrays.asList(highestJh, highestJd),
33
+                new Poker(Arrays.asList(highest8, highest10, highestJh, highestJd)).getBestHands());
34
+    }
35
+
36
+    @Ignore("Remove to run test")
37
+    @Test
38
+    public void sameHighCards() {
39
+        String nextHighest3 = "3S 5H 6S 8D 7H";
40
+        String nextHighest2 = "2S 5D 6D 8C 7S";
41
+        assertEquals(Collections.singletonList(nextHighest3), new Poker(Arrays.asList(nextHighest3, nextHighest2)).getBestHands());
13
     }
42
     }
14
 
43
 
15
     @Ignore("Remove to run test")
44
     @Ignore("Remove to run test")
16
     @Test
45
     @Test
17
     public void nothingVsOnePair() {
46
     public void nothingVsOnePair() {
18
-        final String nothing = "4S 5H 6S 8D JH";
19
-        final String pairOf4 = "2S 4H 6S 4D JH";
20
-        assertEquals(Arrays.asList(pairOf4), new Poker(Arrays.asList(nothing, pairOf4)).getBestHands());
47
+        String nothing = "4S 5H 6C 8D KH";
48
+        String pairOf4 = "2S 4H 6S 4D JH";
49
+        assertEquals(Collections.singletonList(pairOf4), new Poker(Arrays.asList(nothing, pairOf4)).getBestHands());
21
     }
50
     }
22
 
51
 
23
     @Ignore("Remove to run test")
52
     @Ignore("Remove to run test")
24
     @Test
53
     @Test
25
     public void twoPairs() {
54
     public void twoPairs() {
26
-        final String pairOf2 = "4S 2H 6S 2D JH";
27
-        final String pairOf4 = "2S 4H 6S 4D JH";
28
-        assertEquals(Arrays.asList(pairOf4), new Poker(Arrays.asList(pairOf2, pairOf4)).getBestHands());
55
+        String pairOf2 = "4S 2H 6S 2D JH";
56
+        String pairOf4 = "2S 4H 6C 4D JD";
57
+        assertEquals(Collections.singletonList(pairOf4), new Poker(Arrays.asList(pairOf2, pairOf4)).getBestHands());
29
     }
58
     }
30
 
59
 
31
     @Ignore("Remove to run test")
60
     @Ignore("Remove to run test")
32
     @Test
61
     @Test
33
     public void onePairVsDoublePair() {
62
     public void onePairVsDoublePair() {
34
-        final String pairOf8 = "2S 8H 6S 8D JH";
35
-        final String doublePair = "4S 5H 4S 8D 5H";
36
-        assertEquals(Arrays.asList(doublePair), new Poker(Arrays.asList(pairOf8, doublePair)).getBestHands());
63
+        String pairOf8 = "2S 8H 6S 8D JH";
64
+        String doublePair = "4S 5H 4C 8C 5C";
65
+        assertEquals(Collections.singletonList(doublePair), new Poker(Arrays.asList(pairOf8, doublePair)).getBestHands());
37
     }
66
     }
38
 
67
 
39
     @Ignore("Remove to run test")
68
     @Ignore("Remove to run test")
40
     @Test
69
     @Test
41
     public void twoDoublePairs() {
70
     public void twoDoublePairs() {
42
-        final String doublePair2And8 = "2S 8H 2S 8D JH";
43
-        final String doublePair4And5 = "4S 5H 4S 8D 5H";
44
-        assertEquals(Arrays.asList(doublePair2And8), new Poker(Arrays.asList(doublePair2And8, doublePair4And5)).getBestHands());
71
+        String doublePair2And8 = "2S 8H 2D 8D 3H";
72
+        String doublePair4And5 = "4S 5H 4C 8S 5D";
73
+        assertEquals(Collections.singletonList(doublePair2And8),
74
+                new Poker(Arrays.asList(doublePair2And8, doublePair4And5)).getBestHands());
75
+    }
76
+
77
+    @Ignore("Remove to run test")
78
+    @Test
79
+    public void sameHighestPair() {
80
+        String doublePair2AndQ = "2S QS 2C QD JH";
81
+        String doublePairJAndQ = "JD QH JS 8D QC";
82
+        assertEquals(Collections.singletonList(doublePairJAndQ),
83
+                new Poker(Arrays.asList(doublePairJAndQ, doublePair2AndQ)).getBestHands());
84
+    }
85
+
86
+    @Ignore("Remove to run test")
87
+    @Test
88
+    public void identicallyRankedPairs() {
89
+        String kicker8 = "JD QH JS 8D QC";
90
+        String kicker2 = "JS QS JC 2D QD";
91
+        assertEquals(Collections.singletonList(kicker8), new Poker(Arrays.asList(kicker8, kicker2)).getBestHands());
45
     }
92
     }
46
 
93
 
47
     @Ignore("Remove to run test")
94
     @Ignore("Remove to run test")
48
     @Test
95
     @Test
49
     public void doublePairVsThree() {
96
     public void doublePairVsThree() {
50
-        final String doublePair2And8 = "2S 8H 2S 8D JH";
51
-        final String threeOf4 = "4S 5H 4S 8D 4H";
52
-        assertEquals(Arrays.asList(threeOf4), new Poker(Arrays.asList(doublePair2And8, threeOf4)).getBestHands());
97
+        String doublePair2And8 = "2S 8H 2H 8D JH";
98
+        String threeOf4 = "4S 5H 4C 8S 4H";
99
+        assertEquals(Collections.singletonList(threeOf4), new Poker(Arrays.asList(doublePair2And8, threeOf4)).getBestHands());
53
     }
100
     }
54
 
101
 
55
     @Ignore("Remove to run test")
102
     @Ignore("Remove to run test")
56
     @Test
103
     @Test
57
     public void twoThrees() {
104
     public void twoThrees() {
58
-        final String threeOf2 = "2S 2H 2S 8D JH";
59
-        final String threeOf1 = "4S AH AS 8D AH";
60
-        assertEquals(Arrays.asList(threeOf1), new Poker(Arrays.asList(threeOf2, threeOf1)).getBestHands());
105
+        String threeOf2 = "2S 2H 2C 8D JH";
106
+        String threeOf1 = "4S AH AS 8C AD";
107
+        assertEquals(Collections.singletonList(threeOf1), new Poker(Arrays.asList(threeOf2, threeOf1)).getBestHands());
108
+    }
109
+
110
+    @Ignore("Remove to run test")
111
+    @Test
112
+    public void sameThreesMultipleDecks() {
113
+        String remainingCard7 = "4S AH AS 7C AD";
114
+        String remainingCard8 = "4S AH AS 8C AD";
115
+        assertEquals(Collections.singletonList(remainingCard8),
116
+                new Poker(Arrays.asList(remainingCard7, remainingCard8)).getBestHands());
61
     }
117
     }
62
 
118
 
63
     @Ignore("Remove to run test")
119
     @Ignore("Remove to run test")
64
     @Test
120
     @Test
65
     public void threeVsStraight() {
121
     public void threeVsStraight() {
66
-        final String threeOf4 = "4S 5H 4S 8D 4H";
67
-        final String straight = "3S 4H 2S 6D 5H";
68
-        assertEquals(Arrays.asList(straight), new Poker(Arrays.asList(threeOf4, straight)).getBestHands());
122
+        String threeOf4 = "4S 5H 4C 8D 4H";
123
+        String straight = "3S 4D 2S 6D 5C";
124
+        assertEquals(Collections.singletonList(straight), new Poker(Arrays.asList(threeOf4, straight)).getBestHands());
125
+    }
126
+
127
+    @Ignore("Remove to run test")
128
+    @Test
129
+    public void AcesCanEndAStraight() {
130
+        String hand = "4S 5H 4C 8D 4H";
131
+        String straightEndsA = "10D JH QS KD AC";
132
+        assertEquals(Collections.singletonList(straightEndsA), new Poker(Arrays.asList(hand, straightEndsA)).getBestHands());
133
+    }
134
+
135
+    @Ignore("Remove to run test")
136
+    @Test
137
+    public void AcesCanStartAStraight() {
138
+        String hand = "4S 5H 4C 8D 4H";
139
+        String straightStartA = "4D AH 3S 2D 5C";
140
+        assertEquals(Collections.singletonList(straightStartA), new Poker(Arrays.asList(hand, straightStartA)).getBestHands());
69
     }
141
     }
70
 
142
 
71
     @Ignore("Remove to run test")
143
     @Ignore("Remove to run test")
72
     @Test
144
     @Test
73
     public void twoStraights() {
145
     public void twoStraights() {
74
-        final String straightTo8 = "4S 6H 7S 8D 5H";
75
-        final String straightTo9 = "5S 7H 8S 9D 6H";
76
-        assertEquals(Arrays.asList(straightTo9), new Poker(Arrays.asList(straightTo8, straightTo9)).getBestHands());
146
+        String straightTo8 = "4S 6C 7S 8D 5H";
147
+        String straightTo9 = "5S 7H 8S 9D 6H";
148
+        assertEquals(Collections.singletonList(straightTo9), new Poker(Arrays.asList(straightTo8, straightTo9)).getBestHands());
149
+    }
77
 
150
 
78
-        final String straightTo1 = "AS QH KS TD JH";
79
-        final String straightTo5 = "4S AH 3S 2D 5H";
80
-        assertEquals(Arrays.asList(straightTo1), new Poker(Arrays.asList(straightTo1, straightTo5)).getBestHands());
151
+    @Ignore("Remove to run test")
152
+    @Test
153
+    public void theLowestStraightStartsWithAce() {
154
+        String straight = "2H 3C 4D 5D 6H";
155
+        String straightStartA = "4S AH 3S 2D 5H";
156
+        assertEquals(Collections.singletonList(straight), new Poker(Arrays.asList(straight, straightStartA)).getBestHands());
81
     }
157
     }
82
 
158
 
83
     @Ignore("Remove to run test")
159
     @Ignore("Remove to run test")
84
     @Test
160
     @Test
85
     public void straightVsFlush() {
161
     public void straightVsFlush() {
86
-        final String straightTo8 = "4S 6H 7S 8D 5H";
87
-        final String flushTo7 = "2S 4S 5S 6S 7S";
88
-        assertEquals(Arrays.asList(flushTo7), new Poker(Arrays.asList(straightTo8, flushTo7)).getBestHands());
162
+        String straightTo8 = "4C 6H 7D 8D 5H";
163
+        String flushTo7 = "2S 4S 5S 6S 7S";
164
+        assertEquals(Collections.singletonList(flushTo7), new Poker(Arrays.asList(straightTo8, flushTo7)).getBestHands());
89
     }
165
     }
90
 
166
 
91
     @Ignore("Remove to run test")
167
     @Ignore("Remove to run test")
92
     @Test
168
     @Test
93
     public void twoFlushes() {
169
     public void twoFlushes() {
94
-        final String flushTo8 = "3H 6H 7H 8H 5H";
95
-        final String flushTo7 = "2S 4S 5S 6S 7S";
96
-        assertEquals(Arrays.asList(flushTo8), new Poker(Arrays.asList(flushTo8, flushTo7)).getBestHands());
170
+        String flushTo8 = "4H 7H 8H 9H 6H";
171
+        String flushTo7 = "2S 4S 5S 6S 7S";
172
+        assertEquals(Collections.singletonList(flushTo8), new Poker(Arrays.asList(flushTo8, flushTo7)).getBestHands());
97
     }
173
     }
98
 
174
 
99
     @Ignore("Remove to run test")
175
     @Ignore("Remove to run test")
100
     @Test
176
     @Test
101
     public void flushVsFull() {
177
     public void flushVsFull() {
102
-        final String flushTo8 = "3H 6H 7H 8H 5H";
103
-        final String full = "4S 5H 4S 5D 4H";
104
-        assertEquals(Arrays.asList(full), new Poker(Arrays.asList(full, flushTo8)).getBestHands());
178
+        String flushTo8 = "3H 6H 7H 8H 5H";
179
+        String full = "4S 5H 4C 5D 4H";
180
+        assertEquals(Collections.singletonList(full), new Poker(Arrays.asList(full, flushTo8)).getBestHands());
105
     }
181
     }
106
 
182
 
107
     @Ignore("Remove to run test")
183
     @Ignore("Remove to run test")
108
     @Test
184
     @Test
109
     public void twoFulls() {
185
     public void twoFulls() {
110
-        final String fullOf4By9 = "4H 4S 4D 9S 9D";
111
-        final String fullOf5By8 = "5H 5S 5D 8S 8D";
112
-        assertEquals(Arrays.asList(fullOf5By8), new Poker(Arrays.asList(fullOf4By9, fullOf5By8)).getBestHands());
186
+        String fullOf4By9 = "4H 4S 4D 9S 9D";
187
+        String fullOf5By8 = "5H 5S 5D 8S 8D";
188
+        assertEquals(Collections.singletonList(fullOf5By8), new Poker(Arrays.asList(fullOf4By9, fullOf5By8)).getBestHands());
113
     }
189
     }
114
 
190
 
115
     @Ignore("Remove to run test")
191
     @Ignore("Remove to run test")
116
     @Test
192
     @Test
117
-    public void fullVsSquare() {
118
-        final String full = "4S 5H 4S 5D 4H";
119
-        final String squareOf3 = "3S 3H 2S 3D 3H";
120
-        assertEquals(Arrays.asList(squareOf3), new Poker(Arrays.asList(full, squareOf3)).getBestHands());
193
+    public void twoFullssameThripletMultipleDecks() {
194
+        String fullOf5By9 = "5H 5S 5D 9S 9D";
195
+        String fullOf5By8 = "5H 5S 5D 8S 8D";
196
+        assertEquals(Collections.singletonList(fullOf5By9), new Poker(Arrays.asList(fullOf5By9, fullOf5By8)).getBestHands());
121
     }
197
     }
122
 
198
 
123
     @Ignore("Remove to run test")
199
     @Ignore("Remove to run test")
124
     @Test
200
     @Test
125
-    public void twoSquares() {
126
-        final String squareOf2 = "2S 2H 2S 8D 2H";
127
-        final String squareOf5 = "4S 5H 5S 5D 5H";
128
-        assertEquals(Arrays.asList(squareOf5), new Poker(Arrays.asList(squareOf2, squareOf5)).getBestHands());
201
+    public void fullVsSquare() {
202
+        String full = "4S 5H 4D 5D 4H";
203
+        String squareOf3 = "3S 3H 2S 3D 3C";
204
+        assertEquals(Collections.singletonList(squareOf3), new Poker(Arrays.asList(full, squareOf3)).getBestHands());
129
     }
205
     }
130
 
206
 
131
     @Ignore("Remove to run test")
207
     @Ignore("Remove to run test")
132
     @Test
208
     @Test
133
-    public void squareVsStraightFlush() {
134
-        final String squareOf5 = "4S 5H 5S 5D 5H";
135
-        final String straightFlushTo9 = "5S 7S 8S 9S 6S";
136
-        assertEquals(Arrays.asList(straightFlushTo9), new Poker(Arrays.asList(squareOf5, straightFlushTo9)).getBestHands());
209
+    public void twoSquares() {
210
+        String squareOf2 = "2S 2H 2C 8D 2D";
211
+        String squareOf5 = "4S 5H 5S 5D 5C";
212
+        assertEquals(Collections.singletonList(squareOf5), new Poker(Arrays.asList(squareOf2, squareOf5)).getBestHands());
137
     }
213
     }
138
 
214
 
139
     @Ignore("Remove to run test")
215
     @Ignore("Remove to run test")
140
     @Test
216
     @Test
141
-    public void twoStraightFlushes() {
142
-        final String straightFlushTo8 = "4H 6H 7H 8H 5H";
143
-        final String straightFlushTo9 = "5S 7S 8S 9S 6S";
144
-        assertEquals(Arrays.asList(straightFlushTo9), new Poker(Arrays.asList(straightFlushTo8, straightFlushTo9)).getBestHands());
217
+    public void sameSquaresMultipleDecks() {
218
+        String kicker2 = "3S 3H 2S 3D 3C";
219
+        String kicker4 = "3S 3H 4S 3D 3C";
220
+        assertEquals(Collections.singletonList(kicker4), new Poker(Arrays.asList(kicker2, kicker4)).getBestHands());
145
     }
221
     }
146
 
222
 
147
     @Ignore("Remove to run test")
223
     @Ignore("Remove to run test")
148
     @Test
224
     @Test
149
-    public void threeHandWithTie() {
150
-        final String spadeStraightTo9 = "9S 8S 7S 6S 5S";
151
-        final String diamondStraightTo9 = "9D 8D 7D 6D 5D";
152
-        final String threeOf4 = "4D 4S 4H QS KS";
153
-        assertEquals(Arrays.asList(spadeStraightTo9, diamondStraightTo9), new Poker(Arrays.asList(spadeStraightTo9, diamondStraightTo9, threeOf4)).getBestHands());
225
+    public void squareVsStraightFlush() {
226
+        String squareOf5 = "4S 5H 5S 5D 5C";
227
+        String straightFlushTo9 = "7S 8S 9S 6S 10S";
228
+        assertEquals(Collections.singletonList(straightFlushTo9),
229
+                new Poker(Arrays.asList(squareOf5, straightFlushTo9)).getBestHands());
154
     }
230
     }
155
 
231
 
156
     @Ignore("Remove to run test")
232
     @Ignore("Remove to run test")
157
     @Test
233
     @Test
158
-    public void straightTo5AgainstAPairOfJacks() {
159
-        final String straightTo5 = "2S 4D 5C 3S AS";
160
-        final String twoJacks = "JD 8D 7D JC 5D";
161
-        assertEquals(Arrays.asList(straightTo5), new Poker(Arrays.asList(straightTo5, twoJacks)).getBestHands());
234
+    public void twoStraightFlushes() {
235
+        String straightFlushTo8 = "4H 6H 7H 8H 5H";
236
+        String straightFlushTo9 = "5S 7S 8S 9S 6S";
237
+        assertEquals(Collections.singletonList(straightFlushTo9),
238
+                new Poker(Arrays.asList(straightFlushTo8, straightFlushTo9)).getBestHands());
162
     }
239
     }
163
 }
240
 }

+ 10
- 10
exercises/pythagorean-triplet/src/test/java/PythagoreanTripletTest.java Visa fil

15
     @Test
15
     @Test
16
     public void shouldCalculateSum() {
16
     public void shouldCalculateSum() {
17
         PythagoreanTriplet triplet = new PythagoreanTriplet(3, 4, 5);
17
         PythagoreanTriplet triplet = new PythagoreanTriplet(3, 4, 5);
18
-        final int expected = 12;
19
-        final int actual = triplet.calculateSum();
18
+        int expected = 12;
19
+        int actual = triplet.calculateSum();
20
         assertEquals(expected, actual);
20
         assertEquals(expected, actual);
21
     }
21
     }
22
 
22
 
24
     @Test
24
     @Test
25
     public void shouldCalculateProduct() {
25
     public void shouldCalculateProduct() {
26
         PythagoreanTriplet triplet = new PythagoreanTriplet(3, 4, 5);
26
         PythagoreanTriplet triplet = new PythagoreanTriplet(3, 4, 5);
27
-        final long expected = 60l;
28
-        final long actual = triplet.calculateProduct();
27
+        long expected = 60l;
28
+        long actual = triplet.calculateProduct();
29
         assertEquals(expected, actual);
29
         assertEquals(expected, actual);
30
     }
30
     }
31
 
31
 
46
     @Ignore("Remove to run test")
46
     @Ignore("Remove to run test")
47
     @Test
47
     @Test
48
     public void shouldMakeTripletsUpToTen() {
48
     public void shouldMakeTripletsUpToTen() {
49
-        final List<Long> actual
49
+        List<Long> actual
50
                 = PythagoreanTriplet
50
                 = PythagoreanTriplet
51
                         .makeTripletsList()
51
                         .makeTripletsList()
52
                         .withFactorsLessThanOrEqualTo(10)
52
                         .withFactorsLessThanOrEqualTo(10)
55
                         .map(t -> t.calculateProduct())
55
                         .map(t -> t.calculateProduct())
56
                         .sorted()
56
                         .sorted()
57
                         .collect(Collectors.toList());
57
                         .collect(Collectors.toList());
58
-        final List<Long> expected = Arrays.asList(60l, 480l);
58
+        List<Long> expected = Arrays.asList(60l, 480l);
59
         assertEquals(expected, actual);
59
         assertEquals(expected, actual);
60
     }
60
     }
61
 
61
 
62
     @Ignore("Remove to run test")
62
     @Ignore("Remove to run test")
63
     @Test
63
     @Test
64
     public void shouldMakeTripletsElevenToTwenty() {
64
     public void shouldMakeTripletsElevenToTwenty() {
65
-        final List<Long> actual
65
+        List<Long> actual
66
                 = PythagoreanTriplet
66
                 = PythagoreanTriplet
67
                         .makeTripletsList()
67
                         .makeTripletsList()
68
                         .withFactorsGreaterThanOrEqualTo(11)
68
                         .withFactorsGreaterThanOrEqualTo(11)
72
                         .map(t -> t.calculateProduct())
72
                         .map(t -> t.calculateProduct())
73
                         .sorted((p1, p2) -> Double.compare(p1, p2))
73
                         .sorted((p1, p2) -> Double.compare(p1, p2))
74
                         .collect(Collectors.toList());
74
                         .collect(Collectors.toList());
75
-        final List<Long> expected = Arrays.asList(3840l);
75
+        List<Long> expected = Arrays.asList(3840l);
76
         assertEquals(expected, actual);
76
         assertEquals(expected, actual);
77
     }
77
     }
78
 
78
 
79
     @Ignore("Remove to run test")
79
     @Ignore("Remove to run test")
80
     @Test
80
     @Test
81
     public void shouldMakeTripletsAndFilterOnSum() {
81
     public void shouldMakeTripletsAndFilterOnSum() {
82
-        final List<Long> actual
82
+        List<Long> actual
83
                 = PythagoreanTriplet
83
                 = PythagoreanTriplet
84
                         .makeTripletsList()
84
                         .makeTripletsList()
85
                         .withFactorsLessThanOrEqualTo(100)
85
                         .withFactorsLessThanOrEqualTo(100)
89
                         .map(t -> t.calculateProduct())
89
                         .map(t -> t.calculateProduct())
90
                         .sorted((p1, p2) -> Double.compare(p1, p2))
90
                         .sorted((p1, p2) -> Double.compare(p1, p2))
91
                         .collect(Collectors.toList());
91
                         .collect(Collectors.toList());
92
-        final List<Long> expected = Arrays.asList(118080l, 168480l, 202500l);
92
+        List<Long> expected = Arrays.asList(118080l, 168480l, 202500l);
93
         assertEquals(expected, actual);
93
         assertEquals(expected, actual);
94
     }
94
     }
95
 }
95
 }

+ 0
- 39
exercises/queen-attack/.meta/src/reference/java/BoardCoordinate.java Visa fil

1
-final class BoardCoordinate {
2
-
3
-    private final int row;
4
-
5
-    private final int column;
6
-
7
-    BoardCoordinate(final int row, final int column) throws IllegalArgumentException {
8
-        this.row = row;
9
-        this.column = column;
10
-
11
-        validateInputs();
12
-    }
13
-
14
-    int getRow() {
15
-        return row;
16
-    }
17
-
18
-    int getColumn() {
19
-        return column;
20
-    }
21
-
22
-    private void validateInputs() throws IllegalArgumentException {
23
-        validateCoordinateComponent(row, "row");
24
-        validateCoordinateComponent(column, "column");
25
-    }
26
-
27
-    private void validateCoordinateComponent(final int value, final String componentName)
28
-            throws IllegalArgumentException {
29
-
30
-        if (value < 0) {
31
-            throw new IllegalArgumentException("Coordinate must have positive " + componentName + ".");
32
-        }
33
-
34
-        if (value > 7) {
35
-            throw new IllegalArgumentException("Coordinate must have " + componentName + " <= 7.");
36
-        }
37
-    }
38
-
39
-}

+ 38
- 0
exercises/queen-attack/.meta/src/reference/java/Queen.java Visa fil

1
+final class Queen {
2
+
3
+    private final int row;
4
+
5
+    private final int column;
6
+
7
+    Queen(final int row, final int column) {
8
+        this.row = row;
9
+        this.column = column;
10
+
11
+        validatePosition();
12
+    }
13
+
14
+    int getRow() {
15
+        return row;
16
+    }
17
+
18
+    int getColumn() {
19
+        return column;
20
+    }
21
+
22
+    private void validatePosition() {
23
+        validatePositionComponent(row, "row");
24
+        validatePositionComponent(column, "column");
25
+    }
26
+
27
+    private void validatePositionComponent(final int value, final String componentName) {
28
+
29
+        if (value < 0) {
30
+            throw new IllegalArgumentException("Queen position must have positive " + componentName + ".");
31
+        }
32
+
33
+        if (value > 7) {
34
+            throw new IllegalArgumentException("Queen position must have " + componentName + " <= 7.");
35
+        }
36
+    }
37
+
38
+}

+ 11
- 12
exercises/queen-attack/.meta/src/reference/java/QueenAttackCalculator.java Visa fil

1
 final class QueenAttackCalculator {
1
 final class QueenAttackCalculator {
2
 
2
 
3
-    private final BoardCoordinate whiteQueenCoordinate;
3
+    private final Queen whiteQueen;
4
 
4
 
5
-    private final BoardCoordinate blackQueenCoordinate;
5
+    private final Queen blackQueen;
6
 
6
 
7
-    QueenAttackCalculator(final BoardCoordinate whiteQueenCoordinate, final BoardCoordinate blackQueenCoordinate)
8
-            throws IllegalArgumentException {
7
+    QueenAttackCalculator(final Queen whiteQueen, final Queen blackQueen) {
9
 
8
 
10
-        this.whiteQueenCoordinate = whiteQueenCoordinate;
11
-        this.blackQueenCoordinate = blackQueenCoordinate;
9
+        this.whiteQueen = whiteQueen;
10
+        this.blackQueen = blackQueen;
12
 
11
 
13
         validateInputs();
12
         validateInputs();
14
     }
13
     }
17
         return queensShareColumn() || queensShareRow() || queensShareDiagonal();
16
         return queensShareColumn() || queensShareRow() || queensShareDiagonal();
18
     }
17
     }
19
 
18
 
20
-    private void validateInputs() throws IllegalArgumentException {
21
-        if (whiteQueenCoordinate == null || blackQueenCoordinate == null) {
22
-            throw new IllegalArgumentException("You must supply valid board coordinates for both Queens.");
19
+    private void validateInputs() {
20
+        if (whiteQueen == null || blackQueen == null) {
21
+            throw new IllegalArgumentException("You must supply valid positions for both Queens.");
23
         }
22
         }
24
 
23
 
25
         if (queensShareBoardCoordinate()) {
24
         if (queensShareBoardCoordinate()) {
26
-            throw new IllegalArgumentException("Queens may not occupy the same board coordinate.");
25
+            throw new IllegalArgumentException("Queens cannot occupy the same position.");
27
         }
26
         }
28
     }
27
     }
29
 
28
 
44
     }
43
     }
45
 
44
 
46
     private int differenceBetweenRows() {
45
     private int differenceBetweenRows() {
47
-        return Math.abs(whiteQueenCoordinate.getRow() - blackQueenCoordinate.getRow());
46
+        return Math.abs(whiteQueen.getRow() - blackQueen.getRow());
48
     }
47
     }
49
 
48
 
50
     private int differenceBetweenColumns() {
49
     private int differenceBetweenColumns() {
51
-        return Math.abs(whiteQueenCoordinate.getColumn() - blackQueenCoordinate.getColumn());
50
+        return Math.abs(whiteQueen.getColumn() - blackQueen.getColumn());
52
     }
51
     }
53
 
52
 
54
 }
53
 }

+ 1
- 1
exercises/queen-attack/.meta/version Visa fil

1
-2.0.0
1
+2.1.0

+ 50
- 44
exercises/queen-attack/src/test/java/QueenAttackCalculatorTest.java Visa fil

12
     public ExpectedException expectedException = ExpectedException.none();
12
     public ExpectedException expectedException = ExpectedException.none();
13
 
13
 
14
     @Test
14
     @Test
15
-    public void testQueensThatDoNotShareRowColumnOrDiagonalCannotAttack() {
16
-        final QueenAttackCalculator calculator
17
-                = new QueenAttackCalculator(new BoardCoordinate(2, 4), new BoardCoordinate(6, 6));
15
+    public void testCreateQueenWithAValidPosition() {
16
+        new Queen(2, 2);
17
+    }
18
 
18
 
19
-        assertFalse(calculator.canQueensAttackOneAnother());
19
+    @Ignore("Remove to run test")
20
+    @Test
21
+    public void testCreateQueenMustHavePositiveRow() {
22
+        expectedException.expect(IllegalArgumentException.class);
23
+        expectedException.expectMessage("Queen position must have positive row.");
24
+
25
+        new Queen(-2, 2);
20
     }
26
     }
21
 
27
 
22
     @Ignore("Remove to run test")
28
     @Ignore("Remove to run test")
23
     @Test
29
     @Test
24
-    public void testQueensCanAttackOnTheSameRow() {
25
-        final QueenAttackCalculator calculator
26
-                = new QueenAttackCalculator(new BoardCoordinate(2, 4), new BoardCoordinate(2, 6));
30
+    public void testCreateQueenMustHaveRowOnBoard() {
31
+        expectedException.expect(IllegalArgumentException.class);
32
+        expectedException.expectMessage("Queen position must have row <= 7.");
27
 
33
 
28
-        assertTrue(calculator.canQueensAttackOneAnother());
34
+        new Queen(8, 4);
29
     }
35
     }
30
 
36
 
31
     @Ignore("Remove to run test")
37
     @Ignore("Remove to run test")
32
     @Test
38
     @Test
33
-    public void testQueensCanAttackOnTheSameColumn() {
34
-        final QueenAttackCalculator calculator
35
-                = new QueenAttackCalculator(new BoardCoordinate(4, 5), new BoardCoordinate(2, 5));
39
+    public void testCreateQueenMustHavePositiveColumn() {
40
+        expectedException.expect(IllegalArgumentException.class);
41
+        expectedException.expectMessage("Queen position must have positive column.");
36
 
42
 
37
-        assertTrue(calculator.canQueensAttackOneAnother());
43
+        new Queen(2, -2);
38
     }
44
     }
39
 
45
 
40
     @Ignore("Remove to run test")
46
     @Ignore("Remove to run test")
41
     @Test
47
     @Test
42
-    public void testQueensCanAttackOnFirstDiagonal() {
43
-        final QueenAttackCalculator calculator
44
-                = new QueenAttackCalculator(new BoardCoordinate(2, 2), new BoardCoordinate(0, 4));
48
+    public void testCreateQueenMustHaveColumnOnBoard() {
49
+        expectedException.expect(IllegalArgumentException.class);
50
+        expectedException.expectMessage("Queen position must have column <= 7.");
45
 
51
 
46
-        assertTrue(calculator.canQueensAttackOneAnother());
52
+        new Queen(4, 8);
47
     }
53
     }
48
 
54
 
49
     @Ignore("Remove to run test")
55
     @Ignore("Remove to run test")
50
     @Test
56
     @Test
51
-    public void testQueensCanAttackOnSecondDiagonal() {
57
+    public void testQueensCannotAttack() {
52
         final QueenAttackCalculator calculator
58
         final QueenAttackCalculator calculator
53
-                = new QueenAttackCalculator(new BoardCoordinate(2, 2), new BoardCoordinate(3, 1));
59
+                = new QueenAttackCalculator(new Queen(2, 4), new Queen(6, 6));
54
 
60
 
55
-        assertTrue(calculator.canQueensAttackOneAnother());
61
+        assertFalse(calculator.canQueensAttackOneAnother());
56
     }
62
     }
57
 
63
 
58
     @Ignore("Remove to run test")
64
     @Ignore("Remove to run test")
59
     @Test
65
     @Test
60
-    public void testQueensCanAttackOnThirdDiagonal() {
66
+    public void testQueensCanAttackOnTheSameRow() {
61
         final QueenAttackCalculator calculator
67
         final QueenAttackCalculator calculator
62
-                = new QueenAttackCalculator(new BoardCoordinate(2, 2), new BoardCoordinate(1, 1));
68
+                = new QueenAttackCalculator(new Queen(2, 4), new Queen(2, 6));
63
 
69
 
64
         assertTrue(calculator.canQueensAttackOneAnother());
70
         assertTrue(calculator.canQueensAttackOneAnother());
65
     }
71
     }
66
 
72
 
67
     @Ignore("Remove to run test")
73
     @Ignore("Remove to run test")
68
     @Test
74
     @Test
69
-    public void testQueensCanAttackOnFourthDiagonal() {
75
+    public void testQueensCanAttackOnTheSameColumn() {
70
         final QueenAttackCalculator calculator
76
         final QueenAttackCalculator calculator
71
-                = new QueenAttackCalculator(new BoardCoordinate(2, 2), new BoardCoordinate(5, 5));
77
+                = new QueenAttackCalculator(new Queen(4, 5), new Queen(2, 5));
72
 
78
 
73
         assertTrue(calculator.canQueensAttackOneAnother());
79
         assertTrue(calculator.canQueensAttackOneAnother());
74
     }
80
     }
75
 
81
 
76
     @Ignore("Remove to run test")
82
     @Ignore("Remove to run test")
77
     @Test
83
     @Test
78
-    public void testCoordinateWithNegativeRowNotAllowed() {
79
-        expectedException.expect(IllegalArgumentException.class);
80
-        expectedException.expectMessage("Coordinate must have positive row.");
84
+    public void testQueensCanAttackOnFirstDiagonal() {
85
+        final QueenAttackCalculator calculator
86
+                = new QueenAttackCalculator(new Queen(2, 2), new Queen(0, 4));
81
 
87
 
82
-        new BoardCoordinate(-2, 2);
88
+        assertTrue(calculator.canQueensAttackOneAnother());
83
     }
89
     }
84
 
90
 
85
     @Ignore("Remove to run test")
91
     @Ignore("Remove to run test")
86
     @Test
92
     @Test
87
-    public void testCoordinateWithRowGreaterThan7NotAllowed() {
88
-        expectedException.expect(IllegalArgumentException.class);
89
-        expectedException.expectMessage("Coordinate must have row <= 7.");
93
+    public void testQueensCanAttackOnSecondDiagonal() {
94
+        final QueenAttackCalculator calculator
95
+                = new QueenAttackCalculator(new Queen(2, 2), new Queen(3, 1));
90
 
96
 
91
-        new BoardCoordinate(8, 4);
97
+        assertTrue(calculator.canQueensAttackOneAnother());
92
     }
98
     }
93
 
99
 
94
     @Ignore("Remove to run test")
100
     @Ignore("Remove to run test")
95
     @Test
101
     @Test
96
-    public void testCoordinateWithNegativeColumnNotAllowed() {
97
-        expectedException.expect(IllegalArgumentException.class);
98
-        expectedException.expectMessage("Coordinate must have positive column.");
102
+    public void testQueensCanAttackOnThirdDiagonal() {
103
+        final QueenAttackCalculator calculator
104
+                = new QueenAttackCalculator(new Queen(2, 2), new Queen(1, 1));
99
 
105
 
100
-        new BoardCoordinate(2, -2);
106
+        assertTrue(calculator.canQueensAttackOneAnother());
101
     }
107
     }
102
 
108
 
103
     @Ignore("Remove to run test")
109
     @Ignore("Remove to run test")
104
     @Test
110
     @Test
105
-    public void testCoordinateWithColumnGreaterThan7NotAllowed() {
106
-        expectedException.expect(IllegalArgumentException.class);
107
-        expectedException.expectMessage("Coordinate must have column <= 7.");
111
+    public void testQueensCanAttackOnFourthDiagonal() {
112
+        final QueenAttackCalculator calculator
113
+                = new QueenAttackCalculator(new Queen(2, 2), new Queen(5, 5));
108
 
114
 
109
-        new BoardCoordinate(4, 8);
115
+        assertTrue(calculator.canQueensAttackOneAnother());
110
     }
116
     }
111
 
117
 
112
     @Ignore("Remove to run test")
118
     @Ignore("Remove to run test")
113
     @Test
119
     @Test
114
-    public void testNullCoordinateNotAllowed() {
120
+    public void testNullPositionsNotAllowed() {
115
         expectedException.expect(IllegalArgumentException.class);
121
         expectedException.expect(IllegalArgumentException.class);
116
-        expectedException.expectMessage("You must supply valid board coordinates for both Queens.");
122
+        expectedException.expectMessage("You must supply valid positions for both Queens.");
117
 
123
 
118
-        new QueenAttackCalculator(null, new BoardCoordinate(0, 7));
124
+        new QueenAttackCalculator(null, new Queen(0, 7));
119
     }
125
     }
120
 
126
 
121
     @Ignore("Remove to run test")
127
     @Ignore("Remove to run test")
122
     @Test
128
     @Test
123
     public void testQueensMustNotOccupyTheSameSquare() {
129
     public void testQueensMustNotOccupyTheSameSquare() {
124
         expectedException.expect(IllegalArgumentException.class);
130
         expectedException.expect(IllegalArgumentException.class);
125
-        expectedException.expectMessage("Queens may not occupy the same board coordinate.");
131
+        expectedException.expectMessage("Queens cannot occupy the same position.");
126
 
132
 
127
-        new QueenAttackCalculator(new BoardCoordinate(2, 2), new BoardCoordinate(2, 2));
133
+        new QueenAttackCalculator(new Queen(2, 2), new Queen(2, 2));
128
     }
134
     }
129
 
135
 
130
 }
136
 }

+ 1
- 1
exercises/rectangles/.meta/version Visa fil

1
-1.0.0
1
+1.1.0

+ 9
- 1
exercises/rectangles/src/test/java/RectangleCounterTest.java Visa fil

14
     }
14
     }
15
 
15
 
16
     @Test
16
     @Test
17
-    public void testInputWithNoColumnsContainsNoRectangles() {
17
+    public void testInputWithNoRowsContainsNoRectangles() {
18
         String[] inputGrid = new String[]{};
18
         String[] inputGrid = new String[]{};
19
 
19
 
20
         assertEquals(0, rectangleCounter.countRectangles(inputGrid));
20
         assertEquals(0, rectangleCounter.countRectangles(inputGrid));
21
     }
21
     }
22
+    
23
+    @Ignore("Remove to run test")
24
+    @Test
25
+    public void testInputWithNoColumnsContainsNoRectangles() {
26
+        String[] inputGrid = new String[]{""};
22
 
27
 
28
+        assertEquals(0, rectangleCounter.countRectangles(inputGrid));
29
+    }
30
+    
23
     @Ignore("Remove to run test")
31
     @Ignore("Remove to run test")
24
     @Test
32
     @Test
25
     public void testNonTrivialInputWithNoRectangles() {
33
     public void testNonTrivialInputWithNoRectangles() {

+ 2
- 0
exercises/rna-transcription/.meta/hints.md Visa fil

1
+For more help on how to solve this exercise, please refer to the tutorial provided as part of the hello world exercise:
2
+[TUTORIAL.md](https://github.com/exercism/java/blob/master/exercises/hello-world/TUTORIAL.md)

+ 6
- 0
exercises/rna-transcription/README.md Visa fil

18
 * `T` -> `A`
18
 * `T` -> `A`
19
 * `A` -> `U`
19
 * `A` -> `U`
20
 
20
 
21
+# Java Tips
22
+
23
+For more help on how to solve this exercise, please refer to the tutorial provided as part of the hello world exercise:
24
+[TUTORIAL.md](https://github.com/exercism/java/blob/master/exercises/hello-world/TUTORIAL.md)
25
+
26
+
21
 # Running the tests
27
 # Running the tests
22
 
28
 
23
 You can run all the tests for an exercise by entering
29
 You can run all the tests for an exercise by entering

+ 1
- 1
exercises/robot-simulator/.meta/version Visa fil

1
-1.0.0
1
+2.2.0

+ 1
- 1
exercises/robot-simulator/src/test/java/RobotTest.java Visa fil

6
 public class RobotTest {
6
 public class RobotTest {
7
 
7
 
8
     @Test
8
     @Test
9
-    public void testRobotIsCreatedWithCorrectInitialPositionAndOrientation() {
9
+    public void robotIsCreatedWithInitialPositionAndOrientation() {
10
         final Orientation initialOrientation = Orientation.NORTH;
10
         final Orientation initialOrientation = Orientation.NORTH;
11
         final GridPosition initialGridPosition = new GridPosition(0, 0);
11
         final GridPosition initialGridPosition = new GridPosition(0, 0);
12
         final Robot robot = new Robot(initialGridPosition, initialOrientation);
12
         final Robot robot = new Robot(initialGridPosition, initialOrientation);

+ 1
- 1
exercises/roman-numerals/.meta/version Visa fil

1
-1.0.0
1
+1.2.0

+ 7
- 0
exercises/roman-numerals/src/test/java/RomanNumeralsTest.java Visa fil

68
         romanNumeral = new RomanNumeral(48);
68
         romanNumeral = new RomanNumeral(48);
69
         assertEquals("XLVIII", romanNumeral.getRomanNumeral());
69
         assertEquals("XLVIII", romanNumeral.getRomanNumeral());
70
     }
70
     }
71
+    
72
+    @Ignore("Remove to run test")
73
+    @Test
74
+    public void test49ToRomanNumberXLIX() {
75
+        romanNumeral = new RomanNumeral(49);
76
+        assertEquals("XLIX", romanNumeral.getRomanNumeral());
77
+    }
71
 
78
 
72
     @Ignore("Remove to run test")
79
     @Ignore("Remove to run test")
73
     @Test
80
     @Test

+ 1
- 1
exercises/saddle-points/.meta/version Visa fil

1
-1.0.0
1
+1.1.0

+ 6
- 6
exercises/series/README.md Visa fil

1
 # Series
1
 # Series
2
 
2
 
3
 Given a string of digits, output all the contiguous substrings of length `n` in
3
 Given a string of digits, output all the contiguous substrings of length `n` in
4
-that string.
4
+that string in the order that they appear.
5
 
5
 
6
 For example, the string "49142" has the following 3-digit series:
6
 For example, the string "49142" has the following 3-digit series:
7
 
7
 
8
-- 491
9
-- 914
10
-- 142
8
+- "491"
9
+- "914"
10
+- "142"
11
 
11
 
12
 And the following 4-digit series:
12
 And the following 4-digit series:
13
 
13
 
14
-- 4914
15
-- 9142
14
+- "4914"
15
+- "9142"
16
 
16
 
17
 And if you ask for a 6-digit series from a 5-digit string, you deserve
17
 And if you ask for a 6-digit series from a 5-digit string, you deserve
18
 whatever you get.
18
 whatever you get.

+ 5
- 0
exercises/settings.gradle Visa fil

25
 include 'diamond'
25
 include 'diamond'
26
 include 'difference-of-squares'
26
 include 'difference-of-squares'
27
 include 'diffie-hellman'
27
 include 'diffie-hellman'
28
+include 'dominoes'
29
+include 'error-handling'
28
 include 'etl'
30
 include 'etl'
29
 include 'flatten-array'
31
 include 'flatten-array'
30
 include 'food-chain'
32
 include 'food-chain'
31
 include 'forth'
33
 include 'forth'
32
 include 'gigasecond'
34
 include 'gigasecond'
35
+include 'go-counting'
33
 include 'grade-school'
36
 include 'grade-school'
37
+include 'grep'
34
 include 'hamming'
38
 include 'hamming'
35
 include 'hexadecimal'
39
 include 'hexadecimal'
36
 include 'hello-world'
40
 include 'hello-world'
93
 include 'twelve-days'
97
 include 'twelve-days'
94
 include 'two-bucket'
98
 include 'two-bucket'
95
 include 'two-fer'
99
 include 'two-fer'
100
+include 'variable-length-quantity'
96
 include 'word-count'
101
 include 'word-count'
97
 include 'word-search'
102
 include 'word-search'
98
 include 'wordy'
103
 include 'wordy'

+ 5
- 3
exercises/sieve/README.md Visa fil

5
 
5
 
6
 The Sieve of Eratosthenes is a simple, ancient algorithm for finding all
6
 The Sieve of Eratosthenes is a simple, ancient algorithm for finding all
7
 prime numbers up to any given limit. It does so by iteratively marking as
7
 prime numbers up to any given limit. It does so by iteratively marking as
8
-composite (i.e. not prime) the multiples of each prime,
9
-starting with the multiples of 2.
8
+composite (i.e. not prime) the multiples of each prime, starting with the
9
+multiples of 2. It does not use any division or remainder operation.
10
 
10
 
11
 Create your range, starting at two and continuing up to and including the given limit. (i.e. [2, limit])
11
 Create your range, starting at two and continuing up to and including the given limit. (i.e. [2, limit])
12
 
12
 
25
 
25
 
26
 Notice that this is a very specific algorithm, and the tests don't check
26
 Notice that this is a very specific algorithm, and the tests don't check
27
 that you've implemented the algorithm, only that you've come up with the
27
 that you've implemented the algorithm, only that you've come up with the
28
-correct list of primes.
28
+correct list of primes. A good first test is to check that you do not use
29
+division or remainder operations (div, /, mod or % depending on the
30
+language).
29
 
31
 
30
 # Running the tests
32
 # Running the tests
31
 
33
 

+ 1
- 1
exercises/sublist/.meta/version Visa fil

1
-1.0.0
1
+1.1.0

+ 1
- 1
exercises/tournament/.meta/version Visa fil

1
-1.3.0
1
+1.4.0

+ 53
- 0
exercises/variable-length-quantity/.meta/src/reference/java/VariableLengthQuantity.java Visa fil

1
+import java.util.ArrayList;
2
+import java.util.Collections;
3
+import java.util.List;
4
+
5
+class VariableLengthQuantity {
6
+
7
+    private long sevenBitsMask = 0x7f;
8
+    private long eightBitsMask = 0x80;
9
+
10
+    List<String> encodeSingleNumber(long number) {
11
+        List<String> bytes = new ArrayList<String>();
12
+        bytes.add("0x" + Long.toHexString(number & sevenBitsMask));
13
+        number >>= 7;
14
+
15
+        while (number > 0) {
16
+            bytes.add("0x" + Long.toHexString(number & sevenBitsMask | eightBitsMask));
17
+            number >>= 7;
18
+        }
19
+
20
+        Collections.reverse(bytes);
21
+        return bytes;
22
+    }
23
+
24
+    List<String> encode(List<Long> numbers) {
25
+        List<String> bytes = new ArrayList<String>();
26
+        for (long number : numbers) {
27
+            bytes.addAll(encodeSingleNumber(number));
28
+        }
29
+
30
+        return bytes;
31
+    }
32
+
33
+    List<String> decode(List<Long> bytes) {
34
+        List<String> numbers = new ArrayList<String>();
35
+        int i = 0;
36
+        long number = 0;
37
+
38
+        for (long b : bytes) {
39
+            number <<= 7;
40
+            number += b & sevenBitsMask;
41
+
42
+            if ((b & eightBitsMask) == 0) {
43
+                numbers.add("0x" + Long.toHexString(number));
44
+                number = 0;
45
+                i++;
46
+            } else if (i == bytes.size() - 1) {
47
+                throw new IllegalArgumentException("Invalid variable-length quantity encoding");
48
+            }
49
+        }
50
+
51
+        return numbers;
52
+    }
53
+}

+ 1
- 0
exercises/variable-length-quantity/.meta/version Visa fil

1
+1.1.0

+ 0
- 0
exercises/variable-length-quantity/README.md Visa fil


Vissa filer visades inte eftersom för många filer har ändrats