trackler 2.2.1.52 → 2.2.1.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/leap/canonical-data.json +2 -2
  4. data/tracks/cfml/tasks/FormatConfig.cfc +6 -4
  5. data/tracks/cfml/tasks/GenerateReadme.cfc +197 -0
  6. data/tracks/cfml/tasks/ScaffoldExercise.cfc +6 -0
  7. data/tracks/csharp/config.json +1 -1
  8. data/tracks/delphi/exercises/leap/uLeapTests.pas +1 -1
  9. data/tracks/fsharp/exercises/clock/Clock.fs +1 -1
  10. data/tracks/fsharp/exercises/clock/ClockTest.fs +239 -61
  11. data/tracks/fsharp/exercises/clock/Example.fs +3 -3
  12. data/tracks/fsharp/exercises/dominoes/DominoesTest.fs +29 -26
  13. data/tracks/fsharp/exercises/largest-series-product/LargestSeriesProductTest.fs +30 -15
  14. data/tracks/fsharp/exercises/leap/LeapTest.fs +2 -2
  15. data/tracks/fsharp/exercises/rectangles/Example.fs +1 -1
  16. data/tracks/fsharp/exercises/rectangles/Rectangles.fs +1 -1
  17. data/tracks/fsharp/exercises/rectangles/RectanglesTest.fs +66 -43
  18. data/tracks/fsharp/generators/Generators.fs +85 -1
  19. data/tracks/java/scripts/canonical_data_check.sh +8 -0
  20. data/tracks/kotlin/.gitignore +1 -0
  21. data/tracks/kotlin/exercises/acronym/.meta/version +1 -0
  22. data/tracks/kotlin/exercises/acronym/src/test/kotlin/AcronymTest.kt +9 -10
  23. data/tracks/kotlin/exercises/all-your-base/.meta/version +1 -1
  24. data/tracks/kotlin/exercises/all-your-base/src/test/kotlin/BaseConverterTest.kt +20 -20
  25. data/tracks/kotlin/exercises/allergies/.meta/version +1 -0
  26. data/tracks/kotlin/exercises/allergies/src/test/kotlin/AllergiesTest.kt +19 -72
  27. data/tracks/kotlin/exercises/anagram/.meta/src/reference/kotlin/Anagram.kt +7 -4
  28. data/tracks/kotlin/exercises/anagram/.meta/version +1 -0
  29. data/tracks/kotlin/exercises/anagram/src/test/kotlin/AnagramTest.kt +76 -29
  30. data/tracks/kotlin/exercises/atbash-cipher/.meta/version +1 -0
  31. data/tracks/kotlin/exercises/atbash-cipher/src/test/kotlin/AtbashTest.kt +6 -3
  32. data/tracks/kotlin/exercises/beer-song/.meta/version +1 -0
  33. data/tracks/kotlin/exercises/beer-song/src/test/kotlin/BeerSongTest.kt +21 -46
  34. data/tracks/kotlin/exercises/binary-search/.meta/version +1 -0
  35. data/tracks/kotlin/exercises/binary-search/src/test/kotlin/BinarySearchTest.kt +30 -19
  36. data/tracks/kotlin/exercises/bob/.meta/src/reference/kotlin/Bob.kt +8 -7
  37. data/tracks/kotlin/exercises/bob/.meta/version +1 -0
  38. data/tracks/kotlin/exercises/bob/src/test/kotlin/BobTest.kt +57 -15
  39. data/tracks/kotlin/exercises/bracket-push/.meta/version +1 -0
  40. data/tracks/kotlin/exercises/bracket-push/src/test/kotlin/BracketPushTest.kt +3 -1
  41. data/tracks/kotlin/exercises/collatz-conjecture/.meta/version +1 -1
  42. data/tracks/kotlin/exercises/difference-of-squares/.meta/version +1 -0
  43. data/tracks/kotlin/exercises/difference-of-squares/src/test/kotlin/SquaresTest.kt +10 -23
  44. data/tracks/kotlin/exercises/etl/.meta/src/reference/kotlin/ETL.kt +7 -1
  45. data/tracks/kotlin/exercises/etl/.meta/version +1 -0
  46. data/tracks/kotlin/exercises/etl/src/test/kotlin/ETLTest.kt +10 -10
  47. data/tracks/kotlin/exercises/flatten-array/.meta/version +1 -0
  48. data/tracks/kotlin/exercises/flatten-array/src/test/kotlin/FlattenerTest.kt +8 -16
  49. data/tracks/kotlin/exercises/gigasecond/.meta/version +1 -0
  50. data/tracks/kotlin/exercises/gigasecond/src/test/kotlin/GigasecondTest.kt +1 -1
  51. data/tracks/kotlin/exercises/hamming/.meta/src/reference/kotlin/Hamming.kt +1 -1
  52. data/tracks/kotlin/exercises/hamming/.meta/version +1 -1
  53. data/tracks/kotlin/exercises/hamming/src/test/kotlin/HammingTest.kt +4 -4
  54. data/tracks/kotlin/exercises/hello-world/.meta/version +1 -0
  55. data/tracks/kotlin/exercises/hello-world/src/test/kotlin/HelloWorldTest.kt +1 -1
  56. data/tracks/kotlin/exercises/isogram/.meta/version +1 -0
  57. data/tracks/kotlin/exercises/isogram/src/test/kotlin/IsogramTest.kt +5 -8
  58. data/tracks/kotlin/exercises/largest-series-product/.meta/src/reference/kotlin/Series.kt +2 -3
  59. data/tracks/kotlin/exercises/largest-series-product/.meta/version +1 -0
  60. data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesTest.kt +97 -0
  61. data/tracks/kotlin/exercises/leap/.meta/version +1 -0
  62. data/tracks/kotlin/exercises/leap/src/test/kotlin/LeapTest.kt +8 -26
  63. data/tracks/kotlin/exercises/list-ops/.meta/version +1 -1
  64. data/tracks/kotlin/exercises/luhn/.meta/version +1 -0
  65. data/tracks/kotlin/exercises/luhn/src/test/kotlin/LuhnTest.kt +0 -3
  66. data/tracks/kotlin/exercises/nth-prime/.meta/version +1 -0
  67. data/tracks/kotlin/exercises/nth-prime/src/test/kotlin/PrimeTest.kt +0 -2
  68. data/tracks/kotlin/exercises/nucleotide-count/.meta/src/reference/kotlin/{DNA.kt → Dna.kt} +3 -8
  69. data/tracks/kotlin/exercises/nucleotide-count/.meta/version +1 -0
  70. data/tracks/kotlin/exercises/nucleotide-count/src/test/kotlin/DnaTest.kt +48 -0
  71. data/tracks/kotlin/exercises/pangram/.meta/src/reference/kotlin/{Pangrams.kt → Pangram.kt} +1 -1
  72. data/tracks/kotlin/exercises/pangram/.meta/version +1 -1
  73. data/tracks/kotlin/exercises/pangram/src/test/kotlin/PangramTest.kt +15 -9
  74. data/tracks/kotlin/exercises/pascals-triangle/.meta/version +1 -0
  75. data/tracks/kotlin/exercises/pascals-triangle/src/test/kotlin/PascalsTriangleTest.kt +32 -14
  76. data/tracks/kotlin/exercises/perfect-numbers/.meta/src/reference/kotlin/NaturalNumber.kt +1 -1
  77. data/tracks/kotlin/exercises/perfect-numbers/.meta/version +1 -0
  78. data/tracks/kotlin/exercises/perfect-numbers/src/test/kotlin/{PerfectNumbersTest.kt → NaturalNumberTest.kt} +25 -7
  79. data/tracks/kotlin/exercises/phone-number/.meta/src/reference/kotlin/PhoneNumber.kt +15 -7
  80. data/tracks/kotlin/exercises/phone-number/.meta/version +1 -0
  81. data/tracks/kotlin/exercises/phone-number/src/test/kotlin/PhoneNumberTest.kt +46 -29
  82. data/tracks/kotlin/exercises/pig-latin/.meta/src/reference/kotlin/PigLatin.kt +2 -2
  83. data/tracks/kotlin/exercises/pig-latin/.meta/version +1 -0
  84. data/tracks/kotlin/exercises/pig-latin/src/test/kotlin/PigLatinTest.kt +21 -10
  85. data/tracks/kotlin/exercises/raindrops/.meta/version +1 -0
  86. data/tracks/kotlin/exercises/raindrops/src/test/kotlin/RaindropsTest.kt +19 -26
  87. data/tracks/kotlin/exercises/react/.meta/version +1 -0
  88. data/tracks/kotlin/exercises/react/src/test/kotlin/ReactTest.kt +11 -4
  89. data/tracks/kotlin/exercises/robot-simulator/.meta/version +1 -1
  90. data/tracks/kotlin/exercises/roman-numerals/.meta/version +1 -0
  91. data/tracks/kotlin/exercises/roman-numerals/src/test/kotlin/RomanNumeralTest.kt +1 -2
  92. data/tracks/kotlin/exercises/rotational-cipher/.meta/version +1 -1
  93. data/tracks/kotlin/exercises/rotational-cipher/src/test/kotlin/RotationalCipherTest.kt +7 -7
  94. data/tracks/kotlin/exercises/scrabble-score/.meta/src/reference/kotlin/{Scrabble.kt → ScrabbleScore.kt} +1 -1
  95. data/tracks/kotlin/exercises/scrabble-score/.meta/version +1 -0
  96. data/tracks/kotlin/exercises/scrabble-score/src/test/kotlin/ScrabbleScoreTest.kt +9 -7
  97. data/tracks/kotlin/exercises/sieve/.meta/version +1 -0
  98. data/tracks/kotlin/exercises/sieve/src/test/kotlin/SieveTest.kt +8 -0
  99. data/tracks/kotlin/exercises/space-age/.meta/version +1 -0
  100. data/tracks/kotlin/exercises/space-age/src/test/kotlin/SpaceAgeTest.kt +1 -16
  101. data/tracks/kotlin/exercises/sum-of-multiples/.meta/version +1 -0
  102. data/tracks/kotlin/exercises/sum-of-multiples/src/test/kotlin/SumOfMultiplesTest.kt +7 -7
  103. data/tracks/kotlin/exercises/triangle/.meta/version +1 -0
  104. data/tracks/kotlin/exercises/two-fer/.meta/version +1 -0
  105. data/tracks/kotlin/exercises/two-fer/src/test/kotlin/TwoferTest.kt +0 -1
  106. data/tracks/kotlin/exercises/word-count/.meta/src/reference/kotlin/WordCount.kt +6 -2
  107. data/tracks/kotlin/exercises/word-count/.meta/version +1 -0
  108. data/tracks/kotlin/exercises/word-count/src/test/kotlin/WordCountTest.kt +31 -9
  109. data/tracks/kotlin/scripts/canonical_data_check.sh +8 -0
  110. data/tracks/perl6/exercises/leap/leap.t +2 -2
  111. data/tracks/php/config.json +16 -0
  112. data/tracks/php/exercises/crypto-square/crypto-square_test.php +50 -0
  113. data/tracks/php/exercises/crypto-square/example.php +32 -0
  114. data/tracks/php/exercises/meetup/README.md +21 -0
  115. data/tracks/php/exercises/meetup/example.php +19 -0
  116. data/tracks/php/exercises/meetup/meetup_test.php +577 -0
  117. data/tracks/python/README.md +7 -5
  118. data/tracks/python/config.json +36 -27
  119. data/tracks/python/docs/TESTS.md +36 -12
  120. data/tracks/python/exercises/complex-numbers/complex_numbers_test.py +1 -1
  121. data/tracks/python/exercises/diffie-hellman/.meta/hints.md +16 -0
  122. data/tracks/python/exercises/diffie-hellman/README.md +15 -2
  123. data/tracks/python/exercises/error-handling/README.md +23 -0
  124. data/tracks/python/exercises/error-handling/error_handling.py +14 -0
  125. data/tracks/python/exercises/error-handling/error_handling_test.py +66 -0
  126. data/tracks/python/exercises/error-handling/example.py +21 -0
  127. data/tracks/python/exercises/forth/forth_test.py +1 -1
  128. data/tracks/python/exercises/isogram/isogram_test.py +5 -3
  129. data/tracks/python/exercises/leap/leap_test.py +2 -2
  130. data/tracks/python/exercises/rotational-cipher/rotational_cipher_test.py +4 -4
  131. data/tracks/python/exercises/simple-cipher/.meta/hints.md +16 -0
  132. data/tracks/python/exercises/simple-cipher/README.md +17 -0
  133. data/tracks/python/exercises/sum-of-multiples/sum_of_multiples_test.py +4 -1
  134. data/tracks/python/exercises/twelve-days/example.py +3 -3
  135. data/tracks/python/exercises/twelve-days/twelve_days.py +2 -2
  136. metadata +53 -9
  137. data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesInvalidInputTest.kt +0 -30
  138. data/tracks/kotlin/exercises/largest-series-product/src/test/kotlin/SeriesValidInputTest.kt +0 -34
  139. data/tracks/kotlin/exercises/nucleotide-count/src/test/kotlin/NucleotideTest.kt +0 -87
@@ -6,15 +6,15 @@ type Clock = { hours: int; minutes: int }
6
6
 
7
7
  let modulo x y = (int)(((x % y) + y) % y)
8
8
 
9
- let mkClock hours minutes =
9
+ let create hours minutes =
10
10
  let totalMinutes = hours * 60 + minutes
11
11
  let normalizedHours = modulo ((double)totalMinutes / 60.0) 24.0
12
12
  let normalizedMinutes = modulo ((double)minutes) 60.0
13
13
 
14
14
  { hours = normalizedHours; minutes = normalizedMinutes }
15
15
 
16
- let add minutes clock = mkClock clock.hours (clock.minutes + minutes)
16
+ let add minutes clock = create clock.hours (clock.minutes + minutes)
17
17
 
18
- let subtract minutes clock = mkClock clock.hours (clock.minutes - minutes)
18
+ let subtract minutes clock = create clock.hours (clock.minutes - minutes)
19
19
 
20
20
  let display clock = sprintf "%02i:%02i" clock.hours clock.minutes
@@ -1,66 +1,69 @@
1
+ // This file was auto-generated based on version 2.0.0 of the canonical data.
2
+
1
3
  module DominoesTest
2
4
 
3
- open Xunit
4
5
  open FsUnit.Xunit
6
+ open Xunit
5
7
 
6
8
  open Dominoes
7
9
 
8
10
  [<Fact>]
9
11
  let ``Empty input = empty output`` () =
10
- let actual = []
11
- canChain actual |> should equal true
12
+ let input = []
13
+ canChain input |> should equal true
12
14
 
13
15
  [<Fact(Skip = "Remove to run test")>]
14
16
  let ``Singleton input = singleton output`` () =
15
- let actual = [(1, 1)]
16
- canChain actual |> should equal true
17
+ let input = [(1, 1)]
18
+ canChain input |> should equal true
17
19
 
18
20
  [<Fact(Skip = "Remove to run test")>]
19
21
  let ``Singleton that can't be chained`` () =
20
- let actual = [(1, 2)]
21
- canChain actual |> should equal false
22
+ let input = [(1, 2)]
23
+ canChain input |> should equal false
22
24
 
23
25
  [<Fact(Skip = "Remove to run test")>]
24
26
  let ``Three elements`` () =
25
- let actual = [(1, 2); (3, 1); (2, 3)]
26
- canChain actual |> should equal true
27
+ let input = [(1, 2); (3, 1); (2, 3)]
28
+ canChain input |> should equal true
27
29
 
28
30
  [<Fact(Skip = "Remove to run test")>]
29
31
  let ``Can reverse dominoes`` () =
30
- let actual = [(1, 2); (1, 3); (2, 3)]
31
- canChain actual |> should equal true
32
+ let input = [(1, 2); (1, 3); (2, 3)]
33
+ canChain input |> should equal true
32
34
 
33
35
  [<Fact(Skip = "Remove to run test")>]
34
36
  let ``Can't be chained`` () =
35
- let actual = [(1, 2); (4, 1); (2, 3)]
36
- canChain actual |> should equal false
37
+ let input = [(1, 2); (4, 1); (2, 3)]
38
+ canChain input |> should equal false
37
39
 
38
40
  [<Fact(Skip = "Remove to run test")>]
39
41
  let ``Disconnected - simple`` () =
40
- let actual = [(1, 1); (2, 2)]
41
- canChain actual |> should equal false
42
+ let input = [(1, 1); (2, 2)]
43
+ canChain input |> should equal false
42
44
 
43
45
  [<Fact(Skip = "Remove to run test")>]
44
46
  let ``Disconnected - double loop`` () =
45
- let actual = [(1, 2); (2, 1); (3, 4); (4, 3)]
46
- canChain actual |> should equal false
47
+ let input = [(1, 2); (2, 1); (3, 4); (4, 3)]
48
+ canChain input |> should equal false
47
49
 
48
50
  [<Fact(Skip = "Remove to run test")>]
49
51
  let ``Disconnected - single isolated`` () =
50
- let actual = [(1, 2); (2, 3); (3, 1); (4, 4)]
51
- canChain actual |> should equal false
52
+ let input = [(1, 2); (2, 3); (3, 1); (4, 4)]
53
+ canChain input |> should equal false
52
54
 
53
55
  [<Fact(Skip = "Remove to run test")>]
54
56
  let ``Need backtrack`` () =
55
- let actual = [(1, 2); (2, 3); (3, 1); (2, 4); (2, 4)]
56
- canChain actual |> should equal true
57
+ let input = [(1, 2); (2, 3); (3, 1); (2, 4); (2, 4)]
58
+ canChain input |> should equal true
57
59
 
58
60
  [<Fact(Skip = "Remove to run test")>]
59
61
  let ``Separate loops`` () =
60
- let actual = [(1, 2); (2, 3); (3, 1); (1, 1); (2, 2); (3, 3)]
61
- canChain actual |> should equal true
62
+ let input = [(1, 2); (2, 3); (3, 1); (1, 1); (2, 2); (3, 3)]
63
+ canChain input |> should equal true
62
64
 
63
65
  [<Fact(Skip = "Remove to run test")>]
64
- let ``Ten elements`` () =
65
- let actual = [(1, 2); (5, 3); (3, 1); (1, 2); (2, 4); (1, 6); (2, 3); (3, 4); (5, 6)]
66
- canChain actual |> should equal true
66
+ let ``Nine elements`` () =
67
+ let input = [(1, 2); (5, 3); (3, 1); (1, 2); (2, 4); (1, 6); (2, 3); (3, 4); (5, 6)]
68
+ canChain input |> should equal true
69
+
@@ -10,75 +10,90 @@ open LargestSeriesProduct
10
10
  [<Fact>]
11
11
  let ``Finds the largest product if span equals length`` () =
12
12
  let digits = "29"
13
- largestProduct digits 2 |> should equal (Some 18)
13
+ let span = 2
14
+ largestProduct digits span |> should equal (Some 18)
14
15
 
15
16
  [<Fact(Skip = "Remove to run test")>]
16
17
  let ``Can find the largest product of 2 with numbers in order`` () =
17
18
  let digits = "0123456789"
18
- largestProduct digits 2 |> should equal (Some 72)
19
+ let span = 2
20
+ largestProduct digits span |> should equal (Some 72)
19
21
 
20
22
  [<Fact(Skip = "Remove to run test")>]
21
23
  let ``Can find the largest product of 2`` () =
22
24
  let digits = "576802143"
23
- largestProduct digits 2 |> should equal (Some 48)
25
+ let span = 2
26
+ largestProduct digits span |> should equal (Some 48)
24
27
 
25
28
  [<Fact(Skip = "Remove to run test")>]
26
29
  let ``Can find the largest product of 3 with numbers in order`` () =
27
30
  let digits = "0123456789"
28
- largestProduct digits 3 |> should equal (Some 504)
31
+ let span = 3
32
+ largestProduct digits span |> should equal (Some 504)
29
33
 
30
34
  [<Fact(Skip = "Remove to run test")>]
31
35
  let ``Can find the largest product of 3`` () =
32
36
  let digits = "1027839564"
33
- largestProduct digits 3 |> should equal (Some 270)
37
+ let span = 3
38
+ largestProduct digits span |> should equal (Some 270)
34
39
 
35
40
  [<Fact(Skip = "Remove to run test")>]
36
41
  let ``Can find the largest product of 5 with numbers in order`` () =
37
42
  let digits = "0123456789"
38
- largestProduct digits 5 |> should equal (Some 15120)
43
+ let span = 5
44
+ largestProduct digits span |> should equal (Some 15120)
39
45
 
40
46
  [<Fact(Skip = "Remove to run test")>]
41
47
  let ``Can get the largest product of a big number`` () =
42
48
  let digits = "73167176531330624919225119674426574742355349194934"
43
- largestProduct digits 6 |> should equal (Some 23520)
49
+ let span = 6
50
+ largestProduct digits span |> should equal (Some 23520)
44
51
 
45
52
  [<Fact(Skip = "Remove to run test")>]
46
53
  let ``Reports zero if the only digits are zero`` () =
47
54
  let digits = "0000"
48
- largestProduct digits 2 |> should equal (Some 0)
55
+ let span = 2
56
+ largestProduct digits span |> should equal (Some 0)
49
57
 
50
58
  [<Fact(Skip = "Remove to run test")>]
51
59
  let ``Reports zero if all spans include zero`` () =
52
60
  let digits = "99099"
53
- largestProduct digits 3 |> should equal (Some 0)
61
+ let span = 3
62
+ largestProduct digits span |> should equal (Some 0)
54
63
 
55
64
  [<Fact(Skip = "Remove to run test")>]
56
65
  let ``Rejects span longer than string length`` () =
57
66
  let digits = "123"
58
- largestProduct digits 4 |> should equal None
67
+ let span = 4
68
+ largestProduct digits span |> should equal None
59
69
 
60
70
  [<Fact(Skip = "Remove to run test")>]
61
71
  let ``Reports 1 for empty string and empty product (0 span)`` () =
62
72
  let digits = ""
63
- largestProduct digits 0 |> should equal (Some 1)
73
+ let span = 0
74
+ largestProduct digits span |> should equal (Some 1)
64
75
 
65
76
  [<Fact(Skip = "Remove to run test")>]
66
77
  let ``Reports 1 for nonempty string and empty product (0 span)`` () =
67
78
  let digits = "123"
68
- largestProduct digits 0 |> should equal (Some 1)
79
+ let span = 0
80
+ largestProduct digits span |> should equal (Some 1)
69
81
 
70
82
  [<Fact(Skip = "Remove to run test")>]
71
83
  let ``Rejects empty string and nonzero span`` () =
72
84
  let digits = ""
73
- largestProduct digits 1 |> should equal None
85
+ let span = 1
86
+ largestProduct digits span |> should equal None
74
87
 
75
88
  [<Fact(Skip = "Remove to run test")>]
76
89
  let ``Rejects invalid character in digits`` () =
77
90
  let digits = "1234a5"
78
- largestProduct digits 2 |> should equal None
91
+ let span = 2
92
+ largestProduct digits span |> should equal None
79
93
 
80
94
  [<Fact(Skip = "Remove to run test")>]
81
95
  let ``Rejects negative span`` () =
82
96
  let digits = "12345"
83
- largestProduct digits -1 |> should equal None
97
+ let span = -1
98
+ largestProduct digits span |> should equal None
84
99
 
@@ -1,4 +1,4 @@
1
- // This file was auto-generated based on version 1.1.0 of the canonical data.
1
+ // This file was auto-generated based on version 1.2.0 of the canonical data.
2
2
 
3
3
  module LeapTest
4
4
 
@@ -13,7 +13,7 @@ let ``Year not divisible by 4: common year`` () =
13
13
 
14
14
  [<Fact(Skip = "Remove to run test")>]
15
15
  let ``Year divisible by 4, not divisible by 100: leap year`` () =
16
- leapYear 2020 |> should equal true
16
+ leapYear 1996 |> should equal true
17
17
 
18
18
  [<Fact(Skip = "Remove to run test")>]
19
19
  let ``Year divisible by 100, not divisible by 400: common year`` () =
@@ -1,4 +1,4 @@
1
- module Rectangle
1
+ module Rectangles
2
2
 
3
3
  open System
4
4
 
@@ -1,3 +1,3 @@
1
- module Rectangle
1
+ module Rectangles
2
2
 
3
3
  let rectangles lines = failwith "You need to implement this function."
@@ -1,11 +1,11 @@
1
+ // This file was auto-generated based on version 1.0.0 of the canonical data.
2
+
1
3
  module RectanglesTest
2
4
 
3
- open Xunit
4
5
  open FsUnit.Xunit
6
+ open Xunit
5
7
 
6
- open System
7
-
8
- open Rectangle
8
+ open Rectangles
9
9
 
10
10
  [<Fact>]
11
11
  let ``No rows`` () =
@@ -25,70 +25,93 @@ let ``No rectangles`` () =
25
25
  [<Fact(Skip = "Remove to run test")>]
26
26
  let ``One rectangle`` () =
27
27
  let input =
28
- [ "+-+";
29
- "| |";
30
- "+-+" ]
28
+ [ "+-+";
29
+ "| |";
30
+ "+-+" ]
31
31
  rectangles input |> should equal 1
32
32
 
33
33
  [<Fact(Skip = "Remove to run test")>]
34
- let ``two rectangles without shared parts`` () =
34
+ let ``Two rectangles without shared parts`` () =
35
35
  let input =
36
- [ " +-+";
37
- " | |";
38
- "+-+-+";
39
- "| | ";
40
- "+-+ " ]
36
+ [ " +-+";
37
+ " | |";
38
+ "+-+-+";
39
+ "| | ";
40
+ "+-+ " ]
41
41
  rectangles input |> should equal 2
42
42
 
43
43
  [<Fact(Skip = "Remove to run test")>]
44
44
  let ``Five rectangles with shared parts`` () =
45
45
  let input =
46
- [ " +-+";
47
- " | |";
48
- "+-+-+";
49
- "| | |";
50
- "+-+-+" ]
46
+ [ " +-+";
47
+ " | |";
48
+ "+-+-+";
49
+ "| | |";
50
+ "+-+-+" ]
51
51
  rectangles input |> should equal 5
52
52
 
53
+ [<Fact(Skip = "Remove to run test")>]
54
+ let ``Rectangle of height 1 is counted`` () =
55
+ let input =
56
+ [ "+--+";
57
+ "+--+" ]
58
+ rectangles input |> should equal 1
59
+
60
+ [<Fact(Skip = "Remove to run test")>]
61
+ let ``Rectangle of width 1 is counted`` () =
62
+ let input =
63
+ [ "++";
64
+ "||";
65
+ "++" ]
66
+ rectangles input |> should equal 1
67
+
68
+ [<Fact(Skip = "Remove to run test")>]
69
+ let ``1x1 square is counted`` () =
70
+ let input =
71
+ [ "++";
72
+ "++" ]
73
+ rectangles input |> should equal 1
74
+
53
75
  [<Fact(Skip = "Remove to run test")>]
54
76
  let ``Only complete rectangles are counted`` () =
55
77
  let input =
56
- [ " +-+";
57
- " |";
58
- "+-+-+";
59
- "| | -";
60
- "+-+-+" ]
78
+ [ " +-+";
79
+ " |";
80
+ "+-+-+";
81
+ "| | -";
82
+ "+-+-+" ]
61
83
  rectangles input |> should equal 1
62
84
 
63
85
  [<Fact(Skip = "Remove to run test")>]
64
86
  let ``Rectangles can be of different sizes`` () =
65
- let input =
66
- ["+------+----+";
67
- "| | |";
68
- "+---+--+ |";
69
- "| | |";
70
- "+---+-------+" ]
87
+ let input =
88
+ [ "+------+----+";
89
+ "| | |";
90
+ "+---+--+ |";
91
+ "| | |";
92
+ "+---+-------+" ]
71
93
  rectangles input |> should equal 3
72
94
 
73
95
  [<Fact(Skip = "Remove to run test")>]
74
96
  let ``Corner is required for a rectangle to be complete`` () =
75
97
  let input =
76
- [ "+------+----+";
77
- "| | |";
78
- "+------+ |";
79
- "| | |";
80
- "+---+-------+" ]
98
+ [ "+------+----+";
99
+ "| | |";
100
+ "+------+ |";
101
+ "| | |";
102
+ "+---+-------+" ]
81
103
  rectangles input |> should equal 2
82
104
 
83
105
  [<Fact(Skip = "Remove to run test")>]
84
106
  let ``Large input with many rectangles`` () =
85
107
  let input =
86
- [ "+---+--+----+";
87
- "| +--+----+";
88
- "+---+--+ |";
89
- "| +--+----+";
90
- "+---+--+--+-+";
91
- "+---+--+--+-+";
92
- "+------+ | |";
93
- " +-+" ]
94
- rectangles input |> should equal 60
108
+ [ "+---+--+----+";
109
+ "| +--+----+";
110
+ "+---+--+ |";
111
+ "| +--+----+";
112
+ "+---+--+--+-+";
113
+ "+---+--+--+-+";
114
+ "+------+ | |";
115
+ " +-+" ]
116
+ rectangles input |> should equal 60
117
+
@@ -94,12 +94,67 @@ type Change() =
94
94
  | _ -> None
95
95
  | _ -> None
96
96
 
97
+ type Clock() =
98
+ inherit Exercise()
99
+
100
+ let createClock (value:obj) clockId =
101
+ let clock = value :?> JObject
102
+ let hour = clock.["hour"].ToObject<string>()
103
+ let minute = clock.["minute"].ToObject<string>()
104
+ sprintf "let %s = create %s %s" clockId hour minute
105
+
106
+ member private this.renderPropertyValue canonicalDataCase property =
107
+ this.RenderSutParameter (canonicalDataCase, property, Map.find property canonicalDataCase.Properties)
108
+
109
+ override this.PropertiesWithIdentifier canonicalDataCase = ["clock1"; "clock2"]
110
+
111
+ override this.RenderValueWithIdentifier (canonicalDataCase, key, value) =
112
+ match key with
113
+ | "clock1" | "clock2" -> createClock value key
114
+ | _ -> base.RenderValueWithIdentifier (canonicalDataCase, key, value)
115
+
116
+ override this.RenderArrange canonicalDataCase =
117
+ match canonicalDataCase.Property with
118
+ | "create" | "add" ->
119
+ let hour = this.renderPropertyValue canonicalDataCase "hour"
120
+ let minute = this.renderPropertyValue canonicalDataCase "minute"
121
+ [sprintf "let clock = create %s %s" hour minute]
122
+ | _ ->
123
+ base.RenderArrange canonicalDataCase
124
+
125
+ override this.RenderSut canonicalDataCase =
126
+ match canonicalDataCase.Property with
127
+ | "create" ->
128
+ sprintf "display clock"
129
+ | "add" ->
130
+ this.renderPropertyValue canonicalDataCase "add"
131
+ |> sprintf "add %s clock |> display"
132
+ | "equal" ->
133
+ "clock1 = clock2"
134
+ | _ ->
135
+ base.RenderSut canonicalDataCase
136
+
97
137
  type CryptoSquare() =
98
138
  inherit Exercise()
99
139
 
100
140
  type DifferenceOfSquares() =
101
141
  inherit Exercise()
102
142
 
143
+ type Dominoes() =
144
+ inherit Exercise()
145
+
146
+ let formatAsTuple (value:obj) =
147
+ let twoElementList = value :?> JArray |> normalizeJArray
148
+ (twoElementList.Item 0, twoElementList.Item 1) |> string
149
+
150
+ override this.RenderInput (canonicalDataCase, key, value) =
151
+ value :?> JArray
152
+ |> normalizeJArray
153
+ |> Seq.map formatAsTuple
154
+ |> formatList
155
+
156
+ override this.PropertiesWithIdentifier canonicalDataCase = this.PropertiesUsedAsSutParameter canonicalDataCase
157
+
103
158
  type Gigasecond() =
104
159
  inherit Exercise()
105
160
 
@@ -147,7 +202,7 @@ type KindergartenGarden() =
147
202
  type LargestSeriesProduct() =
148
203
  inherit Exercise()
149
204
 
150
- override this.PropertiesWithIdentifier canonicalDataCase = ["digits"]
205
+ override this.PropertiesWithIdentifier canonicalDataCase = this.PropertiesUsedAsSutParameter canonicalDataCase
151
206
 
152
207
  override this.RenderExpected (canonicalDataCase, key, value) =
153
208
  value
@@ -267,6 +322,35 @@ type RailFenceCipher() =
267
322
  type Raindrops() =
268
323
  inherit Exercise()
269
324
 
325
+ type Rectangles() =
326
+ inherit Exercise()
327
+
328
+ member private this.GetPadding n =
329
+ String.replicate n " "
330
+
331
+ member private this.FormatList (list: List<string>) =
332
+ let separator = "; \n" + (this.GetPadding 8)
333
+ let value =
334
+ list
335
+ |> String.concat separator
336
+
337
+ if list.Length < 2 then
338
+ sprintf "[%s]" value
339
+ else
340
+ sprintf "\n%s[ %s ]" (this.GetPadding 6) value
341
+
342
+ override this.PropertiesWithIdentifier canonicalDataCase = ["input"]
343
+ override this.RenderSutProperty canonicalDataCase = "rectangles"
344
+
345
+ override this.RenderValueWithoutIdentifier (canonicalDataCase, key, value) =
346
+ match key with
347
+ | "input" ->
348
+ (value :?> JToken).ToObject<List<string>>()
349
+ |> List.map formatString
350
+ |> this.FormatList
351
+ | _ ->
352
+ base.RenderValueWithoutIdentifier (canonicalDataCase, key, value)
353
+
270
354
  type RobotSimulator() =
271
355
  inherit Exercise()
272
356