trackler 2.2.1.60 → 2.2.1.61

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/beer-song/canonical-data.json +366 -31
  4. data/problem-specifications/exercises/beer-song/description.md +1 -1
  5. data/problem-specifications/exercises/pascals-triangle/canonical-data.json +19 -1
  6. data/problem-specifications/exercises/proverb/canonical-data.json +91 -0
  7. data/problem-specifications/exercises/proverb/description.md +5 -3
  8. data/tracks/c/README.md +0 -10
  9. data/tracks/c/config/maintainers.json +45 -0
  10. data/tracks/c/config.json +1 -2
  11. data/tracks/c/docs/TESTS.md +43 -44
  12. data/tracks/d/docs/INSTALLATION.md +1 -1
  13. data/tracks/delphi/exercises/beer-song/README.md +1 -1
  14. data/tracks/delphi/exercises/beer-song/inputdata.txt +3 -1
  15. data/tracks/delphi/exercises/beer-song/uBeerSongExample.pas +14 -5
  16. data/tracks/delphi/exercises/beer-song/uBeerSongTests.pas +58 -42
  17. data/tracks/delphi/exercises/nucleotide-count/README.md +2 -2
  18. data/tracks/ecmascript/config.json +14 -0
  19. data/tracks/ecmascript/exercises/house/README.md +146 -0
  20. data/tracks/ecmascript/exercises/house/example.js +62 -0
  21. data/tracks/ecmascript/exercises/house/house.spec.js +292 -0
  22. data/tracks/ecmascript/exercises/house/package.json +71 -0
  23. data/tracks/go/exercises/allergies/example.go +3 -2
  24. data/tracks/go/exercises/custom-set/cases_test.go +7 -2
  25. data/tracks/go/exercises/isogram/.meta/gen.go +55 -0
  26. data/tracks/go/exercises/isogram/cases_test.go +57 -0
  27. data/tracks/go/exercises/isogram/isogram_test.go +4 -20
  28. data/tracks/java/config.json +7 -1
  29. data/tracks/java/exercises/luhn/src/test/java/LuhnValidatorTest.java +6 -1
  30. data/tracks/javascript/.eslintignore +0 -3
  31. data/tracks/javascript/exercises/acronym/example.js +2 -1
  32. data/tracks/javascript/exercises/diamond/diamond.spec.js +3 -3
  33. data/tracks/javascript/exercises/diamond/example.js +2 -2
  34. data/tracks/javascript/exercises/sum-of-multiples/sum-of-multiples.spec.js +9 -9
  35. data/tracks/python/config.json +33 -11
  36. data/tracks/python/exercises/dominoes/README.md +28 -0
  37. data/tracks/python/exercises/dominoes/dominoes.py +2 -0
  38. data/tracks/python/exercises/dominoes/dominoes_test.py +114 -0
  39. data/tracks/python/exercises/dominoes/example.py +30 -0
  40. data/tracks/python/exercises/grains/grains_test.py +5 -7
  41. data/tracks/python/exercises/phone-number/example.py +7 -13
  42. data/tracks/python/exercises/phone-number/phone_number_test.py +15 -15
  43. data/tracks/python/exercises/poker/poker_test.py +93 -52
  44. data/tracks/python/exercises/react/README.md +30 -0
  45. data/tracks/python/exercises/react/example.py +65 -0
  46. data/tracks/python/exercises/react/react.py +17 -0
  47. data/tracks/python/exercises/react/react_test.py +136 -0
  48. data/tracks/rust/exercises/pascals-triangle/Cargo.toml +1 -1
  49. data/tracks/rust/exercises/pascals-triangle/tests/pascals-triangle.rs +56 -0
  50. data/tracks/swift/Package.swift +1 -1
  51. data/tracks/swift/config.json +11 -0
  52. data/tracks/swift/exercises/atbash-cipher/Sources/AtbashExample.swift +1 -1
  53. data/tracks/swift/exercises/bracket-push/Sources/BracketPushExample.swift +1 -1
  54. data/tracks/swift/exercises/collatz-conjecture/Package.swift +5 -0
  55. data/tracks/swift/exercises/collatz-conjecture/README.md +41 -0
  56. data/tracks/swift/exercises/collatz-conjecture/Sources/CollatzConjecture.swift +1 -0
  57. data/tracks/swift/exercises/collatz-conjecture/Sources/CollatzConjectureExample.swift +27 -0
  58. data/tracks/swift/exercises/collatz-conjecture/Tests/CollatzConjectureTests/CollatzConjectureTests.swift +40 -0
  59. data/tracks/swift/exercises/collatz-conjecture/Tests/LinuxMain.swift +6 -0
  60. data/tracks/swift/exercises/dominoes/Sources/DominoesExample.swift +3 -3
  61. data/tracks/swift/exercises/grains/Tests/GrainsTests/GrainsTests.swift +3 -3
  62. data/tracks/swift/exercises/kindergarten-garden/Sources/KindergartenGardenExample.swift +2 -2
  63. data/tracks/swift/exercises/meetup/Sources/MeetupExample.swift +1 -1
  64. data/tracks/swift/exercises/nucleotide-count/Sources/NucleotideCountExample.swift +2 -2
  65. data/tracks/swift/exercises/poker/Sources/PokerExample.swift +137 -131
  66. data/tracks/swift/exercises/rna-transcription/Sources/RnaTranscriptionExample.swift +2 -2
  67. data/tracks/swift/exercises/rotational-cipher/Sources/RotationalCipherExample.swift +12 -12
  68. metadata +24 -2
@@ -4,12 +4,12 @@ describe('Diamond', function () {
4
4
  var diamond = new Diamond();
5
5
 
6
6
  it('test letter A', function () {
7
- result = 'A\n';
7
+ var result = 'A\n';
8
8
  expect(diamond.makeDiamond('A')).toEqual(result);
9
9
  });
10
10
 
11
11
  it('test letter C', function () {
12
- result = [' A ',
12
+ var result = [' A ',
13
13
  ' B B ',
14
14
  'C C',
15
15
  ' B B ',
@@ -18,7 +18,7 @@ describe('Diamond', function () {
18
18
  });
19
19
 
20
20
  it('test letter E', function () {
21
- result = [' A ',
21
+ var result = [' A ',
22
22
  ' B B ',
23
23
  ' C C ',
24
24
  ' D D ',
@@ -5,8 +5,8 @@ var Diamond = function () {
5
5
  for (var i = 0; i <= inputIndex; i++) {
6
6
  output += getLine(inputIndex, i);
7
7
  }
8
- for (var i = inputIndex - 1; i >= 0; i--) {
9
- output += getLine(inputIndex, i);
8
+ for (var j = inputIndex - 1; j >= 0; j--) {
9
+ output += getLine(inputIndex, j);
10
10
  }
11
11
  return output;
12
12
  };
@@ -2,38 +2,38 @@ var SumOfMultiples = require('./sum-of-multiples');
2
2
 
3
3
  describe('SumOfMultiples', function () {
4
4
  it('to 1', function () {
5
- expect(SumOfMultiples([3, 5]).to(1)).toBe(0);
5
+ expect(new SumOfMultiples([3, 5]).to(1)).toBe(0);
6
6
  });
7
7
 
8
8
  xit('to 3', function () {
9
- expect(SumOfMultiples([3, 5]).to(4)).toBe(3);
9
+ expect(new SumOfMultiples([3, 5]).to(4)).toBe(3);
10
10
  });
11
11
 
12
12
  xit('to 10', function () {
13
- expect(SumOfMultiples([3, 5]).to(10)).toBe(23);
13
+ expect(new SumOfMultiples([3, 5]).to(10)).toBe(23);
14
14
  });
15
15
 
16
16
  xit('to 100', function () {
17
- expect(SumOfMultiples([3, 5]).to(100)).toBe(2318);
17
+ expect(new SumOfMultiples([3, 5]).to(100)).toBe(2318);
18
18
  });
19
19
 
20
20
  xit('to 1000', function () {
21
- expect(SumOfMultiples([3, 5]).to(1000)).toBe(233168);
21
+ expect(new SumOfMultiples([3, 5]).to(1000)).toBe(233168);
22
22
  });
23
23
 
24
24
  xit('[7, 13, 17] to 20', function () {
25
- expect(SumOfMultiples([7, 13, 17]).to(20)).toBe(51);
25
+ expect(new SumOfMultiples([7, 13, 17]).to(20)).toBe(51);
26
26
  });
27
27
 
28
28
  xit('[4, 6] to 15', function () {
29
- expect(SumOfMultiples([4, 6]).to(15)).toBe(30);
29
+ expect(new SumOfMultiples([4, 6]).to(15)).toBe(30);
30
30
  });
31
31
 
32
32
  xit('[5, 6, 8] to 150', function () {
33
- expect(SumOfMultiples([5, 6, 8]).to(150)).toBe(4419);
33
+ expect(new SumOfMultiples([5, 6, 8]).to(150)).toBe(4419);
34
34
  });
35
35
 
36
36
  xit('[43, 47] to 10000', function () {
37
- expect(SumOfMultiples([43, 47]).to(10000)).toBe(2203160);
37
+ expect(new SumOfMultiples([43, 47]).to(10000)).toBe(2203160);
38
38
  });
39
39
  });
@@ -1116,17 +1116,39 @@
1116
1116
  ]
1117
1117
  },
1118
1118
  {
1119
- "uuid": "55c818d6-04a8-2480-de83-9f85fd0d2eafa71935f",
1120
- "slug": "pov",
1121
- "core": false,
1122
- "unlocked_by": null,
1123
- "difficulty": 9,
1124
- "topics": [
1125
- "graphs",
1126
- "recursion",
1127
- "searching",
1128
- "trees"
1129
- ]
1119
+ "uuid": "4354f631-0cf5-9980-75e7-86d1c3da1f0d3f5e619",
1120
+ "slug": "dominoes",
1121
+ "core": false,
1122
+ "unlocked_by": null,
1123
+ "difficulty": 7,
1124
+ "topics": [
1125
+ "tuples",
1126
+ "lists"
1127
+ ]
1128
+ },
1129
+ {
1130
+ "uuid": "55c818d6-04a8-2480-de83-9f85fd0d2eafa71935f",
1131
+ "slug": "pov",
1132
+ "core": false,
1133
+ "unlocked_by": null,
1134
+ "difficulty": 9,
1135
+ "topics": [
1136
+ "graphs",
1137
+ "recursion",
1138
+ "searching",
1139
+ "trees"
1140
+ ]
1141
+ },
1142
+ {
1143
+ "uuid": "21dacf48-0580-4d80-a6d2-257b07ad3cc47b02454",
1144
+ "slug": "react",
1145
+ "core": false,
1146
+ "unlocked_by": null,
1147
+ "difficulty": 8,
1148
+ "topics": [
1149
+ "events",
1150
+ "reactive_programming"
1151
+ ]
1130
1152
  },
1131
1153
  {
1132
1154
  "uuid": "e7351e8e-d3ff-4621-b818-cd55cf05bffd",
@@ -0,0 +1,28 @@
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
+ ## Submitting Exercises
18
+
19
+ Note that, when trying to submit an exercise, make sure the solution is in the `exercism/python/<exerciseName>` directory.
20
+
21
+ For example, if you're submitting `bob.py` for the Bob exercise, the submit command would be something like `exercism submit <path_to_exercism_dir>/python/bob/bob.py`.
22
+
23
+
24
+ For more detailed information about running tests, code style and linting,
25
+ please see the [help page](http://exercism.io/languages/python).
26
+
27
+ ## Submitting Incomplete Solutions
28
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,2 @@
1
+ def chain(dominoes):
2
+ pass
@@ -0,0 +1,114 @@
1
+ import unittest
2
+
3
+ from dominoes import chain
4
+
5
+
6
+ # Tests adapted from `problem-specifications//canonical-data.json` @ v2.0.0
7
+
8
+ class DominoesTest(unittest.TestCase):
9
+ def test_empty_input_empty_output(self):
10
+ input_dominoes = []
11
+ output_chain = chain(input_dominoes)
12
+ self.assert_correct_chain(input_dominoes, output_chain)
13
+
14
+ def test_singleton_input_singleton_output(self):
15
+ input_dominoes = [(1, 1)]
16
+ output_chain = chain(input_dominoes)
17
+ self.assert_correct_chain(input_dominoes, output_chain)
18
+
19
+ def test_singleton_cant_be_chained(self):
20
+ input_dominoes = [(1, 2)]
21
+ output_chain = chain(input_dominoes)
22
+ self.refute_correct_chain(input_dominoes, output_chain)
23
+
24
+ def test_three_elements(self):
25
+ input_dominoes = [(1, 2), (3, 1), (2, 3)]
26
+ output_chain = chain(input_dominoes)
27
+ self.assert_correct_chain(input_dominoes, output_chain)
28
+
29
+ def test_can_reverse_dominoes(self):
30
+ input_dominoes = [(1, 2), (1, 3), (2, 3)]
31
+ output_chain = chain(input_dominoes)
32
+ self.assert_correct_chain(input_dominoes, output_chain)
33
+
34
+ def test_cant_be_chained(self):
35
+ input_dominoes = [(1, 2), (4, 1), (2, 3)]
36
+ output_chain = chain(input_dominoes)
37
+ self.refute_correct_chain(input_dominoes, output_chain)
38
+
39
+ def test_disconnected_simple(self):
40
+ input_dominoes = [(1, 1), (2, 2)]
41
+ output_chain = chain(input_dominoes)
42
+ self.refute_correct_chain(input_dominoes, output_chain)
43
+
44
+ def test_disconnected_double_loop(self):
45
+ input_dominoes = [(1, 2), (2, 1), (3, 4), (4, 3)]
46
+ output_chain = chain(input_dominoes)
47
+ self.refute_correct_chain(input_dominoes, output_chain)
48
+
49
+ def test_disconnected_single_isolated(self):
50
+ input_dominoes = [(1, 2), (2, 3), (3, 1), (4, 4)]
51
+ output_chain = chain(input_dominoes)
52
+ self.refute_correct_chain(input_dominoes, output_chain)
53
+
54
+ def test_need_backtrack(self):
55
+ input_dominoes = [(1, 2), (2, 3), (3, 1), (2, 4), (2, 4)]
56
+ output_chain = chain(input_dominoes)
57
+ self.assert_correct_chain(input_dominoes, output_chain)
58
+
59
+ def test_separate_loops(self):
60
+ input_dominoes = [(1, 2), (2, 3), (3, 1), (1, 1), (2, 2), (3, 3)]
61
+ output_chain = chain(input_dominoes)
62
+ self.assert_correct_chain(input_dominoes, output_chain)
63
+
64
+ def test_nine_elements(self):
65
+ input_dominoes = [(1, 2), (5, 3), (3, 1), (1, 2), (2, 4), (1, 6),
66
+ (2, 3), (3, 4), (5, 6)]
67
+ output_chain = chain(input_dominoes)
68
+ self.assert_correct_chain(input_dominoes, output_chain)
69
+
70
+ # Utility methods
71
+
72
+ def normalize_dominoes(self, dominoes):
73
+ return list(sorted(tuple(sorted(domino)) for domino in dominoes))
74
+
75
+ def assert_same_dominoes(self, input_dominoes, output_chain):
76
+ msg = ('Dominoes used in the output must be the same '
77
+ 'as the ones given in the input')
78
+ input_normal = self.normalize_dominoes(input_dominoes)
79
+ output_normal = self.normalize_dominoes(output_chain)
80
+ self.assertEqual(input_normal, output_normal, msg)
81
+
82
+ def assert_consecutive_dominoes_match(self, output_chain):
83
+ for i in range(len(output_chain) - 1):
84
+ msg = ("In chain {}, right end of domino {} ({}) "
85
+ "and left end of domino {} ({}) must match")
86
+ msg = msg.format(output_chain,
87
+ i,
88
+ output_chain[i],
89
+ i + 1,
90
+ output_chain[i + 1])
91
+ self.assertEqual(output_chain[i][1], output_chain[i + 1][0], msg)
92
+
93
+ def assert_dominoes_at_ends_match(self, output_chain):
94
+ msg = ("In chain {}, left end of first domino ({}) and "
95
+ "right end of last domino ({}) must match")
96
+ msg = msg.format(output_chain, output_chain[0], output_chain[-1])
97
+ self.assertEqual(output_chain[0][0], output_chain[-1][1], msg)
98
+
99
+ def assert_correct_chain(self, input_dominoes, output_chain):
100
+ msg = 'There should be a chain for {}'.format(input_dominoes)
101
+ self.assertIsNotNone(output_chain, msg)
102
+ self.assert_same_dominoes(input_dominoes, output_chain)
103
+ if not any(output_chain):
104
+ return
105
+ self.assert_consecutive_dominoes_match(output_chain)
106
+ self.assert_dominoes_at_ends_match(output_chain)
107
+
108
+ def refute_correct_chain(self, input_dominoes, output_chain):
109
+ msg = 'There should be no valid chain for {}'.format(input_dominoes)
110
+ self.assertIsNone(output_chain, msg)
111
+
112
+
113
+ if __name__ == '__main__':
114
+ unittest.main()
@@ -0,0 +1,30 @@
1
+ from itertools import permutations
2
+ from functools import reduce
3
+
4
+
5
+ def swap(a, b):
6
+ return (b, a)
7
+
8
+
9
+ def build_chain(chain, domino):
10
+ if chain is not None:
11
+ last = chain[-1]
12
+ if len(chain) == 1 and last[0] == domino[0]:
13
+ return [swap(*last), domino]
14
+ elif len(chain) == 1 and last[0] == domino[1]:
15
+ return [swap(*last), swap(*domino)]
16
+ elif last[1] == domino[0]:
17
+ return chain + [domino]
18
+ elif last[1] == domino[1]:
19
+ return chain + [swap(*domino)]
20
+ return None
21
+
22
+
23
+ def chain(dominoes):
24
+ if not any(dominoes):
25
+ return []
26
+ for perm in permutations(dominoes):
27
+ chain = reduce(build_chain, perm[1:], [perm[0]])
28
+ if chain is not None and chain[0][0] == chain[-1][1]:
29
+ return chain
30
+ return None
@@ -6,34 +6,29 @@ from grains import (
6
6
  )
7
7
 
8
8
 
9
+ # Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.0
10
+
9
11
  class GrainsTest(unittest.TestCase):
10
12
  def test_square_1(self):
11
13
  self.assertEqual(on_square(1), 1)
12
- self.assertEqual(total_after(1), 1)
13
14
 
14
15
  def test_square_2(self):
15
16
  self.assertEqual(on_square(2), 2)
16
- self.assertEqual(total_after(2), 3)
17
17
 
18
18
  def test_square_3(self):
19
19
  self.assertEqual(on_square(3), 4)
20
- self.assertEqual(total_after(3), 7)
21
20
 
22
21
  def test_square_4(self):
23
22
  self.assertEqual(on_square(4), 8)
24
- self.assertEqual(total_after(4), 15)
25
23
 
26
24
  def test_square_16(self):
27
25
  self.assertEqual(on_square(16), 32768)
28
- self.assertEqual(total_after(16), 65535)
29
26
 
30
27
  def test_square_32(self):
31
28
  self.assertEqual(on_square(32), 2147483648)
32
- self.assertEqual(total_after(32), 4294967295)
33
29
 
34
30
  def test_square_64(self):
35
31
  self.assertEqual(on_square(64), 9223372036854775808)
36
- self.assertEqual(total_after(64), 18446744073709551615)
37
32
 
38
33
  def test_square_0_raises_exception(self):
39
34
  with self.assertRaises(ValueError):
@@ -53,6 +48,9 @@ class GrainsTest(unittest.TestCase):
53
48
  with self.assertRaises(ValueError):
54
49
  total_after(65)
55
50
 
51
+ def test_total(self):
52
+ self.assertEqual(total_after(64), 18446744073709551615)
53
+
56
54
 
57
55
  if __name__ == '__main__':
58
56
  unittest.main()
@@ -4,21 +4,15 @@ import re
4
4
  class Phone(object):
5
5
  def __init__(self, number):
6
6
  self.number = self._clean(number)
7
-
8
- def area_code(self):
9
- return self.number[:3]
10
-
11
- def exchange_code(self):
12
- return self.number[3:6]
13
-
14
- def subscriber_number(self):
15
- return self.number[-4:]
7
+ self.area_code = self.number[:3]
8
+ self.exchange_code = self.number[3:6]
9
+ self.subscriber_number = self.number[-4:]
16
10
 
17
11
  def pretty(self):
18
12
  return "(%s) %s-%s" % (
19
- self.area_code(),
20
- self.exchange_code(),
21
- self.subscriber_number()
13
+ self.area_code,
14
+ self.exchange_code,
15
+ self.subscriber_number
22
16
  )
23
17
 
24
18
  def _clean(self, number):
@@ -35,4 +29,4 @@ class Phone(object):
35
29
  if valid:
36
30
  return number[-10:]
37
31
  else:
38
- return '0' * 10
32
+ raise ValueError()
@@ -19,12 +19,12 @@ class PhoneTest(unittest.TestCase):
19
19
  self.assertEqual(number, "2234567890")
20
20
 
21
21
  def test_invalid_when_9_digits(self):
22
- number = Phone("123456789").number
23
- self.assertEqual(number, "0000000000")
22
+ with self.assertRaises(ValueError):
23
+ Phone("123456789")
24
24
 
25
25
  def test_invalid_when_11_digits_and_first_not_1(self):
26
- number = Phone("22234567890").number
27
- self.assertEqual(number, "0000000000")
26
+ with self.assertRaises(ValueError):
27
+ Phone("22234567890")
28
28
 
29
29
  def test_valid_when_11_digits_and_first_is_1(self):
30
30
  number = Phone("12234567890").number
@@ -35,29 +35,29 @@ class PhoneTest(unittest.TestCase):
35
35
  self.assertEqual(number, "2234567890")
36
36
 
37
37
  def test_invalid_when_more_than_11_digits(self):
38
- number = Phone("321234567890").number
39
- self.assertEqual(number, "0000000000")
38
+ with self.assertRaises(ValueError):
39
+ Phone("321234567890")
40
40
 
41
41
  def test_invalid_with_letters(self):
42
- number = Phone("123-abc-7890").number
43
- self.assertEqual(number, "0000000000")
42
+ with self.assertRaises(ValueError):
43
+ Phone("123-abc-7890")
44
44
 
45
45
  def test_invalid_with_punctuation(self):
46
- number = Phone("123-@:!-7890").number
47
- self.assertEqual(number, "0000000000")
46
+ with self.assertRaises(ValueError):
47
+ Phone("123-@:!-7890")
48
48
 
49
49
  def test_invalid_area_code(self):
50
- number = Phone("(123) 456-7890").number
51
- self.assertEqual(number, "0000000000")
50
+ with self.assertRaises(ValueError):
51
+ Phone("(123) 456-7890")
52
52
 
53
53
  def test_invalid_exchange_code(self):
54
- number = Phone("(223) 056-7890").number
55
- self.assertEqual(number, "0000000000")
54
+ with self.assertRaises(ValueError):
55
+ Phone("(223) 056-7890")
56
56
 
57
57
  # Track specific tests
58
58
  def test_area_code(self):
59
59
  number = Phone("2234567890")
60
- self.assertEqual(number.area_code(), "223")
60
+ self.assertEqual(number.area_code, "223")
61
61
 
62
62
  def test_pretty_print(self):
63
63
  number = Phone("2234567890")
@@ -3,81 +3,120 @@ import unittest
3
3
  from poker import poker
4
4
 
5
5
 
6
+ # Tests adapted from `problem-specifications//canonical-data.json` @ v1.0.0
7
+
6
8
  class PokerTest(unittest.TestCase):
7
- def test_one_hand(self):
9
+ def test_single_hand_wins(self):
8
10
  hand = '4S 5S 7H 8D JC'.split()
9
11
  self.assertEqual(poker([hand]), [hand])
10
12
 
11
- def test_nothing_vs_one_pair(self):
12
- nothing = '4S 5H 6S 8D JH'.split()
13
+ def highest_card_wins(self):
14
+ first = '4D 5S 6S 8D 3C'.split()
15
+ second = '2S 4C 7S 9H 10H'.split()
16
+ third = '3S 4S 5D 6H JH'.split()
17
+ self.assertEqual(poker([first, second, third]), [third])
18
+
19
+ def tie_has_multiple_winners(self):
20
+ first = '4D 5S 6S 8D 3C'.split()
21
+ second = '2S 4C 7S 9H 10H'.split()
22
+ third = '3S 4S 5D 6H JH'.split()
23
+ fourth = '3H 4H 5C 6C JD'.split()
24
+ self.assertEqual(
25
+ poker([first, second, third, fourth]),
26
+ [third, fourth])
27
+
28
+ def tie_compares_multiple(self):
29
+ higher = '3S 5H 6S 8D 7H'.split()
30
+ lower = '2S 5D 6D 8C 7S'.split()
31
+ self.assertEqual(poker([higher, lower]), [higher])
32
+
33
+ def pair_beats_high_card(self):
34
+ nothing = '4S 5H 6C 8D KH'.split()
13
35
  pairOf4 = '2S 4H 6S 4D JH'.split()
14
36
  self.assertEqual(poker([nothing, pairOf4]), [pairOf4])
15
37
 
16
- def test_two_pair(self):
38
+ def highest_pair_wins(self):
17
39
  pairOf2 = '4S 2H 6S 2D JH'.split()
18
- pairOf4 = '2S 4H 6S 4D JH'.split()
40
+ pairOf4 = '2S 4H 6C 4D JD'.split()
19
41
  self.assertEqual(poker([pairOf2, pairOf4]), [pairOf4])
20
42
 
21
- def test_one_pair_vs_double_pair(self):
43
+ def two_pairs_beats_one_pair(self):
22
44
  pairOf8 = '2S 8H 6S 8D JH'.split()
23
- doublePair = '4S 5H 4S 8D 5H'.split()
45
+ doublePair = '4S 5H 4C 8C 5C'.split()
24
46
  self.assertEqual(poker([pairOf8, doublePair]), [doublePair])
25
47
 
26
48
  def test_two_double_pair(self):
27
- doublePair2and8 = '2S 8H 2S 8D JH'.split()
28
- doublePair4and5 = '4S 5H 4S 8D 5H'.split()
49
+ doublePair2and8 = '2S 8H 2D 8D 3H'.split()
50
+ doublePair4and5 = '4S 5H 4C 8S 5D'.split()
29
51
  self.assertEqual(
30
52
  poker([doublePair2and8, doublePair4and5]), [doublePair2and8])
31
53
 
32
- def test_two_double_pair_lower(self):
33
- doublePair2and8 = '2S 8H 2S 8C JH'.split()
34
- doublePair3and8 = '4S 3H 8S 8D 3H'.split()
54
+ def test_two_double_pair_higher_tie(self):
55
+ doublePair2andQ = '2S QS 2C QD JH'.split()
56
+ doublePairJandQ = 'JD QH JS 8D QC'.split()
35
57
  self.assertEqual(
36
- poker([doublePair2and8, doublePair3and8]), [doublePair3and8])
58
+ poker([doublePair2andQ, doublePairJandQ]), [doublePairJandQ])
37
59
 
38
- def test_two_double_pair_and_high(self):
39
- doublePair2and8 = '2S 8H 2C 8C 3H'.split()
40
- doublePair2and8high = '2D 2H 8S 8D AH'.split()
60
+ def test_two_double_pair_tie_kicker(self):
61
+ doublePair2and8high = 'JD QH JS 8D QC'.split()
62
+ doublePair2and8 = 'JS QS JC 2D QD'.split()
41
63
  self.assertEqual(
42
64
  poker([doublePair2and8high, doublePair2and8]),
43
65
  [doublePair2and8high])
44
66
 
45
- def test_double_pair_vs_three(self):
46
- doublePair2and8 = '2S 8H 2S 8D JH'.split()
47
- threeOf4 = '4S 5H 4S 8D 4H'.split()
67
+ def three_beats_two_pair(self):
68
+ doublePair2and8 = '2S 8H 2H 8D JH'.split()
69
+ threeOf4 = '4S 5H 4C 8S 4H'.split()
48
70
  self.assertEqual(poker([doublePair2and8, threeOf4]), [threeOf4])
49
71
 
50
72
  def test_two_three(self):
51
- threeOf2 = '2S 2H 2S 8D JH'.split()
52
- threeOf1 = '4S AH AS 8D AH'.split()
73
+ threeOf2 = '2S 2H 2C 8D JH'.split()
74
+ threeOf1 = '4S AH AS 8C AD'.split()
53
75
  self.assertEqual(poker([threeOf2, threeOf1]), [threeOf1])
54
76
 
77
+ def test_two_three_multiple_decks(self):
78
+ threeOf1Low = '4S AH AS 7C AD'.split()
79
+ threeOf1High = '4S AH AS 8C AD'.split()
80
+ self.assertEqual(poker([threeOf1Low, threeOf1High]), [threeOf1High])
81
+
55
82
  def test_three_vs_straight(self):
56
- threeOf4 = '4S 5H 4S 8D 4H'.split()
57
- straight = '3S 4H 2S 6D 5H'.split()
83
+ threeOf4 = '4S 5H 4C 8D 4H'.split()
84
+ straight = '3S 4D 2S 6D 5C'.split()
85
+ self.assertEqual(poker([threeOf4, straight]), [straight])
86
+
87
+ def aces_can_end_straight(self):
88
+ threeOf4 = '4S 5H 4C 8D 4H'.split()
89
+ straight = '10D JH QS KD AC'.split()
90
+ self.assertEqual(poker([threeOf4, straight]), [straight])
91
+
92
+ def aces_can_start_straight(self):
93
+ threeOf4 = '4S 5H 4C 8D 4H'.split()
94
+ straight = '4D AH 3S 2D 5C'.split()
58
95
  self.assertEqual(poker([threeOf4, straight]), [straight])
59
96
 
60
97
  def test_two_straights(self):
61
- straightTo8 = '4S 6H 7S 8D 5H'.split()
98
+ straightTo8 = '4S 6C 7S 8D 5H'.split()
62
99
  straightTo9 = '5S 7H 8S 9D 6H'.split()
63
100
  self.assertEqual(poker([straightTo8, straightTo9]), [straightTo9])
64
- straightTo1 = 'AS QH KS TD JH'.split()
101
+
102
+ def test_two_straights_lowest(self):
103
+ straightTo6 = '2H 3C 4D 5D 6H'.split()
65
104
  straightTo5 = '4S AH 3S 2D 5H'.split()
66
- self.assertEqual(poker([straightTo1, straightTo5]), [straightTo1])
105
+ self.assertEqual(poker([straightTo6, straightTo5]), [straightTo6])
67
106
 
68
107
  def test_straight_vs_flush(self):
69
- straightTo8 = '4S 6H 7S 8D 5H'.split()
108
+ straightTo8 = '4C 6H 7D 8D 5H'.split()
70
109
  flushTo7 = '2S 4S 5S 6S 7S'.split()
71
110
  self.assertEqual(poker([straightTo8, flushTo7]), [flushTo7])
72
111
 
73
112
  def test_two_flushes(self):
74
- flushTo8 = '3H 6H 7H 8H 5H'.split()
113
+ flushTo9 = '4H 7H 8H 9H 6H'.split()
75
114
  flushTo7 = '2S 4S 5S 6S 7S'.split()
76
- self.assertEqual(poker([flushTo8, flushTo7]), [flushTo8])
115
+ self.assertEqual(poker([flushTo9, flushTo7]), [flushTo9])
77
116
 
78
117
  def test_flush_vs_full(self):
79
118
  flushTo8 = '3H 6H 7H 8H 5H'.split()
80
- full = '4S 5H 4S 5D 4H'.split()
119
+ full = '4S 5H 4C 5D 4H'.split()
81
120
  self.assertEqual(poker([full, flushTo8]), [full])
82
121
 
83
122
  def test_two_fulls(self):
@@ -85,21 +124,31 @@ class PokerTest(unittest.TestCase):
85
124
  fullOf5by8 = '5H 5S 5D 8S 8D'.split()
86
125
  self.assertEqual(poker([fullOf4by9, fullOf5by8]), [fullOf5by8])
87
126
 
88
- def test_full_vs_square(self):
89
- full = '4S 5H 4S 5D 4H'.split()
90
- squareOf3 = '3S 3H 2S 3D 3H'.split()
91
- self.assertEqual(poker([full, squareOf3]), [squareOf3])
92
-
93
- def test_two_square(self):
94
- squareOf2 = '2S 2H 2S 8D 2H'.split()
95
- squareOf5 = '4S 5H 5S 5D 5H'.split()
96
- self.assertEqual(poker([squareOf2, squareOf5]), [squareOf5])
97
-
98
- def test_square_vs_straight_flush(self):
99
- squareOf5 = '4S 5H 5S 5D 5H'.split()
100
- straightFlushTo9 = '5S 7S 8S 9S 6S'.split()
127
+ def test_two_fulls_same_triplet(self):
128
+ fullOf5by9 = '5H 5S 5D 9S 9D'.split()
129
+ fullOf5by8 = '5H 5S 5D 8S 8D'.split()
130
+ self.assertEqual(poker([fullOf5by9, fullOf5by8]), [fullOf5by9])
131
+
132
+ def test_full_vs_four(self):
133
+ full = '4S 5H 4D 5D 4H'.split()
134
+ fourOf3 = '3S 3H 2S 3D 3C'.split()
135
+ self.assertEqual(poker([full, fourOf3]), [fourOf3])
136
+
137
+ def test_two_fours(self):
138
+ fourOf2 = '2S 2H 2C 8D 2D'.split()
139
+ fourOf5 = '4S 5H 5S 5D 5C'.split()
140
+ self.assertEqual(poker([fourOf2, fourOf5]), [fourOf5])
141
+
142
+ def test_two_fours_kicker(self):
143
+ fourOf3low = '3S 3H 2S 3D 3C'.split()
144
+ fourOf3high = '3S 3H 4S 3D 3C'.split()
145
+ self.assertEqual(poker([fourOf3low, fourOf3high]), [fourOf3high])
146
+
147
+ def test_four_vs_straight_flush(self):
148
+ fourOf5 = '4S 5H 5S 5D 5C'.split()
149
+ straightFlushTo9 = '7S 8S 9S 6S 5S'.split()
101
150
  self.assertEqual(
102
- poker([squareOf5, straightFlushTo9]), [straightFlushTo9])
151
+ poker([fourOf5, straightFlushTo9]), [straightFlushTo9])
103
152
 
104
153
  def test_two_straight_flushes(self):
105
154
  straightFlushTo8 = '4H 6H 7H 8H 5H'.split()
@@ -107,14 +156,6 @@ class PokerTest(unittest.TestCase):
107
156
  self.assertEqual(
108
157
  poker([straightFlushTo8, straightFlushTo9]), [straightFlushTo9])
109
158
 
110
- def test_three_hand_with_tie(self):
111
- spadeStraightTo9 = '9S 8S 7S 6S 5S'.split()
112
- diamondStraightTo9 = '9D 8D 7D 6D 5D'.split()
113
- threeOf4 = '4D 4S 4H QS KS'.split()
114
- self.assertEqual(
115
- poker([spadeStraightTo9, diamondStraightTo9, threeOf4]),
116
- [spadeStraightTo9, diamondStraightTo9])
117
-
118
159
 
119
160
  if __name__ == '__main__':
120
161
  unittest.main()