Parcourir la source

Merge pull request #1 from exercism/master

Merge
Aaditya Arvind Kulkarni il y a 6 ans
Parent
révision
da4c3dd4c1
Aucun compte lié à l'adresse email de l'auteur
100 fichiers modifiés avec 2955 ajouts et 657 suppressions
  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 Voir le fichier

@@ -9,6 +9,8 @@
9 9
 * [Advanced: Complete Local Setup](#advanced-complete-local-setup)
10 10
   * [Tip: `gradle clean` before `exercism fetch`](#tip-gradle-clean-before-exercism-fetch)
11 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 15
 ## Overview
14 16
 
@@ -22,14 +24,13 @@ For general guidelines about contributing to Exercism see the [Exercism contribu
22 24
 
23 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 35
 ## Contributing With Minimal Setup
35 36
 
@@ -146,10 +147,12 @@ Any completely new exercise needs to be added and accepted there before it can b
146 147
 
147 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 149
 Please review this before porting an exercise to the Java track.
149
- 
150
+
150 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 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 157
 The Java specific details you need to know about adding an exercise are:
155 158
 
@@ -167,7 +170,7 @@ The `build.gradle` file can just be copied from any other exercise submodule.
167 170
 The `README.md` file can be generated using [configlet](https://github.com/exercism/configlet/releases).
168 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 175
   2. Clone [the problem-specifications repository](https://github.com/exercism/problem-specifications).
173 176
 
@@ -181,5 +184,37 @@ If there is canonical data available you also need to create a file at `exercise
181 184
 The canonical data version can be found at the top of the canonical data file for that exercise.
182 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 189
 Hopefully that should be enough information to help you port an exercise to the Java track.
185 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 Voir le fichier

@@ -17,7 +17,7 @@ Our policies are not set-in-stone. They represent directions chosen at a point i
17 17
 
18 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 21
 | Track rearranged | [Starter implementations](#starter-implementations); [Multiple file submissions](#multiple-file-submissions) |
22 22
 | New issue observed in track | [Good first patches](#good-first-patches) |
23 23
 | "Good first patch" issue completed | [Good first patches](#good-first-patches) |
@@ -46,7 +46,33 @@ References: [[1](https://github.com/exercism/java/issues/178)], [[2](https://git
46 46
 ### Adhere to best practices
47 47
 
48 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 77
 ### Ignore noninitial tests
52 78
 
@@ -74,7 +100,7 @@ References: [[1](https://github.com/exercism/java/issues/395#issue-215734887)]
74 100
 
75 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 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,3 +119,42 @@ References: [[1](https://github.com/exercism/java/issues/697)]
93 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 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 Voir le fichier

@@ -197,7 +197,7 @@
197 197
         "loops",
198 198
         "strings"
199 199
       ],
200
-      "unlocked_by": "rna-transcription",
200
+      "unlocked_by": "two-fer",
201 201
       "uuid": "331073b3-bd1a-4868-b767-a64ce9fd9d97"
202 202
     },
203 203
     {
@@ -398,6 +398,17 @@
398 398
     {
399 399
       "core": false,
400 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 412
       "slug": "diamond",
402 413
       "topics": [
403 414
         "arrays",
@@ -423,6 +434,21 @@
423 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 452
       "core": true,
427 453
       "difficulty": 5,
428 454
       "slug": "flatten-array",
@@ -615,15 +641,16 @@
615 641
     {
616 642
       "core": false,
617 643
       "difficulty": 5,
618
-      "slug": "two-bucket",
644
+      "slug": "grep",
619 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 656
       "core": false,
@@ -914,6 +941,19 @@
914 941
     {
915 942
       "core": false,
916 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 957
       "slug": "anagram",
918 958
       "topics": [
919 959
         "arrays",
@@ -1065,6 +1105,32 @@
1065 1105
     },
1066 1106
     {
1067 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 1134
       "difficulty": 8,
1069 1135
       "slug": "ocr-numbers",
1070 1136
       "topics": [

+ 10
- 10
exercises/acronym/src/test/java/AcronymTest.java Voir le fichier

@@ -7,40 +7,40 @@ public class AcronymTest {
7 7
 
8 8
     @Test
9 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 12
         assertEquals(expected, new Acronym(phrase).get());
13 13
     }
14 14
 
15 15
     @Ignore("Remove to run test")
16 16
     @Test
17 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 20
         assertEquals(expected, new Acronym(phrase).get());
21 21
     }
22 22
 
23 23
     @Ignore("Remove to run test")
24 24
     @Test
25 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 28
         assertEquals(expected, new Acronym(phrase).get());
29 29
     }
30 30
 
31 31
     @Ignore("Remove to run test")
32 32
     @Test
33 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 36
         assertEquals(expected, new Acronym(phrase).get());
37 37
     }
38 38
 
39 39
     @Ignore("Remove to run test")
40 40
     @Test
41 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 44
         assertEquals(expected, new Acronym(phrase).get());
45 45
     }
46 46
 

+ 1
- 1
exercises/all-your-base/.meta/version Voir le fichier

@@ -1 +1 @@
1
-2.1.0
1
+2.3.0

+ 40
- 40
exercises/all-your-base/src/test/java/BaseConverterTest.java Voir le fichier

@@ -14,10 +14,10 @@ public class BaseConverterTest {
14 14
 
15 15
     @Test
16 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 22
         assertArrayEquals(
23 23
                 String.format(
@@ -31,10 +31,10 @@ public class BaseConverterTest {
31 31
     @Ignore("Remove to run test")
32 32
     @Test
33 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 39
         assertArrayEquals(
40 40
                 String.format(
@@ -48,10 +48,10 @@ public class BaseConverterTest {
48 48
     @Ignore("Remove to run test")
49 49
     @Test
50 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 56
         assertArrayEquals(
57 57
                 String.format(
@@ -65,10 +65,10 @@ public class BaseConverterTest {
65 65
     @Ignore("Remove to run test")
66 66
     @Test
67 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 73
         assertArrayEquals(
74 74
                 String.format(
@@ -82,10 +82,10 @@ public class BaseConverterTest {
82 82
     @Ignore("Remove to run test")
83 83
     @Test
84 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 90
         assertArrayEquals(
91 91
                 String.format(
@@ -99,10 +99,10 @@ public class BaseConverterTest {
99 99
     @Ignore("Remove to run test")
100 100
     @Test
101 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 107
         assertArrayEquals(
108 108
                 String.format(
@@ -116,10 +116,10 @@ public class BaseConverterTest {
116 116
     @Ignore("Remove to run test")
117 117
     @Test
118 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 124
         assertArrayEquals(
125 125
                 String.format(
@@ -133,10 +133,10 @@ public class BaseConverterTest {
133 133
     @Ignore("Remove to run test")
134 134
     @Test
135 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 141
         assertArrayEquals(
142 142
                 String.format(
@@ -150,10 +150,10 @@ public class BaseConverterTest {
150 150
     @Ignore("Remove to run test")
151 151
     @Test
152 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 158
         assertArrayEquals(
159 159
             String.format(
@@ -167,10 +167,10 @@ public class BaseConverterTest {
167 167
     @Ignore("Remove to run test")
168 168
     @Test
169 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 175
         assertArrayEquals(
176 176
                 String.format(
@@ -184,10 +184,10 @@ public class BaseConverterTest {
184 184
     @Ignore("Remove to run test")
185 185
     @Test
186 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 192
         assertArrayEquals(
193 193
             String.format(
@@ -201,10 +201,10 @@ public class BaseConverterTest {
201 201
     @Ignore("Remove to run test")
202 202
     @Test
203 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 209
         assertArrayEquals(
210 210
             String.format(
@@ -221,7 +221,7 @@ public class BaseConverterTest {
221 221
         expectedException.expect(IllegalArgumentException.class);
222 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 227
     @Ignore("Remove to run test")
@@ -263,7 +263,7 @@ public class BaseConverterTest {
263 263
     @Ignore("Remove to run test")
264 264
     @Test
265 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 268
         expectedException.expect(IllegalArgumentException.class);
269 269
         expectedException.expectMessage("Bases must be at least 2.");
@@ -274,7 +274,7 @@ public class BaseConverterTest {
274 274
     @Ignore("Remove to run test")
275 275
     @Test
276 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 279
         expectedException.expect(IllegalArgumentException.class);
280 280
         expectedException.expectMessage("Bases must be at least 2.");
@@ -285,7 +285,7 @@ public class BaseConverterTest {
285 285
     @Ignore("Remove to run test")
286 286
     @Test
287 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 290
         expectedException.expect(IllegalArgumentException.class);
291 291
         expectedException.expectMessage("Bases must be at least 2.");

+ 1
- 0
exercises/alphametics/.meta/version Voir le fichier

@@ -0,0 +1 @@
1
+1.2.0

+ 1
- 0
exercises/binary-search-tree/.meta/version Voir le fichier

@@ -0,0 +1 @@
1
+1.0.0

+ 25
- 10
exercises/binary-search-tree/src/test/java/BinarySearchTreeTest.java Voir le fichier

@@ -95,7 +95,7 @@ public class BinarySearchTreeTest {
95 95
         );
96 96
 
97 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 100
         treeData.forEach(binarySearchTree::insert);
101 101
 
@@ -108,10 +108,10 @@ public class BinarySearchTreeTest {
108 108
     public void sortsSingleElement() {
109 109
         BinarySearchTree<String> binarySearchTree = new BinarySearchTree<>();
110 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 116
         List<String> actual = binarySearchTree.getAsSortedList();
117 117
         assertEquals(expected, actual);
@@ -122,26 +122,41 @@ public class BinarySearchTreeTest {
122 122
     public void sortsCollectionOfTwoIfSecondInsertedIsSmallerThanFirst() {
123 123
         BinarySearchTree<Integer> binarySearchTree = new BinarySearchTree<>();
124 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 128
         binarySearchTree.insert(2);
129
+        binarySearchTree.insert(1);
130 130
 
131 131
         List<Integer> actual = binarySearchTree.getAsSortedList();
132 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 150
     @Ignore("Remove to run test")
136 151
     @Test
137 152
     public void sortsCollectionOfTwoIfSecondInsertedIsBiggerThanFirst() {
138 153
         BinarySearchTree<Character> binarySearchTree = new BinarySearchTree<>();
139 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 161
         List<Character> actual = binarySearchTree.getAsSortedList();
147 162
         assertEquals(expected, actual);
@@ -152,11 +167,11 @@ public class BinarySearchTreeTest {
152 167
     public void iteratesOverComplexTree() {
153 168
         BinarySearchTree<String> binarySearchTree = new BinarySearchTree<>();
154 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 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 176
         treeData.forEach(binarySearchTree::insert);
162 177
 

+ 1
- 1
exercises/book-store/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.2.0
1
+1.3.0

+ 1
- 1
exercises/bowling/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.1.0
1
+1.2.0

+ 30
- 5
exercises/bowling/src/test/java/BowlingTest.java Voir le fichier

@@ -199,7 +199,7 @@ public class BowlingTest {
199 199
 
200 200
         game.score();
201 201
     }
202
-    
202
+
203 203
     @Ignore("Remove to run test")
204 204
     @Test
205 205
     public void twoBonusRollsAfterAStrikeInTheLastFrameCanNotScoreMoreThan10Points() {
@@ -222,7 +222,7 @@ public class BowlingTest {
222 222
 
223 223
         assertEquals(26, game.score());
224 224
     }
225
-    
225
+
226 226
     @Ignore("Remove to run test")
227 227
     @Test
228 228
     public void theSecondBonusRollsAfterAStrikeInTheLastFrameCanNotBeAStrikeIfTheFirstOneIsNotAStrike() {
@@ -235,7 +235,7 @@ public class BowlingTest {
235 235
 
236 236
         game.score();
237 237
     }
238
-    
238
+
239 239
     @Ignore("Remove to run test")
240 240
     @Test
241 241
     public void secondBonusRollAfterAStrikeInTheLastFrameCanNotScoreMoreThan10Points() {
@@ -248,7 +248,7 @@ public class BowlingTest {
248 248
 
249 249
         game.score();
250 250
     }
251
-    
251
+
252 252
     @Ignore("Remove to run test")
253 253
     @Test
254 254
     public void anUnstartedGameCanNotBeScored() {
@@ -327,4 +327,29 @@ public class BowlingTest {
327 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 Voir le fichier

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

+ 1
- 1
exercises/change/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.1.0
1
+1.2.0

+ 1
- 1
exercises/circular-buffer/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.0.1
1
+1.1.0

+ 1
- 1
exercises/clock/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.0.1
1
+2.2.1

+ 1
- 1
exercises/collatz-conjecture/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.1.1
1
+1.2.0

+ 1
- 1
exercises/complex-numbers/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.0.0
1
+1.3.0

+ 56
- 48
exercises/complex-numbers/src/test/java/ComplexNumberTest.java Voir le fichier

@@ -23,6 +23,54 @@ public class ComplexNumberTest {
23 23
     // Tests
24 24
 
25 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 74
     public void testImaginaryUnitExhibitsDefiningProperty() {
27 75
         ComplexNumber expected = new ComplexNumber(-1.0, 0);
28 76
         ComplexNumber actual = new ComplexNumber(0, 1.0).times(new ComplexNumber(0, 1.0));
@@ -191,54 +239,6 @@ public class ComplexNumberTest {
191 239
 
192 240
     @Ignore("Remove to run test")
193 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 242
     public void testExponentialOfPurelyImaginaryNumber() {
243 243
         ComplexNumber expected = new ComplexNumber(-1.0, 0);
244 244
         ComplexNumber actual = new ComplexNumber(0, Math.PI).exponentialOf();
@@ -261,4 +261,12 @@ public class ComplexNumberTest {
261 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 Voir le fichier

@@ -1 +1 @@
1
-3.1.0
1
+3.2.0

+ 4
- 5
exercises/crypto-square/README.md Voir le fichier

@@ -45,11 +45,10 @@ The message above is coded as:
45 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 53
 ```text
55 54
 imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn  sseoau 

+ 1
- 1
exercises/custom-set/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.1.0
1
+1.3.0

+ 18
- 18
exercises/difference-of-squares/src/test/java/DifferenceOfSquaresCalculatorTest.java Voir le fichier

@@ -15,72 +15,72 @@ public class DifferenceOfSquaresCalculatorTest {
15 15
 
16 16
     @Test
17 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 20
         assertEquals(expected, actual);
21 21
     }
22 22
 
23 23
     @Ignore("Remove to run test")
24 24
     @Test
25 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 28
         assertEquals(expected, actual);
29 29
     }
30 30
 
31 31
     @Ignore("Remove to run test")
32 32
     @Test
33 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 36
         assertEquals(expected, actual);
37 37
     }
38 38
 
39 39
     @Ignore("Remove to run test")
40 40
     @Test
41 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 44
         assertEquals(expected, actual);
45 45
     }
46 46
 
47 47
     @Ignore("Remove to run test")
48 48
     @Test
49 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 52
         assertEquals(expected, actual);
53 53
     }
54 54
 
55 55
     @Ignore("Remove to run test")
56 56
     @Test
57 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 60
         assertEquals(expected, actual);
61 61
     }
62 62
 
63 63
     @Ignore("Remove to run test")
64 64
     @Test
65 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 68
         assertEquals(expected, actual);
69 69
     }
70 70
 
71 71
     @Ignore("Remove to run test")
72 72
     @Test
73 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 76
         assertEquals(expected, actual);
77 77
     }
78 78
 
79 79
     @Ignore("Remove to run test")
80 80
     @Test
81 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 84
         assertEquals(expected, actual);
85 85
     }
86 86
 

+ 5
- 0
exercises/dominoes/.meta/src/reference/java/ChainNotFoundException.java Voir le fichier

@@ -0,0 +1,5 @@
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 Voir le fichier

@@ -0,0 +1,30 @@
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 Voir le fichier

@@ -0,0 +1,67 @@
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 Voir le fichier

@@ -0,0 +1,2 @@
1
+2.1.0
2
+

+ 29
- 0
exercises/dominoes/README.md Voir le fichier

@@ -0,0 +1,29 @@
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 Voir le fichier

@@ -0,0 +1,18 @@
1
+apply plugin: "java"
2
+apply plugin: "eclipse"
3
+apply plugin: "idea"
4
+
5
+repositories {
6
+    mavenCentral()
7
+}
8
+
9
+dependencies {
10
+    testCompile "junit:junit:4.12"
11
+}
12
+
13
+test {
14
+    testLogging {
15
+        exceptionFormat = 'full'
16
+        events = ["passed", "failed", "skipped"]
17
+    }
18
+}

+ 5
- 0
exercises/dominoes/src/main/java/ChainNotFoundException.java Voir le fichier

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

+ 30
- 0
exercises/dominoes/src/main/java/Domino.java Voir le fichier

@@ -0,0 +1,30 @@
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 Voir le fichier

@@ -0,0 +1,230 @@
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 Voir le fichier

@@ -0,0 +1,35 @@
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 Voir le fichier

@@ -0,0 +1,11 @@
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 Voir le fichier

@@ -0,0 +1,11 @@
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 Voir le fichier

@@ -0,0 +1,63 @@
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 Voir le fichier

@@ -0,0 +1,62 @@
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 Voir le fichier

@@ -0,0 +1,18 @@
1
+apply plugin: "java"
2
+apply plugin: "eclipse"
3
+apply plugin: "idea"
4
+
5
+repositories {
6
+  mavenCentral()
7
+}
8
+
9
+dependencies {
10
+  testCompile "junit:junit:4.12"
11
+}
12
+
13
+test {
14
+  testLogging {
15
+    exceptionFormat = 'full'
16
+    events = ["passed", "failed", "skipped"]
17
+  }
18
+}

+ 11
- 0
exercises/error-handling/src/main/java/CustomCheckedException.java Voir le fichier

@@ -0,0 +1,11 @@
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 Voir le fichier

@@ -0,0 +1,11 @@
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 Voir le fichier

@@ -0,0 +1,49 @@
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 Voir le fichier

@@ -0,0 +1,116 @@
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 Voir le fichier

@@ -1 +1 @@
1
-1.1.0
1
+1.2.0

+ 1
- 1
exercises/forth/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.4.0
1
+1.5.0

+ 152
- 0
exercises/go-counting/.meta/src/reference/java/GoCounting.java Voir le fichier

@@ -0,0 +1,152 @@
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 Voir le fichier

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

+ 2
- 0
exercises/go-counting/.meta/version Voir le fichier

@@ -0,0 +1,2 @@
1
+1.0.0
2
+

+ 50
- 0
exercises/go-counting/README.md Voir le fichier

@@ -0,0 +1,50 @@
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 Voir le fichier

@@ -0,0 +1,18 @@
1
+apply plugin: "java"
2
+apply plugin: "eclipse"
3
+apply plugin: "idea"
4
+
5
+repositories {
6
+    mavenCentral()
7
+}
8
+
9
+dependencies {
10
+    testCompile "junit:junit:4.12"
11
+}
12
+
13
+test {
14
+    testLogging {
15
+        exceptionFormat = 'full'
16
+        events = ["passed", "failed", "skipped"]
17
+    }
18
+}

+ 0
- 0
exercises/go-counting/src/main/java/.keep Voir le fichier


+ 3
- 0
exercises/go-counting/src/main/java/Player.java Voir le fichier

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

+ 178
- 0
exercises/go-counting/src/test/java/GoCountingTest.java Voir le fichier

@@ -0,0 +1,178 @@
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 Voir le fichier

@@ -0,0 +1,58 @@
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 Voir le fichier

@@ -0,0 +1,65 @@
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 Voir le fichier


+ 145
- 0
exercises/grep/README.md Voir le fichier

@@ -0,0 +1,145 @@
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 Voir le fichier

@@ -0,0 +1,18 @@
1
+apply plugin: "java"
2
+apply plugin: "eclipse"
3
+apply plugin: "idea"
4
+
5
+repositories {
6
+    mavenCentral()
7
+}
8
+
9
+dependencies {
10
+    testCompile "junit:junit:4.12"
11
+}
12
+
13
+test {
14
+    testLogging {
15
+        exceptionFormat = 'full'
16
+        events = ["passed", "failed", "skipped"]
17
+    }
18
+}

+ 0
- 0
exercises/grep/src/main/java/.keep Voir le fichier


+ 395
- 0
exercises/grep/src/test/java/GrepToolTest.java Voir le fichier

@@ -0,0 +1,395 @@
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 Voir le fichier

@@ -33,7 +33,7 @@ class House {
33 33
         verse.append("This is the " + CHARACTERS[verseNumber - 1]);
34 34
 
35 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 39
         return verse.toString();
@@ -46,7 +46,7 @@ class House {
46 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 52
     String sing() {

+ 1
- 1
exercises/house/.meta/version Voir le fichier

@@ -1 +1 @@
1
-2.0.0
1
+2.2.0

+ 157
- 172
exercises/house/src/test/java/HouseTest.java Voir le fichier

@@ -25,7 +25,7 @@ public class HouseTest {
25 25
     @Test
26 26
     public void verseTwo() {
27 27
         String expected =
28
-                "This is the malt\n" +
28
+                "This is the malt " +
29 29
                 "that lay in the house that Jack built.";
30 30
         int verse = 2;
31 31
 
@@ -36,8 +36,8 @@ public class HouseTest {
36 36
     @Test
37 37
     public void verseThree() {
38 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 41
                 "that lay in the house that Jack built.";
42 42
         int verse = 3;
43 43
 
@@ -48,9 +48,9 @@ public class HouseTest {
48 48
     @Test
49 49
     public void verseFour() {
50 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 54
                 "that lay in the house that Jack built.";
55 55
         int verse = 4;
56 56
 
@@ -61,10 +61,10 @@ public class HouseTest {
61 61
     @Test
62 62
     public void verseFive() {
63 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 68
                 "that lay in the house that Jack built.";
69 69
         int verse = 5;
70 70
 
@@ -75,11 +75,11 @@ public class HouseTest {
75 75
     @Test
76 76
     public void verseSix() {
77 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 83
                 "that lay in the house that Jack built.";
84 84
         int verse = 6;
85 85
 
@@ -90,12 +90,12 @@ public class HouseTest {
90 90
     @Test
91 91
     public void verseSeven() {
92 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 99
                 "that lay in the house that Jack built.";
100 100
         int verse = 7;
101 101
 
@@ -106,13 +106,13 @@ public class HouseTest {
106 106
     @Test
107 107
     public void verseEight() {
108 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 116
                 "that lay in the house that Jack built.";
117 117
         int verse = 8;
118 118
 
@@ -123,14 +123,14 @@ public class HouseTest {
123 123
     @Test
124 124
     public void verseNine() {
125 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 134
                 "that lay in the house that Jack built.";
135 135
         int verse = 9;
136 136
 
@@ -141,15 +141,15 @@ public class HouseTest {
141 141
     @Test
142 142
     public void verse10() {
143 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 153
                 "that lay in the house that Jack built.";
154 154
         int verse = 10;
155 155
 
@@ -160,16 +160,16 @@ public class HouseTest {
160 160
     @Test
161 161
     public void verse11() {
162 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 173
                 "that lay in the house that Jack built.";
174 174
         int verse = 11;
175 175
 
@@ -180,17 +180,17 @@ public class HouseTest {
180 180
     @Test
181 181
     public void verse12() {
182 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 194
                 "that lay in the house that Jack built.";
195 195
         int verse = 12;
196 196
 
@@ -201,39 +201,35 @@ public class HouseTest {
201 201
     @Test
202 202
     public void multipleVerses() {
203 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 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 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 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 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 233
                 "that lay in the house that Jack built.";
238 234
 
239 235
         int startVerse = 4;
@@ -247,93 +243,82 @@ public class HouseTest {
247 243
     public void wholeRhyme() {
248 244
         String expected =
249 245
                 "This is the house that Jack built.\n" +
250
-                "\n" +
251
-                "This is the malt\n" +
246
+                "This is the malt " +
252 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 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 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 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 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 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 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 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 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 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 322
                 "that lay in the house that Jack built.";
338 323
 
339 324
         assertEquals(expected, house.sing());

+ 1
- 1
exercises/isogram/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.2.0
1
+1.3.0

+ 36
- 36
exercises/largest-series-product/src/test/java/LargestSeriesProductCalculatorTest.java Voir le fichier

@@ -12,10 +12,10 @@ public class LargestSeriesProductCalculatorTest {
12 12
 
13 13
     @Test
14 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 20
         assertEquals(expectedProduct, actualProduct);
21 21
     }
@@ -23,10 +23,10 @@ public class LargestSeriesProductCalculatorTest {
23 23
     @Ignore("Remove to run test")
24 24
     @Test
25 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 31
         assertEquals(expectedProduct, actualProduct);
32 32
     }
@@ -34,10 +34,10 @@ public class LargestSeriesProductCalculatorTest {
34 34
     @Ignore("Remove to run test")
35 35
     @Test
36 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 42
         assertEquals(expectedProduct, actualProduct);
43 43
     }
@@ -45,10 +45,10 @@ public class LargestSeriesProductCalculatorTest {
45 45
     @Ignore("Remove to run test")
46 46
     @Test
47 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 53
         assertEquals(expectedProduct, actualProduct);
54 54
     }
@@ -56,10 +56,10 @@ public class LargestSeriesProductCalculatorTest {
56 56
     @Ignore("Remove to run test")
57 57
     @Test
58 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 64
         assertEquals(expectedProduct, actualProduct);
65 65
     }
@@ -67,10 +67,10 @@ public class LargestSeriesProductCalculatorTest {
67 67
     @Ignore("Remove to run test")
68 68
     @Test
69 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 75
         assertEquals(expectedProduct, actualProduct);
76 76
     }
@@ -78,12 +78,12 @@ public class LargestSeriesProductCalculatorTest {
78 78
     @Ignore("Remove to run test")
79 79
     @Test
80 80
     public void testCorrectlyCalculatesLargestProductInLongStringToSearchV1() {
81
-        final LargestSeriesProductCalculator calculator
81
+        LargestSeriesProductCalculator calculator
82 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 88
         assertEquals(expectedProduct, actualProduct);
89 89
     }
@@ -91,10 +91,10 @@ public class LargestSeriesProductCalculatorTest {
91 91
     @Ignore("Remove to run test")
92 92
     @Test
93 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 99
         assertEquals(expectedProduct, actualProduct);
100 100
     }
@@ -102,10 +102,10 @@ public class LargestSeriesProductCalculatorTest {
102 102
     @Ignore("Remove to run test")
103 103
     @Test
104 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 110
         assertEquals(expectedProduct, actualProduct);
111 111
     }
@@ -113,7 +113,7 @@ public class LargestSeriesProductCalculatorTest {
113 113
     @Ignore("Remove to run test")
114 114
     @Test
115 115
     public void testSeriesLengthLongerThanLengthOfStringToTestIsRejected() {
116
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("123");
116
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("123");
117 117
 
118 118
         expectedException.expect(IllegalArgumentException.class);
119 119
         expectedException.expectMessage(
@@ -125,10 +125,10 @@ public class LargestSeriesProductCalculatorTest {
125 125
     @Ignore("Remove to run test")
126 126
     @Test
127 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 133
         assertEquals(expectedProduct, actualProduct);
134 134
     }
@@ -136,10 +136,10 @@ public class LargestSeriesProductCalculatorTest {
136 136
     @Ignore("Remove to run test")
137 137
     @Test
138 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 144
         assertEquals(expectedProduct, actualProduct);
145 145
     }
@@ -147,7 +147,7 @@ public class LargestSeriesProductCalculatorTest {
147 147
     @Ignore("Remove to run test")
148 148
     @Test
149 149
     public void testEmptyStringToSearchAndSeriesOfNonZeroLengthIsRejected() {
150
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("");
150
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("");
151 151
 
152 152
         expectedException.expect(IllegalArgumentException.class);
153 153
         expectedException.expectMessage(
@@ -168,7 +168,7 @@ public class LargestSeriesProductCalculatorTest {
168 168
     @Ignore("Remove to run test")
169 169
     @Test
170 170
     public void testNegativeSeriesLengthIsRejected() {
171
-        final LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("12345");
171
+        LargestSeriesProductCalculator calculator = new LargestSeriesProductCalculator("12345");
172 172
 
173 173
         expectedException.expect(IllegalArgumentException.class);
174 174
         expectedException.expectMessage("Series length must be non-negative.");

+ 1
- 1
exercises/list-ops/.meta/version Voir le fichier

@@ -1 +1 @@
1
-2.0.0
1
+2.2.0

+ 1
- 1
exercises/markdown/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.1.0
1
+1.2.0

+ 1
- 1
exercises/minesweeper/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.0.0
1
+1.1.0

+ 36
- 36
exercises/minesweeper/src/test/java/MinesweeperBoardTest.java Voir le fichier

@@ -11,9 +11,9 @@ public class MinesweeperBoardTest {
11 11
 
12 12
     @Test
13 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 18
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
19 19
     }
@@ -21,9 +21,9 @@ public class MinesweeperBoardTest {
21 21
     @Ignore("Remove to run test")
22 22
     @Test
23 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 28
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
29 29
     }
@@ -31,19 +31,19 @@ public class MinesweeperBoardTest {
31 31
     @Ignore("Remove to run test")
32 32
     @Test
33 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 48
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
49 49
     }
@@ -51,19 +51,19 @@ public class MinesweeperBoardTest {
51 51
     @Ignore("Remove to run test")
52 52
     @Test
53 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 68
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
69 69
     }
@@ -71,19 +71,19 @@ public class MinesweeperBoardTest {
71 71
     @Ignore("Remove to run test")
72 72
     @Test
73 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 81
                 "111",
82 82
                 "1*1",
83 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 88
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
89 89
     }
@@ -91,19 +91,19 @@ public class MinesweeperBoardTest {
91 91
     @Ignore("Remove to run test")
92 92
     @Test
93 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 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 108
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
109 109
     }
@@ -111,15 +111,15 @@ public class MinesweeperBoardTest {
111 111
     @Ignore("Remove to run test")
112 112
     @Test
113 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 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 124
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
125 125
     }
@@ -127,15 +127,15 @@ public class MinesweeperBoardTest {
127 127
     @Ignore("Remove to run test")
128 128
     @Test
129 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 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 140
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
141 141
     }
@@ -143,7 +143,7 @@ public class MinesweeperBoardTest {
143 143
     @Ignore("Remove to run test")
144 144
     @Test
145 145
     public void testInputBoardWithSingleColumnAndTwoMines() {
146
-        final List<String> inputBoard = Arrays.asList(
146
+        List<String> inputBoard = Arrays.asList(
147 147
                 " ",
148 148
                 "*",
149 149
                 " ",
@@ -151,7 +151,7 @@ public class MinesweeperBoardTest {
151 151
                 " "
152 152
         );
153 153
 
154
-        final List<String> expectedNumberedBoard = Arrays.asList(
154
+        List<String> expectedNumberedBoard = Arrays.asList(
155 155
                 "1",
156 156
                 "*",
157 157
                 "2",
@@ -159,7 +159,7 @@ public class MinesweeperBoardTest {
159 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 164
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
165 165
     }
@@ -167,7 +167,7 @@ public class MinesweeperBoardTest {
167 167
     @Ignore("Remove to run test")
168 168
     @Test
169 169
     public void testInputBoardWithSingleColumnAndTwoMinesAtEdges() {
170
-        final List<String> inputBoard = Arrays.asList(
170
+        List<String> inputBoard = Arrays.asList(
171 171
                 "*",
172 172
                 " ",
173 173
                 " ",
@@ -175,7 +175,7 @@ public class MinesweeperBoardTest {
175 175
                 "*"
176 176
         );
177 177
 
178
-        final List<String> expectedNumberedBoard = Arrays.asList(
178
+        List<String> expectedNumberedBoard = Arrays.asList(
179 179
                 "*",
180 180
                 "1",
181 181
                 " ",
@@ -183,7 +183,7 @@ public class MinesweeperBoardTest {
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 188
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
189 189
     }
@@ -191,7 +191,7 @@ public class MinesweeperBoardTest {
191 191
     @Ignore("Remove to run test")
192 192
     @Test
193 193
     public void testInputBoardWithMinesInCross() {
194
-        final List<String> inputBoard = Arrays.asList(
194
+        List<String> inputBoard = Arrays.asList(
195 195
                 "  *  ",
196 196
                 "  *  ",
197 197
                 "*****",
@@ -199,7 +199,7 @@ public class MinesweeperBoardTest {
199 199
                 "  *  "
200 200
         );
201 201
 
202
-        final List<String> expectedNumberedBoard = Arrays.asList(
202
+        List<String> expectedNumberedBoard = Arrays.asList(
203 203
                 " 2*2 ",
204 204
                 "25*52",
205 205
                 "*****",
@@ -207,7 +207,7 @@ public class MinesweeperBoardTest {
207 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 212
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
213 213
     }
@@ -215,7 +215,7 @@ public class MinesweeperBoardTest {
215 215
     @Ignore("Remove to run test")
216 216
     @Test
217 217
     public void testLargeInputBoard() {
218
-        final List<String> inputBoard = Arrays.asList(
218
+        List<String> inputBoard = Arrays.asList(
219 219
                 " *  * ",
220 220
                 "  *   ",
221 221
                 "    * ",
@@ -224,7 +224,7 @@ public class MinesweeperBoardTest {
224 224
                 "      "
225 225
         );
226 226
 
227
-        final List<String> expectedNumberedBoard = Arrays.asList(
227
+        List<String> expectedNumberedBoard = Arrays.asList(
228 228
                 "1*22*1",
229 229
                 "12*322",
230 230
                 " 123*2",
@@ -233,7 +233,7 @@ public class MinesweeperBoardTest {
233 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 238
         assertEquals(expectedNumberedBoard, actualNumberedBoard);
239 239
     }

+ 1
- 1
exercises/nth-prime/.meta/version Voir le fichier

@@ -1 +1 @@
1
-2.0.0
1
+2.1.0

+ 1
- 1
exercises/ocr-numbers/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.0.0
1
+1.1.0

+ 1
- 1
exercises/perfect-numbers/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.0.1
1
+1.1.0

+ 14
- 14
exercises/phone-number/src/test/java/PhoneNumberTest.java Voir le fichier

@@ -6,12 +6,12 @@ import org.junit.rules.ExpectedException;
6 6
 import static org.junit.Assert.assertEquals;
7 7
 
8 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 11
             "Can only have 11 digits if number starts with '1'";
12
-    private final static String illegalCharacterExceptionMessage =
12
+    private static String illegalCharacterExceptionMessage =
13 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 15
             "Illegal Area Or Exchange Code. Only 2-9 are valid digits";
16 16
 
17 17
     @Rule
@@ -19,8 +19,8 @@ public class PhoneNumberTest {
19 19
 
20 20
     @Test
21 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 25
         assertEquals(
26 26
                 expectedNumber, actualNumber
@@ -30,8 +30,8 @@ public class PhoneNumberTest {
30 30
     @Ignore("Remove to run test")
31 31
     @Test
32 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 36
         assertEquals(
37 37
                 expectedNumber, actualNumber
@@ -41,8 +41,8 @@ public class PhoneNumberTest {
41 41
     @Ignore("Remove to run test")
42 42
     @Test
43 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 47
         assertEquals(
48 48
                 expectedNumber, actualNumber
@@ -68,8 +68,8 @@ public class PhoneNumberTest {
68 68
     @Ignore("Remove to run test")
69 69
     @Test
70 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 74
         assertEquals(
75 75
                 expectedNumber, actualNumber
@@ -79,8 +79,8 @@ public class PhoneNumberTest {
79 79
     @Ignore("Remove to run test")
80 80
     @Test
81 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 85
         assertEquals(
86 86
                 expectedNumber, actualNumber

+ 4
- 4
exercises/pig-latin/README.md Voir le fichier

@@ -7,10 +7,10 @@ confusing. It obeys a few simple rules (below), but when it's spoken
7 7
 quickly it's really difficult for non-children (and non-native speakers)
8 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 15
 There are a few more rules for edge cases, and there are regional
16 16
 variants too.

+ 5
- 2
exercises/poker/.meta/src/reference/java/Card.java Voir le fichier

@@ -16,10 +16,13 @@ class Card {
16 16
     }
17 17
 
18 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 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 Voir le fichier

@@ -38,10 +38,9 @@ class Hand {
38 38
         }
39 39
         return frequencyMap;
40 40
     }
41
-
41
+    
42 42
     private int scoreHand(List<Card> cards) {
43
-        List<Card> cardsByRank = cards
44
-                .stream()
43
+        List<Card> cardsByRank = cards.stream()
45 44
                 .sorted(Comparator.comparing(Card::getRank))
46 45
                 .unordered()
47 46
                 .collect(Collectors.toList());
@@ -63,7 +62,10 @@ class Hand {
63 62
                 .stream()
64 63
                 .map(Map.Entry::getValue)
65 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 70
         return calculatedScore(frequencyMap, cardsByRank, ranks, rankCounts, suits);
69 71
     }
@@ -74,9 +76,15 @@ class Hand {
74 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 86
         Iterator<Integer> iteratorOverFrequencies = frequencyMap.keySet().iterator();
87
+        
80 88
         int highestFrequency = iteratorOverFrequencies.next();
81 89
 
82 90
         if (straight && flush) {
@@ -86,24 +94,55 @@ class Hand {
86 94
             return 700 + cardsByRank.get(0).getRank();
87 95
         }
88 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 109
         if (flush) {
92 110
             return 500 + highestFrequency;
93 111
         }
94 112
         if (straight) {
95
-            return 400 + highestFrequency;
113
+            int maxValue = Collections.max(ranks);
114
+            return 400 + maxValue;
96 115
         }
97 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 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 138
         if (rankCounts.equals(Arrays.asList(2, 1, 1, 1))) {
104 139
             return 100 + highestFrequency;
105 140
         }
106 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 Voir le fichier

@@ -0,0 +1 @@
1
+1.1.0

+ 143
- 66
exercises/poker/src/test/java/PokerTest.java Voir le fichier

@@ -2,162 +2,239 @@ import org.junit.Ignore;
2 2
 import org.junit.Test;
3 3
 
4 4
 import java.util.Arrays;
5
+import java.util.Collections;
5 6
 
6 7
 import static org.junit.Assert.assertEquals;
7 8
 
8 9
 public class PokerTest {
9 10
     @Test
10 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 44
     @Ignore("Remove to run test")
16 45
     @Test
17 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 52
     @Ignore("Remove to run test")
24 53
     @Test
25 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 60
     @Ignore("Remove to run test")
32 61
     @Test
33 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 68
     @Ignore("Remove to run test")
40 69
     @Test
41 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 94
     @Ignore("Remove to run test")
48 95
     @Test
49 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 102
     @Ignore("Remove to run test")
56 103
     @Test
57 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 119
     @Ignore("Remove to run test")
64 120
     @Test
65 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 143
     @Ignore("Remove to run test")
72 144
     @Test
73 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 159
     @Ignore("Remove to run test")
84 160
     @Test
85 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 167
     @Ignore("Remove to run test")
92 168
     @Test
93 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 175
     @Ignore("Remove to run test")
100 176
     @Test
101 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 183
     @Ignore("Remove to run test")
108 184
     @Test
109 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 191
     @Ignore("Remove to run test")
116 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 199
     @Ignore("Remove to run test")
124 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 207
     @Ignore("Remove to run test")
132 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 215
     @Ignore("Remove to run test")
140 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 223
     @Ignore("Remove to run test")
148 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 232
     @Ignore("Remove to run test")
157 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 Voir le fichier

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

+ 0
- 39
exercises/queen-attack/.meta/src/reference/java/BoardCoordinate.java Voir le fichier

@@ -1,39 +0,0 @@
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 Voir le fichier

@@ -0,0 +1,38 @@
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 Voir le fichier

@@ -1,14 +1,13 @@
1 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 12
         validateInputs();
14 13
     }
@@ -17,13 +16,13 @@ final class QueenAttackCalculator {
17 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 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,11 +43,11 @@ final class QueenAttackCalculator {
44 43
     }
45 44
 
46 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 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 Voir le fichier

@@ -1 +1 @@
1
-2.0.0
1
+2.1.0

+ 50
- 44
exercises/queen-attack/src/test/java/QueenAttackCalculatorTest.java Voir le fichier

@@ -12,119 +12,125 @@ public class QueenAttackCalculatorTest {
12 12
     public ExpectedException expectedException = ExpectedException.none();
13 13
 
14 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 28
     @Ignore("Remove to run test")
23 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 37
     @Ignore("Remove to run test")
32 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 46
     @Ignore("Remove to run test")
41 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 55
     @Ignore("Remove to run test")
50 56
     @Test
51
-    public void testQueensCanAttackOnSecondDiagonal() {
57
+    public void testQueensCannotAttack() {
52 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 64
     @Ignore("Remove to run test")
59 65
     @Test
60
-    public void testQueensCanAttackOnThirdDiagonal() {
66
+    public void testQueensCanAttackOnTheSameRow() {
61 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 70
         assertTrue(calculator.canQueensAttackOneAnother());
65 71
     }
66 72
 
67 73
     @Ignore("Remove to run test")
68 74
     @Test
69
-    public void testQueensCanAttackOnFourthDiagonal() {
75
+    public void testQueensCanAttackOnTheSameColumn() {
70 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 79
         assertTrue(calculator.canQueensAttackOneAnother());
74 80
     }
75 81
 
76 82
     @Ignore("Remove to run test")
77 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 91
     @Ignore("Remove to run test")
86 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 100
     @Ignore("Remove to run test")
95 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 109
     @Ignore("Remove to run test")
104 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 118
     @Ignore("Remove to run test")
113 119
     @Test
114
-    public void testNullCoordinateNotAllowed() {
120
+    public void testNullPositionsNotAllowed() {
115 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 127
     @Ignore("Remove to run test")
122 128
     @Test
123 129
     public void testQueensMustNotOccupyTheSameSquare() {
124 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 Voir le fichier

@@ -1 +1 @@
1
-1.0.0
1
+1.1.0

+ 9
- 1
exercises/rectangles/src/test/java/RectangleCounterTest.java Voir le fichier

@@ -14,12 +14,20 @@ public class RectangleCounterTest {
14 14
     }
15 15
 
16 16
     @Test
17
-    public void testInputWithNoColumnsContainsNoRectangles() {
17
+    public void testInputWithNoRowsContainsNoRectangles() {
18 18
         String[] inputGrid = new String[]{};
19 19
 
20 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 31
     @Ignore("Remove to run test")
24 32
     @Test
25 33
     public void testNonTrivialInputWithNoRectangles() {

+ 2
- 0
exercises/rna-transcription/.meta/hints.md Voir le fichier

@@ -0,0 +1,2 @@
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 Voir le fichier

@@ -18,6 +18,12 @@ each nucleotide with its complement:
18 18
 * `T` -> `A`
19 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 27
 # Running the tests
22 28
 
23 29
 You can run all the tests for an exercise by entering

+ 1
- 1
exercises/robot-simulator/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.0.0
1
+2.2.0

+ 1
- 1
exercises/robot-simulator/src/test/java/RobotTest.java Voir le fichier

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

+ 1
- 1
exercises/roman-numerals/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.0.0
1
+1.2.0

+ 7
- 0
exercises/roman-numerals/src/test/java/RomanNumeralsTest.java Voir le fichier

@@ -68,6 +68,13 @@ public class RomanNumeralsTest {
68 68
         romanNumeral = new RomanNumeral(48);
69 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 79
     @Ignore("Remove to run test")
73 80
     @Test

+ 1
- 1
exercises/saddle-points/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.0.0
1
+1.1.0

+ 6
- 6
exercises/series/README.md Voir le fichier

@@ -1,18 +1,18 @@
1 1
 # Series
2 2
 
3 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 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 12
 And the following 4-digit series:
13 13
 
14
-- 4914
15
-- 9142
14
+- "4914"
15
+- "9142"
16 16
 
17 17
 And if you ask for a 6-digit series from a 5-digit string, you deserve
18 18
 whatever you get.

+ 5
- 0
exercises/settings.gradle Voir le fichier

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

+ 5
- 3
exercises/sieve/README.md Voir le fichier

@@ -5,8 +5,8 @@ number.
5 5
 
6 6
 The Sieve of Eratosthenes is a simple, ancient algorithm for finding all
7 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 11
 Create your range, starting at two and continuing up to and including the given limit. (i.e. [2, limit])
12 12
 
@@ -25,7 +25,9 @@ https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
25 25
 
26 26
 Notice that this is a very specific algorithm, and the tests don't check
27 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 32
 # Running the tests
31 33
 

+ 1
- 1
exercises/sublist/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.0.0
1
+1.1.0

+ 1
- 1
exercises/tournament/.meta/version Voir le fichier

@@ -1 +1 @@
1
-1.3.0
1
+1.4.0

+ 53
- 0
exercises/variable-length-quantity/.meta/src/reference/java/VariableLengthQuantity.java Voir le fichier

@@ -0,0 +1,53 @@
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 Voir le fichier

@@ -0,0 +1 @@
1
+1.1.0

+ 0
- 0
exercises/variable-length-quantity/README.md Voir le fichier


Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff