trackler 2.2.1.153 → 2.2.1.154

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/grade-school/canonical-data.json +68 -0
  4. data/problem-specifications/exercises/luhn/canonical-data.json +9 -1
  5. data/problem-specifications/exercises/say/description.md +1 -1
  6. data/problem-specifications/exercises/word-search/canonical-data.json +2 -3
  7. data/tracks/csharp/exercises/go-counting/Example.cs +49 -42
  8. data/tracks/csharp/exercises/go-counting/GoCounting.cs +3 -3
  9. data/tracks/csharp/exercises/go-counting/GoCountingTest.cs +137 -88
  10. data/tracks/csharp/exercises/palindrome-products/Example.cs +25 -34
  11. data/tracks/csharp/exercises/palindrome-products/PalindromeProducts.cs +3 -29
  12. data/tracks/csharp/exercises/palindrome-products/PalindromeProductsTest.cs +103 -0
  13. data/tracks/csharp/exercises/word-search/Example.cs +24 -16
  14. data/tracks/csharp/exercises/word-search/WordSearch.cs +2 -2
  15. data/tracks/csharp/exercises/word-search/WordSearchTest.cs +539 -66
  16. data/tracks/csharp/generators/Exercises/GoCounting.cs +95 -0
  17. data/tracks/csharp/generators/Exercises/PalindromeProducts.cs +47 -0
  18. data/tracks/csharp/generators/Exercises/WordSearch.cs +84 -0
  19. data/tracks/csharp/generators/Output/ValueFormatter.cs +6 -0
  20. data/tracks/delphi/exercises/grade-school/uGradeSchoolTest.pas +4 -4
  21. data/tracks/ecmascript/.travis.yml +3 -1
  22. data/tracks/ecmascript/exercises/linked-list/linked-list.spec.js +16 -0
  23. data/tracks/elm/config.json +9 -1
  24. data/tracks/elm/exercises/bracket-push/BracketPush.elm +6 -0
  25. data/tracks/elm/exercises/bracket-push/BracketPush.example.elm +50 -0
  26. data/tracks/elm/exercises/bracket-push/README.md +40 -0
  27. data/tracks/elm/exercises/bracket-push/elm-package.json +14 -0
  28. data/tracks/elm/exercises/bracket-push/tests/Tests.elm +71 -0
  29. data/tracks/elm/exercises/bracket-push/tests/elm-package.json +16 -0
  30. data/tracks/go/config.json +14 -3
  31. data/tracks/go/exercises/linked-list/README.md +59 -0
  32. data/tracks/go/exercises/linked-list/cases_test.go +189 -0
  33. data/tracks/go/exercises/linked-list/example.go +212 -0
  34. data/tracks/go/exercises/linked-list/linked_list_test.go +106 -0
  35. data/tracks/java/exercises/go-counting/.meta/src/reference/java/GoCounting.java +6 -12
  36. data/tracks/java/exercises/go-counting/src/test/java/GoCountingTest.java +12 -12
  37. data/tracks/java/exercises/kindergarten-garden/src/main/java/KindergartenGarden.java +0 -4
  38. data/tracks/python/exercises/hamming/README.md +4 -3
  39. data/tracks/rust/exercises/beer-song/src/lib.rs +7 -7
  40. data/tracks/rust/exercises/bob/src/lib.rs +3 -3
  41. data/tracks/rust/exercises/difference-of-squares/src/lib.rs +14 -14
  42. data/tracks/rust/exercises/leap/src/lib.rs +3 -3
  43. data/tracks/rust/exercises/perfect-numbers/src/lib.rs +10 -10
  44. data/tracks/rust/exercises/proverb/src/lib.rs +3 -3
  45. data/tracks/rust/exercises/pythagorean-triplet/src/lib.rs +3 -3
  46. data/tracks/rust/exercises/raindrops/src/lib.rs +3 -3
  47. data/tracks/rust/exercises/sum-of-multiples/src/lib.rs +3 -3
  48. metadata +17 -3
  49. data/tracks/csharp/exercises/palindrome-products/PalindromeTest.cs +0 -69
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e991216d9ea33bd87ff86e3588f1cf95947a7897
4
- data.tar.gz: e97ed241757d28be0a367f79cef2dd736c706bfd
3
+ metadata.gz: 891cfc46c3753f1097f043124ad3d933b970024b
4
+ data.tar.gz: f77a21a3997e6167c19f64eace521749c90a8397
5
5
  SHA512:
6
- metadata.gz: dde1e87b24a0de86ea3d2de1bb5ac31f6e33c2d45cc907682a8518e76c65aa9cd611a09c35603feee4df96a5550a2bd146817ab61f161f71357c63cfdaab69da
7
- data.tar.gz: 7551620e5417926310541ccb3c2f711610a817149d068a2b5c28df0f1f2e2c2b608272fc6cab46ae71801f239adf74b1a6ebd684225f907763f3a0880e4d035a
6
+ metadata.gz: 0e47f625db64fa5a520715350120cf821dff4e07df8a6d640daf4c21cba9bcd21545a5a9ae6f33599aea4bd2413c2a4afc0ec2afd21fed91f1ffb048e3cf3f14
7
+ data.tar.gz: 05c5ed9423ef4bb614a0476f8888ffefb753422189a6ae0a91ce0809994473dbea666cb39c8a9a6bab94af00a03479a0685fc65157e0ffaaf9db2a179dd44abe
@@ -1,3 +1,3 @@
1
1
  module Trackler
2
- VERSION = "2.2.1.153"
2
+ VERSION = "2.2.1.154"
3
3
  end
@@ -0,0 +1,68 @@
1
+ {
2
+ "exercise": "grade-school",
3
+ "version": "1.0.0",
4
+ "comments": [
5
+ "Given students' names along with the grade that they are in, ",
6
+ "create a roster for the school."
7
+ ],
8
+ "cases": [
9
+ {
10
+ "description": "Adding a student adds them to the sorted roster",
11
+ "property": "roster",
12
+ "input": {
13
+ "students": [["Aimee", 2]]
14
+ },
15
+ "expected": ["Aimee"]
16
+ },
17
+ {
18
+ "description": "Adding more student adds them to the sorted roster",
19
+ "property": "roster",
20
+ "input": {
21
+ "students": [["Blair", 2], ["James", 2], ["Paul", 2]]
22
+ },
23
+ "expected": ["Blair", "James", "Paul"]
24
+ },
25
+ {
26
+ "description": "Adding students to different grades adds them to the same sorted roster",
27
+ "property": "roster",
28
+ "input": {
29
+ "students": [["Chelsea", 3], ["Logan", 7]]
30
+ },
31
+ "expected": ["Chelsea", "Logan"]
32
+ },
33
+ {
34
+ "description": "Roster returns an empty list if there are no students enrolled",
35
+ "property": "roster",
36
+ "input": {
37
+ "students": []
38
+ },
39
+ "expected": []
40
+ },
41
+ {
42
+ "description": "Student names with grades are displayed in the same sorted roster",
43
+ "property": "roster",
44
+ "input": {
45
+ "students": [["Peter", 2], ["Anna", 1], ["Barb", 1], ["Zoe", 2], ["Alex", 2], ["Jim", 3], ["Charlie", 1]]
46
+ },
47
+ "expected": ["Anna", "Barb", "Charlie", "Alex", "Peter", "Zoe", "Jim"]
48
+ },
49
+ {
50
+ "description": "Grade returns the students in that grade in alphabetical order",
51
+ "property": "grade",
52
+ "input": {
53
+ "students": [["Franklin", 5], ["Bradley", 5], ["Jeff", 1]],
54
+ "desiredGrade": 5
55
+ },
56
+ "expected": ["Bradley", "Franklin"]
57
+ },
58
+ {
59
+ "description": "Grade returns an empty list if there are no students in that grade",
60
+ "property": "grade",
61
+ "input": {
62
+ "students": [],
63
+ "desiredGrade": 1
64
+ },
65
+ "expected": []
66
+ }
67
+ ]
68
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "exercise": "luhn",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "cases": [
5
5
  {
6
6
  "description": "single digit strings can not be valid",
@@ -105,6 +105,14 @@
105
105
  "value": "091"
106
106
  },
107
107
  "expected": true
108
+ },
109
+ {
110
+ "description": "strings with non-digits is invalid",
111
+ "property": "valid",
112
+ "input": {
113
+ "value": ":9"
114
+ },
115
+ "expected": false
108
116
  }
109
117
  ]
110
118
  }
@@ -22,7 +22,7 @@ Some good test cases for this program are:
22
22
  ### Extension
23
23
 
24
24
  If you're on a Mac, shell out to Mac OS X's `say` program to talk out
25
- loud.
25
+ loud. If you're on Linux or Windows, eSpeakNG may be available with the command `espeak`.
26
26
 
27
27
  ## Step 2
28
28
 
@@ -1,9 +1,8 @@
1
1
  {
2
2
  "exercise": "word-search",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "comments": [
5
- "Grid rows and columns are 1-indexed.",
6
- "An expected value of -1 indicates that some sort of failure should occur."
5
+ "Grid rows and columns are 1-indexed."
7
6
  ],
8
7
  "cases": [
9
8
  {
@@ -2,7 +2,7 @@
2
2
  using System.Collections.Generic;
3
3
  using System.Linq;
4
4
 
5
- public enum GoPlayer
5
+ public enum Owner
6
6
  {
7
7
  None,
8
8
  Black,
@@ -11,74 +11,71 @@ public enum GoPlayer
11
11
 
12
12
  public class GoCounting
13
13
  {
14
- private readonly GoPlayer[][] board;
14
+ private readonly Owner[][] board;
15
15
 
16
16
  public GoCounting(string input)
17
17
  {
18
18
  board = ParseBoard(input);
19
19
  }
20
20
 
21
- private static GoPlayer CharToPlayer(char c)
21
+ private static Owner CharToPlayer(char c)
22
22
  {
23
23
  switch (c)
24
24
  {
25
- case 'B': return GoPlayer.Black;
26
- case 'W': return GoPlayer.White;
27
- default: return GoPlayer.None;
25
+ case 'B': return Owner.Black;
26
+ case 'W': return Owner.White;
27
+ default: return Owner.None;
28
28
  }
29
29
  }
30
30
 
31
- private static GoPlayer[][] ParseBoard(string input)
31
+ private static Owner[][] ParseBoard(string input)
32
32
  {
33
33
  var split = input.Split('\n');
34
- var rows = split.Length;
35
- var cols = split[0].Length;
36
-
37
34
  return split.Select(row => row.Select(CharToPlayer).ToArray()).ToArray();
38
35
  }
39
36
 
40
37
  private int Cols => board[0].Length;
41
38
  private int Rows => board.Length;
42
39
 
43
- private bool IsValidCoordinate(Tuple<int, int> coordinate) =>
40
+ private bool IsValidCoordinate(ValueTuple<int, int> coordinate) =>
44
41
  coordinate.Item2 >= 0 && coordinate.Item2 < Rows &&
45
42
  coordinate.Item1 >= 0 && coordinate.Item1 < Cols;
46
43
 
47
- private GoPlayer GetPlayer(Tuple<int, int> coordinate) => board[coordinate.Item2][coordinate.Item1];
44
+ private Owner GetPlayer(ValueTuple<int, int> coordinate) => board[coordinate.Item2][coordinate.Item1];
48
45
 
49
- private bool IsEmpty(Tuple<int, int> coordinate) => GetPlayer(coordinate) == GoPlayer.None;
50
- private bool IsTaken(Tuple<int, int> coordinate) => !IsEmpty(coordinate);
46
+ private bool IsEmpty(ValueTuple<int, int> coordinate) => GetPlayer(coordinate) == Owner.None;
47
+ private bool IsTaken(ValueTuple<int, int> coordinate) => !IsEmpty(coordinate);
51
48
 
52
- private IEnumerable<Tuple<int, int>> EmptyCoordinates()
49
+ private IEnumerable<ValueTuple<int, int>> EmptyCoordinates()
53
50
  {
54
51
  return Enumerable.Range(0, Cols).SelectMany(col =>
55
- Enumerable.Range(0, Rows).Select(row => new Tuple<int, int>(col, row)))
52
+ Enumerable.Range(0, Rows).Select(row => new ValueTuple<int, int>(col, row)))
56
53
  .Where(IsEmpty);
57
54
  }
58
55
 
59
- private IEnumerable<Tuple<int, int>> NeighborCoordinates(Tuple<int, int> coordinate)
56
+ private IEnumerable<ValueTuple<int, int>> NeighborCoordinates(ValueTuple<int, int> coordinate)
60
57
  {
61
58
  var row = coordinate.Item2;
62
59
  var col = coordinate.Item1;
63
60
 
64
61
  var coords = new[]
65
62
  {
66
- new Tuple<int, int>(col, row - 1),
67
- new Tuple<int, int>(col-1, row),
68
- new Tuple<int, int>(col+1, row),
69
- new Tuple<int, int>(col, row+1)
63
+ new ValueTuple<int, int>(col, row - 1),
64
+ new ValueTuple<int, int>(col-1, row),
65
+ new ValueTuple<int, int>(col+1, row),
66
+ new ValueTuple<int, int>(col, row+1)
70
67
  };
71
68
 
72
69
  return coords.Where(IsValidCoordinate);
73
70
  }
74
71
 
75
- private IEnumerable<Tuple<int, int>> TakenNeighborCoordinates(Tuple<int, int> coordinate) =>
72
+ private IEnumerable<ValueTuple<int, int>> TakenNeighborCoordinates(ValueTuple<int, int> coordinate) =>
76
73
  NeighborCoordinates(coordinate).Where(IsTaken);
77
74
 
78
- private IEnumerable<Tuple<int, int>> EmptyNeighborCoordinates(Tuple<int, int> coordinate) =>
75
+ private IEnumerable<ValueTuple<int, int>> EmptyNeighborCoordinates(ValueTuple<int, int> coordinate) =>
79
76
  NeighborCoordinates(coordinate).Where(IsEmpty);
80
77
 
81
- private GoPlayer TerritoryOwner(HashSet<Tuple<int, int>> coords)
78
+ private Owner TerritoryOwner(IEnumerable<ValueTuple<int, int>> coords)
82
79
  {
83
80
  var neighborColors = coords.SelectMany(TakenNeighborCoordinates).Select(GetPlayer);
84
81
  var uniqueNeighborColors = ToSet(neighborColors);
@@ -86,15 +83,15 @@ private GoPlayer TerritoryOwner(HashSet<Tuple<int, int>> coords)
86
83
  if (uniqueNeighborColors.Count == 1)
87
84
  return uniqueNeighborColors.First();
88
85
 
89
- return GoPlayer.None;
86
+ return Owner.None;
90
87
  }
91
88
 
92
- private HashSet<Tuple<int, int>> TerritoryHelper(HashSet<Tuple<int, int>> remainder, HashSet<Tuple<int, int>> acc)
89
+ private HashSet<ValueTuple<int, int>> TerritoryHelper(HashSet<ValueTuple<int, int>> remainder, HashSet<ValueTuple<int, int>> acc)
93
90
  {
94
91
  if (!remainder.Any())
95
92
  return acc;
96
93
 
97
- var emptyNeighbors = new HashSet<Tuple<int, int>>(remainder.SelectMany(EmptyNeighborCoordinates));
94
+ var emptyNeighbors = new HashSet<ValueTuple<int, int>>(remainder.SelectMany(EmptyNeighborCoordinates));
98
95
  emptyNeighbors.ExceptWith(acc);
99
96
 
100
97
  var newAcc = ToSet(acc);
@@ -102,44 +99,54 @@ private GoPlayer TerritoryOwner(HashSet<Tuple<int, int>> coords)
102
99
  return TerritoryHelper(emptyNeighbors, newAcc);
103
100
  }
104
101
 
105
- private HashSet<Tuple<int, int>> Territory(Tuple<int, int> coordinate) =>
102
+ private HashSet<ValueTuple<int, int>> TerritoryHelper(ValueTuple<int, int> coordinate) =>
106
103
  IsValidCoordinate(coordinate) && IsEmpty(coordinate)
107
104
  ? TerritoryHelper(ToSingletonSet(coordinate), ToSingletonSet(coordinate))
108
- : new HashSet<Tuple<int, int>>();
105
+ : new HashSet<ValueTuple<int, int>>();
109
106
 
110
- public Tuple<GoPlayer, IEnumerable<Tuple<int, int>>> TerritoryFor(Tuple<int, int> coord)
107
+ public ValueTuple<Owner, IEnumerable<ValueTuple<int, int>>> Territory(ValueTuple<int, int> coord)
111
108
  {
112
- var coords = Territory(coord);
109
+ if (coord.Item1 < 0 || coord.Item1 >= Rows || coord.Item2 < 0 || coord.Item2 >= Cols)
110
+ {
111
+ throw new ArgumentException();
112
+ }
113
+
114
+ var coords = TerritoryHelper(coord);
113
115
  if (!coords.Any())
114
- return null;
116
+ return (Owner.None, Enumerable.Empty<ValueTuple<int, int>>());
115
117
 
116
118
  var owner = TerritoryOwner(coords);
117
- return Tuple.Create(owner, coords.AsEnumerable());
119
+ return (owner, coords.OrderBy(x => x.Item1).ThenBy(x => x.Item2).ToArray());
118
120
  }
119
121
 
120
- private Dictionary<GoPlayer, IEnumerable<Tuple<int, int>>> TerritoriesHelper(HashSet<Tuple<int, int>> remainder, Dictionary<GoPlayer, IEnumerable<Tuple<int, int>>> acc)
122
+ private Dictionary<Owner, ValueTuple<int, int>[]> TerritoriesHelper(HashSet<ValueTuple<int, int>> remainder, Dictionary<Owner, ValueTuple<int, int>[]> acc)
121
123
  {
122
124
  if (!remainder.Any())
123
125
  return acc;
124
126
 
125
127
  var coord = remainder.First();
126
- var coords = Territory(coord);
128
+ var coords = TerritoryHelper(coord);
127
129
  var owner = TerritoryOwner(coords);
128
130
 
129
131
  var newRemainder = ToSet(remainder);
130
132
  newRemainder.ExceptWith(coords);
131
133
 
132
- var newAcc = new Dictionary<GoPlayer, IEnumerable<Tuple<int, int>>>(acc)
133
- {
134
- [owner] = coords
135
- };
136
- return TerritoriesHelper(newRemainder, newAcc);
134
+ acc[owner] = acc[owner].Concat(coords).ToArray();
135
+ return TerritoriesHelper(newRemainder, acc);
137
136
  }
138
137
 
139
- public Dictionary<GoPlayer, IEnumerable<Tuple<int, int>>> Territories()
138
+ public Dictionary<Owner, ValueTuple<int, int>[]> Territories()
140
139
  {
141
140
  var emptyCoords = EmptyCoordinates();
142
- return TerritoriesHelper(ToSet(emptyCoords), new Dictionary<GoPlayer, IEnumerable<Tuple<int, int>>>());
141
+
142
+ var territories = new Dictionary<Owner, ValueTuple<int, int>[]>
143
+ {
144
+ [Owner.Black] = new ValueTuple<int, int>[0],
145
+ [Owner.White] = new ValueTuple<int, int>[0],
146
+ [Owner.None] = new ValueTuple<int, int>[0]
147
+ };
148
+
149
+ return TerritoriesHelper(ToSet(emptyCoords), territories);
143
150
  }
144
151
 
145
152
  private static HashSet<T> ToSet<T>(IEnumerable<T> value) => new HashSet<T>(value);
@@ -1,7 +1,7 @@
1
1
  using System;
2
2
  using System.Collections.Generic;
3
3
 
4
- public enum GoPlayer
4
+ public enum Owner
5
5
  {
6
6
  None,
7
7
  Black,
@@ -15,12 +15,12 @@ public GoCounting(string input)
15
15
  throw new NotImplementedException("You need to implement this function.");
16
16
  }
17
17
 
18
- public Tuple<GoPlayer, IEnumerable<Tuple<int, int>>> TerritoryFor(Tuple<int, int> coord)
18
+ public Tuple<Owner, IEnumerable<ValueTuple<int, int>>> TerritoryFor(ValueTuple<int, int> coord)
19
19
  {
20
20
  throw new NotImplementedException("You need to implement this function.");
21
21
  }
22
22
 
23
- public Dictionary<GoPlayer, IEnumerable<Tuple<int, int>>> Territories()
23
+ public Dictionary<Owner, IEnumerable<ValueTuple<int, int>>> Territories()
24
24
  {
25
25
  throw new NotImplementedException("You need to implement this function.");
26
26
  }
@@ -1,139 +1,188 @@
1
- using Xunit;
1
+ // This file was auto-generated based on version 1.0.0 of the canonical data.
2
+
3
+ using Xunit;
2
4
  using System;
3
5
  using System.Collections.Generic;
4
- using System.Linq;
5
6
 
6
7
  public class GoCountingTest
7
8
  {
8
- private static readonly string boardFiveByFive =
9
- string.Join("\n", new[]
10
- {
11
- " B ",
12
- " B B ",
13
- "B W B",
14
- " W W ",
15
- " W "
16
- });
17
-
18
- private static readonly string board9x9 =
19
- string.Join("\n", new[]
20
- {
21
- " B B ",
22
- "B B B",
23
- "WBBBWBBBW",
24
- "W W W W W",
25
- " ",
26
- " W W W W ",
27
- "B B B B",
28
- " W BBB W ",
29
- " B B "
30
- });
31
-
32
9
  [Fact]
33
- public void FiveByFiveTerritoryForBlack()
10
+ public void Black_corner_territory_on_5x5_board()
34
11
  {
35
- var board = new GoCounting(boardFiveByFive);
36
- var result = board.TerritoryFor(new Tuple<int, int>(0, 1));
37
- var expected = new HashSet<Tuple<int, int>> { new Tuple<int, int>(0, 0), new Tuple<int, int>(0, 1), new Tuple<int, int>(1, 0) };
38
- Assert.Equal(GoPlayer.Black, result.Item1);
39
- Assert.True(expected.SetEquals(result.Item2));
12
+ var coordinate = (0, 1);
13
+ var board =
14
+ " B \n" +
15
+ " B B \n" +
16
+ "B W B\n" +
17
+ " W W \n" +
18
+ " W ";
19
+ var sut = new GoCounting(board);
20
+ var actual = sut.Territory(coordinate);
21
+ var expected = (Owner.Black, new[] { (0, 0), (0, 1), (1, 0) });
22
+ Assert.Equal(expected.Item1, actual.Item1);
23
+ Assert.Equal(expected.Item2, actual.Item2);
40
24
  }
41
25
 
42
26
  [Fact(Skip = "Remove to run test")]
43
- public void FiveByFiveTerritoryForWhite()
27
+ public void White_center_territory_on_5x5_board()
44
28
  {
45
- var board = new GoCounting(boardFiveByFive);
46
- var result = board.TerritoryFor(new Tuple<int, int>(2, 3));
47
- var expected = new HashSet<Tuple<int, int>> { new Tuple<int, int>(2, 3) };
48
- Assert.Equal(GoPlayer.White, result.Item1);
49
- Assert.True(expected.SetEquals(result.Item2));
29
+ var coordinate = (2, 3);
30
+ var board =
31
+ " B \n" +
32
+ " B B \n" +
33
+ "B W B\n" +
34
+ " W W \n" +
35
+ " W ";
36
+ var sut = new GoCounting(board);
37
+ var actual = sut.Territory(coordinate);
38
+ var expected = (Owner.White, new[] { (2, 3) });
39
+ Assert.Equal(expected.Item1, actual.Item1);
40
+ Assert.Equal(expected.Item2, actual.Item2);
50
41
  }
51
42
 
52
43
  [Fact(Skip = "Remove to run test")]
53
- public void FiveByFiveOpenTerritory()
44
+ public void Open_corner_territory_on_5x5_board()
54
45
  {
55
- var board = new GoCounting(boardFiveByFive);
56
- var result = board.TerritoryFor(new Tuple<int, int>(1, 4));
57
- var expected = new HashSet<Tuple<int, int>> { new Tuple<int, int>(0, 3), new Tuple<int, int>(0, 4), new Tuple<int, int>(1, 4) };
58
- Assert.Equal(GoPlayer.None, result.Item1);
59
- Assert.True(expected.SetEquals(result.Item2));
46
+ var coordinate = (1, 4);
47
+ var board =
48
+ " B \n" +
49
+ " B B \n" +
50
+ "B W B\n" +
51
+ " W W \n" +
52
+ " W ";
53
+ var sut = new GoCounting(board);
54
+ var actual = sut.Territory(coordinate);
55
+ var expected = (Owner.None, new[] { (0, 3), (0, 4), (1, 4) });
56
+ Assert.Equal(expected.Item1, actual.Item1);
57
+ Assert.Equal(expected.Item2, actual.Item2);
60
58
  }
61
59
 
62
60
  [Fact(Skip = "Remove to run test")]
63
- public void FiveByFiveNonTerritoryStone()
61
+ public void A_stone_and_not_a_territory_on_5x5_board()
64
62
  {
65
- var board = new GoCounting(boardFiveByFive);
66
- Assert.Null(board.TerritoryFor(new Tuple<int, int>(1, 1)));
63
+ var coordinate = (1, 1);
64
+ var board =
65
+ " B \n" +
66
+ " B B \n" +
67
+ "B W B\n" +
68
+ " W W \n" +
69
+ " W ";
70
+ var sut = new GoCounting(board);
71
+ var actual = sut.Territory(coordinate);
72
+ var expected = (Owner.None, new ValueTuple<int,int>[0]);
73
+ Assert.Equal(expected.Item1, actual.Item1);
74
+ Assert.Equal(expected.Item2, actual.Item2);
67
75
  }
68
76
 
69
77
  [Fact(Skip = "Remove to run test")]
70
- public void FiveByFiveNonTerritoryDueToTooLowCoordinate()
78
+ public void Invalid_because_x_is_too_low_for_5x5_board()
71
79
  {
72
- var board = new GoCounting(boardFiveByFive);
73
- Assert.Null(board.TerritoryFor(new Tuple<int, int>(-1, 1)));
80
+ var coordinate = (-1, 1);
81
+ var board =
82
+ " B \n" +
83
+ " B B \n" +
84
+ "B W B\n" +
85
+ " W W \n" +
86
+ " W ";
87
+ var sut = new GoCounting(board);
88
+ Assert.Throws<ArgumentException>(() => sut.Territory(coordinate));
74
89
  }
75
90
 
76
91
  [Fact(Skip = "Remove to run test")]
77
- public void FiveByFiveNonTerritoryDueToTooHighCoordinate()
92
+ public void Invalid_because_x_is_too_high_for_5x5_board()
78
93
  {
79
- var board = new GoCounting(boardFiveByFive);
80
- Assert.Null(board.TerritoryFor(new Tuple<int, int>(1, 5)));
94
+ var coordinate = (5, 1);
95
+ var board =
96
+ " B \n" +
97
+ " B B \n" +
98
+ "B W B\n" +
99
+ " W W \n" +
100
+ " W ";
101
+ var sut = new GoCounting(board);
102
+ Assert.Throws<ArgumentException>(() => sut.Territory(coordinate));
81
103
  }
82
104
 
83
105
  [Fact(Skip = "Remove to run test")]
84
- public void MinimalBoardWithNoTerritories()
106
+ public void Invalid_because_y_is_too_low_for_5x5_board()
85
107
  {
86
- var input = "B";
87
- var board = new GoCounting(input);
88
-
89
- var expected = new Dictionary<GoPlayer, IEnumerable<Tuple<int, int>>>();
90
-
91
- Assert.Equal(expected, board.Territories());
108
+ var coordinate = (1, -1);
109
+ var board =
110
+ " B \n" +
111
+ " B B \n" +
112
+ "B W B\n" +
113
+ " W W \n" +
114
+ " W ";
115
+ var sut = new GoCounting(board);
116
+ Assert.Throws<ArgumentException>(() => sut.Territory(coordinate));
92
117
  }
93
118
 
94
119
  [Fact(Skip = "Remove to run test")]
95
- public void OneTerritoryCoveringTheWholeBoard()
120
+ public void Invalid_because_y_is_too_high_for_5x5_board()
96
121
  {
97
- var input = " ";
98
- var board = new GoCounting(input);
99
- var actual = board.Territories();
122
+ var coordinate = (1, 5);
123
+ var board =
124
+ " B \n" +
125
+ " B B \n" +
126
+ "B W B\n" +
127
+ " W W \n" +
128
+ " W ";
129
+ var sut = new GoCounting(board);
130
+ Assert.Throws<ArgumentException>(() => sut.Territory(coordinate));
131
+ }
100
132
 
101
- var expected = new Dictionary<GoPlayer, IEnumerable<Tuple<int, int>>>
133
+ [Fact(Skip = "Remove to run test")]
134
+ public void One_territory_is_the_whole_board()
135
+ {
136
+ var board = " ";
137
+ var sut = new GoCounting(board);
138
+ var actual = sut.Territories();
139
+ var expected = new Dictionary<Owner, ValueTuple<int,int>[]>
102
140
  {
103
- [GoPlayer.None] = new[] { new Tuple<int, int>(0, 0) }
141
+ [Owner.Black] = new ValueTuple<int,int>[0],
142
+ [Owner.White] = new ValueTuple<int,int>[0],
143
+ [Owner.None] = new[] { (0, 0) }
104
144
  };
105
-
106
145
  Assert.Equal(expected.Keys, actual.Keys);
107
- Assert.Equal(expected[GoPlayer.None], actual[GoPlayer.None]);
146
+ Assert.Equal(expected[Owner.Black], actual[Owner.Black]);
147
+ Assert.Equal(expected[Owner.White], actual[Owner.White]);
148
+ Assert.Equal(expected[Owner.None], actual[Owner.None]);
108
149
  }
109
150
 
110
151
  [Fact(Skip = "Remove to run test")]
111
- public void TwoTerritoriesOnRectangularBoard()
152
+ public void Two_territory_rectangular_board()
112
153
  {
113
- var input = string.Join("\n", new[] { " BW ", " BW " });
114
- var board = new GoCounting(input);
115
- var actual = board.Territories();
116
-
117
- var expected = new Dictionary<GoPlayer, IEnumerable<Tuple<int, int>>>
154
+ var board =
155
+ " BW \n" +
156
+ " BW ";
157
+ var sut = new GoCounting(board);
158
+ var actual = sut.Territories();
159
+ var expected = new Dictionary<Owner, ValueTuple<int,int>[]>
118
160
  {
119
- [GoPlayer.Black] = new[] { new Tuple<int, int>(0, 0), new Tuple<int, int>(0, 1) },
120
- [GoPlayer.White] = new[] { new Tuple<int, int>(3, 0), new Tuple<int, int>(3, 1) }
161
+ [Owner.Black] = new[] { (0, 0), (0, 1) },
162
+ [Owner.White] = new[] { (3, 0), (3, 1) },
163
+ [Owner.None] = new ValueTuple<int,int>[0]
121
164
  };
122
-
123
165
  Assert.Equal(expected.Keys, actual.Keys);
124
- Assert.Equal(expected[GoPlayer.Black], actual[GoPlayer.Black]);
125
- Assert.Equal(expected[GoPlayer.White], actual[GoPlayer.White]);
166
+ Assert.Equal(expected[Owner.Black], actual[Owner.Black]);
167
+ Assert.Equal(expected[Owner.White], actual[Owner.White]);
168
+ Assert.Equal(expected[Owner.None], actual[Owner.None]);
126
169
  }
127
170
 
128
- private class EnumerableEqualityComparer<T> : IEqualityComparer<IEnumerable<T>>
171
+ [Fact(Skip = "Remove to run test")]
172
+ public void Two_region_rectangular_board()
129
173
  {
130
- public static readonly EnumerableEqualityComparer<T> Instance = new EnumerableEqualityComparer<T>();
131
-
132
- public bool Equals(IEnumerable<T> x, IEnumerable<T> y) => x.SequenceEqual(y);
133
-
134
- public int GetHashCode(IEnumerable<T> obj)
174
+ var board = " B ";
175
+ var sut = new GoCounting(board);
176
+ var actual = sut.Territories();
177
+ var expected = new Dictionary<Owner, ValueTuple<int,int>[]>
135
178
  {
136
- throw new NotImplementedException();
137
- }
179
+ [Owner.Black] = new[] { (0, 0), (2, 0) },
180
+ [Owner.White] = new ValueTuple<int,int>[0],
181
+ [Owner.None] = new ValueTuple<int,int>[0]
182
+ };
183
+ Assert.Equal(expected.Keys, actual.Keys);
184
+ Assert.Equal(expected[Owner.Black], actual[Owner.Black]);
185
+ Assert.Equal(expected[Owner.White], actual[Owner.White]);
186
+ Assert.Equal(expected[Owner.None], actual[Owner.None]);
138
187
  }
139
- }
188
+ }