trackler 2.2.1.95 → 2.2.1.96

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/two-bucket/canonical-data.json +31 -31
  4. data/tracks/csharp/docs/ABOUT.md +21 -3
  5. data/tracks/dart/.travis.yml +1 -2
  6. data/tracks/dart/README.md +2 -2
  7. data/tracks/dart/{tool/create-exercise → bin/create_exercise.dart} +14 -10
  8. data/tracks/dart/test/create_exercise_test.dart +132 -0
  9. data/tracks/dart/test/exercises_test.dart +1 -1
  10. data/tracks/fsharp/exercises/list-ops/Example.fs +5 -5
  11. data/tracks/fsharp/exercises/list-ops/ListOps.fs +1 -1
  12. data/tracks/fsharp/exercises/list-ops/ListOpsTest.fs +41 -62
  13. data/tracks/fsharp/generators/Common.fs +3 -0
  14. data/tracks/fsharp/generators/Formatting.fs +3 -1
  15. data/tracks/fsharp/generators/Generators.fs +21 -0
  16. data/tracks/go/config.json +14 -0
  17. data/tracks/go/exercises/grep/.meta/gen.go +76 -0
  18. data/tracks/go/exercises/grep/.meta/hints.md +13 -0
  19. data/tracks/go/exercises/grep/README.md +104 -0
  20. data/tracks/go/exercises/grep/cases_test.go +202 -0
  21. data/tracks/go/exercises/grep/example.go +102 -0
  22. data/tracks/go/exercises/grep/grep_test.go +84 -0
  23. data/tracks/java/exercises/anagram/.meta/version +1 -1
  24. data/tracks/java/exercises/anagram/src/test/java/AnagramTest.java +0 -32
  25. data/tracks/java/exercises/space-age/.meta/src/reference/java/SpaceAge.java +0 -4
  26. data/tracks/java/exercises/space-age/.meta/version +1 -0
  27. data/tracks/java/exercises/space-age/src/test/java/SpaceAgeTest.java +0 -16
  28. data/tracks/julia/.gitignore +1 -0
  29. data/tracks/julia/exercises/complex-numbers/{HINTS.md → .meta/hints.md} +0 -0
  30. data/tracks/julia/exercises/custom-set/{HINTS.md → .meta/hints.md} +0 -0
  31. data/tracks/julia/exercises/robot-name/{HINTS.md → .meta/hints.md} +0 -0
  32. data/tracks/julia/exercises/rotational-cipher/{HINTS.md → .meta/hints.md} +0 -0
  33. data/tracks/julia/runtests.jl +24 -25
  34. data/tracks/perl6/.travis.yml +7 -3
  35. data/tracks/perl6/Dockerfile +4 -0
  36. data/tracks/perl6/exercises/accumulate/Accumulate.pm6 +1 -1
  37. data/tracks/perl6/exercises/accumulate/Example.pm6 +1 -1
  38. data/tracks/perl6/exercises/accumulate/accumulate.t +6 -15
  39. data/tracks/perl6/exercises/accumulate/example.yaml +2 -3
  40. data/tracks/perl6/exercises/acronym/Acronym.pm6 +1 -1
  41. data/tracks/perl6/exercises/acronym/Example.pm6 +1 -1
  42. data/tracks/perl6/exercises/acronym/acronym.t +7 -29
  43. data/tracks/perl6/exercises/acronym/example.yaml +2 -3
  44. data/tracks/perl6/exercises/all-your-base/AllYourBase.pm6 +1 -1
  45. data/tracks/perl6/exercises/all-your-base/Example.pm6 +1 -1
  46. data/tracks/perl6/exercises/all-your-base/all-your-base.t +7 -29
  47. data/tracks/perl6/exercises/all-your-base/example.yaml +2 -3
  48. data/tracks/perl6/exercises/allergies/Allergies.pm6 +1 -1
  49. data/tracks/perl6/exercises/allergies/Example.pm6 +1 -1
  50. data/tracks/perl6/exercises/allergies/allergies.t +7 -29
  51. data/tracks/perl6/exercises/allergies/example.yaml +2 -3
  52. data/tracks/perl6/exercises/anagram/Anagram.pm6 +1 -1
  53. data/tracks/perl6/exercises/anagram/Example.pm6 +1 -1
  54. data/tracks/perl6/exercises/anagram/anagram.t +7 -29
  55. data/tracks/perl6/exercises/anagram/example.yaml +2 -3
  56. data/tracks/perl6/exercises/atbash-cipher/AtbashCipher.pm6 +1 -1
  57. data/tracks/perl6/exercises/atbash-cipher/Example.pm6 +1 -1
  58. data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +7 -29
  59. data/tracks/perl6/exercises/atbash-cipher/example.yaml +2 -3
  60. data/tracks/{julia/exercises/.keep → perl6/exercises/binary/Binary.pm6} +0 -0
  61. data/tracks/perl6/exercises/binary/binary.t +3 -5
  62. data/tracks/perl6/exercises/bob/Bob.pm6 +1 -1
  63. data/tracks/perl6/exercises/bob/Example.pm6 +1 -1
  64. data/tracks/perl6/exercises/bob/bob.t +9 -32
  65. data/tracks/perl6/exercises/bob/example.yaml +3 -7
  66. data/tracks/perl6/exercises/clock/Clock.pm6 +1 -1
  67. data/tracks/perl6/exercises/clock/Example.pm6 +1 -1
  68. data/tracks/perl6/exercises/clock/clock.t +12 -32
  69. data/tracks/perl6/exercises/clock/example.yaml +6 -6
  70. data/tracks/perl6/exercises/etl/ETL.pm6 +1 -1
  71. data/tracks/perl6/exercises/etl/Example.pm6 +1 -1
  72. data/tracks/perl6/exercises/etl/etl.t +7 -29
  73. data/tracks/perl6/exercises/etl/example.yaml +2 -3
  74. data/tracks/perl6/exercises/flatten-array/Example.pm6 +1 -1
  75. data/tracks/perl6/exercises/flatten-array/FlattenArray.pm6 +1 -1
  76. data/tracks/perl6/exercises/flatten-array/example.yaml +2 -3
  77. data/tracks/perl6/exercises/flatten-array/flatten-array.t +7 -29
  78. data/tracks/perl6/exercises/grade-school/Example.pm6 +1 -1
  79. data/tracks/perl6/exercises/grade-school/GradeSchool.pm6 +1 -1
  80. data/tracks/perl6/exercises/grade-school/example.yaml +2 -3
  81. data/tracks/perl6/exercises/grade-school/grade-school.t +6 -15
  82. data/tracks/perl6/exercises/grains/Example.pm6 +1 -1
  83. data/tracks/perl6/exercises/grains/Grains.pm6 +1 -1
  84. data/tracks/perl6/exercises/grains/example.yaml +2 -3
  85. data/tracks/perl6/exercises/grains/grains.t +7 -29
  86. data/tracks/perl6/exercises/hamming/Example.pm6 +1 -1
  87. data/tracks/perl6/exercises/hamming/Hamming.pm6 +1 -1
  88. data/tracks/perl6/exercises/hamming/example.yaml +2 -3
  89. data/tracks/perl6/exercises/hamming/hamming.t +7 -29
  90. data/tracks/perl6/exercises/hello-world/Example.pm6 +1 -1
  91. data/tracks/perl6/exercises/hello-world/HelloWorld.pm6 +1 -1
  92. data/tracks/perl6/exercises/hello-world/example.yaml +2 -8
  93. data/tracks/perl6/exercises/hello-world/hello-world.t +7 -33
  94. data/tracks/perl6/exercises/leap/Example.pm6 +1 -1
  95. data/tracks/perl6/exercises/leap/Leap.pm6 +1 -1
  96. data/tracks/perl6/exercises/leap/example.yaml +2 -3
  97. data/tracks/perl6/exercises/leap/leap.t +7 -29
  98. data/tracks/perl6/exercises/linked-list/Example.pm6 +1 -1
  99. data/tracks/perl6/exercises/linked-list/LinkedList.pm6 +1 -1
  100. data/tracks/perl6/exercises/linked-list/example.yaml +3 -3
  101. data/tracks/perl6/exercises/linked-list/linked-list.t +9 -16
  102. data/tracks/perl6/exercises/luhn/Example.pm6 +1 -1
  103. data/tracks/perl6/exercises/luhn/Luhn.pm6 +1 -1
  104. data/tracks/perl6/exercises/luhn/example.yaml +2 -3
  105. data/tracks/perl6/exercises/luhn/luhn.t +7 -29
  106. data/tracks/perl6/exercises/meetup/Example.pm6 +1 -1
  107. data/tracks/perl6/exercises/meetup/Meetup.pm6 +1 -1
  108. data/tracks/perl6/exercises/meetup/example.yaml +2 -3
  109. data/tracks/perl6/exercises/meetup/meetup.t +7 -29
  110. data/tracks/perl6/exercises/nucleotide-count/Example.pm6 +1 -1
  111. data/tracks/perl6/exercises/nucleotide-count/NucleotideCount.pm6 +1 -1
  112. data/tracks/perl6/exercises/nucleotide-count/example.yaml +2 -3
  113. data/tracks/perl6/exercises/nucleotide-count/nucleotide-count.t +7 -29
  114. data/tracks/perl6/exercises/pangram/Example.pm6 +1 -1
  115. data/tracks/perl6/exercises/pangram/Pangram.pm6 +1 -1
  116. data/tracks/perl6/exercises/pangram/example.yaml +2 -3
  117. data/tracks/perl6/exercises/pangram/pangram.t +7 -29
  118. data/tracks/perl6/exercises/phone-number/Example.pm6 +1 -1
  119. data/tracks/perl6/exercises/phone-number/Phone.pm6 +1 -1
  120. data/tracks/perl6/exercises/phone-number/example.yaml +2 -3
  121. data/tracks/perl6/exercises/phone-number/phone-number.t +7 -29
  122. data/tracks/perl6/exercises/raindrops/Example.pm6 +1 -1
  123. data/tracks/perl6/exercises/raindrops/Raindrops.pm6 +1 -1
  124. data/tracks/perl6/exercises/raindrops/example.yaml +2 -3
  125. data/tracks/perl6/exercises/raindrops/raindrops.t +7 -29
  126. data/tracks/perl6/exercises/rna-transcription/Example.pm6 +1 -1
  127. data/tracks/perl6/exercises/rna-transcription/RNA.pm6 +1 -1
  128. data/tracks/perl6/exercises/rna-transcription/example.yaml +2 -3
  129. data/tracks/perl6/exercises/rna-transcription/rna-transcription.t +7 -29
  130. data/tracks/perl6/exercises/robot-name/Example.pm6 +1 -1
  131. data/tracks/perl6/exercises/robot-name/Robot.pm6 +1 -1
  132. data/tracks/perl6/exercises/robot-name/example.yaml +5 -5
  133. data/tracks/perl6/exercises/robot-name/robot-name.t +10 -17
  134. data/tracks/perl6/exercises/roman-numerals/Example.pm6 +1 -1
  135. data/tracks/perl6/exercises/roman-numerals/RomanNumerals.pm6 +1 -1
  136. data/tracks/perl6/exercises/roman-numerals/example.yaml +2 -3
  137. data/tracks/perl6/exercises/roman-numerals/roman-numerals.t +7 -29
  138. data/tracks/perl6/exercises/scrabble-score/Example.pm6 +1 -1
  139. data/tracks/perl6/exercises/scrabble-score/Scrabble.pm6 +1 -1
  140. data/tracks/perl6/exercises/scrabble-score/example.yaml +2 -3
  141. data/tracks/perl6/exercises/scrabble-score/scrabble-score.t +7 -29
  142. data/tracks/perl6/exercises/space-age/Example.pm6 +1 -1
  143. data/tracks/perl6/exercises/space-age/SpaceAge.pm6 +1 -1
  144. data/tracks/perl6/exercises/space-age/example.yaml +2 -3
  145. data/tracks/perl6/exercises/space-age/space-age.t +7 -29
  146. data/tracks/perl6/exercises/trinary/Trinary.pm6 +0 -0
  147. data/tracks/perl6/exercises/trinary/trinary.t +2 -5
  148. data/tracks/perl6/exercises/two-fer/Example.pm6 +1 -1
  149. data/tracks/perl6/exercises/two-fer/TwoFer.pm6 +1 -1
  150. data/tracks/perl6/exercises/two-fer/example.yaml +2 -8
  151. data/tracks/perl6/exercises/two-fer/two-fer.t +7 -33
  152. data/tracks/perl6/exercises/word-count/Example.pm6 +1 -1
  153. data/tracks/perl6/exercises/word-count/WordCount.pm6 +1 -1
  154. data/tracks/perl6/exercises/word-count/example.yaml +2 -3
  155. data/tracks/perl6/exercises/word-count/word-count.t +7 -29
  156. data/tracks/perl6/exercises/wordy/Example.pm6 +1 -1
  157. data/tracks/perl6/exercises/wordy/Wordy.pm6 +1 -1
  158. data/tracks/perl6/exercises/wordy/example.yaml +2 -3
  159. data/tracks/perl6/exercises/wordy/wordy.t +7 -29
  160. data/tracks/perl6/templates/test.mustache +10 -39
  161. data/tracks/python/config.json +10 -0
  162. data/tracks/python/exercises/all-your-base/all_your_base_test.py +2 -2
  163. data/tracks/python/exercises/binary-search/binary_search_test.py +2 -2
  164. data/tracks/python/exercises/binary/binary_test.py +2 -2
  165. data/tracks/python/exercises/bob/bob_test.py +4 -2
  166. data/tracks/python/exercises/bob/example.py +5 -2
  167. data/tracks/python/exercises/circular-buffer/circular_buffer_test.py +2 -2
  168. data/tracks/python/exercises/custom-set/README.md +20 -0
  169. data/tracks/python/exercises/custom-set/custom_set.py +30 -0
  170. data/tracks/python/exercises/custom-set/custom_set_test.py +212 -0
  171. data/tracks/python/exercises/custom-set/example.py +45 -0
  172. data/tracks/python/exercises/dot-dsl/dot_dsl_test.py +20 -10
  173. data/tracks/python/exercises/error-handling/error_handling_test.py +2 -2
  174. data/tracks/python/exercises/forth/forth_test.py +18 -18
  175. data/tracks/python/exercises/grains/grains_test.py +2 -2
  176. data/tracks/python/exercises/hamming/hamming_test.py +2 -2
  177. data/tracks/python/exercises/hexadecimal/hexadecimal_test.py +2 -2
  178. data/tracks/python/exercises/largest-series-product/largest_series_product_test.py +2 -2
  179. data/tracks/python/exercises/meetup/meetup_test.py +2 -2
  180. data/tracks/python/exercises/minesweeper/minesweeper_test.py +2 -2
  181. data/tracks/python/exercises/nth-prime/nth_prime_test.py +2 -2
  182. data/tracks/python/exercises/nucleotide-count/nucleotide_count_test.py +2 -2
  183. data/tracks/python/exercises/ocr-numbers/ocr_numbers_test.py +2 -2
  184. data/tracks/python/exercises/octal/octal_test.py +2 -2
  185. data/tracks/python/exercises/perfect-numbers/perfect_numbers_test.py +2 -2
  186. data/tracks/python/exercises/phone-number/phone_number_test.py +2 -2
  187. data/tracks/python/exercises/pov/pov_test.py +2 -2
  188. data/tracks/python/exercises/protein-translation/protein_translation_test.py +2 -2
  189. data/tracks/python/exercises/pythagorean-triplet/pythagorean_triplet_test.py +2 -2
  190. data/tracks/python/exercises/queen-attack/queen_attack_test.py +2 -2
  191. data/tracks/python/exercises/rna-transcription/rna_transcription_test.py +2 -2
  192. data/tracks/python/exercises/saddle-points/saddle_points_test.py +2 -2
  193. data/tracks/python/exercises/say/say_test.py +2 -2
  194. data/tracks/python/exercises/scale-generator/scale_generator_test.py +2 -2
  195. data/tracks/python/exercises/series/series_test.py +2 -2
  196. data/tracks/python/exercises/simple-cipher/simple_cipher_test.py +2 -2
  197. data/tracks/python/exercises/simple-linked-list/simple_linked_list_test.py +2 -2
  198. data/tracks/python/exercises/tree-building/tree_building_test.py +2 -2
  199. data/tracks/python/exercises/triangle/example.py +14 -24
  200. data/tracks/python/exercises/triangle/triangle.py +6 -6
  201. data/tracks/python/exercises/triangle/triangle_test.py +42 -44
  202. data/tracks/python/exercises/variable-length-quantity/variable_length_quantity_test.py +2 -2
  203. data/tracks/python/exercises/wordy/wordy_test.py +2 -2
  204. data/tracks/python/test/check-exercises.py +2 -1
  205. metadata +22 -8
@@ -2,7 +2,7 @@
2
2
 
3
3
  let rec foldl folder state list = failwith "You need to implement this function."
4
4
 
5
- let rec foldr folder list state = failwith "You need to implement this function."
5
+ let rec foldr folder state list = failwith "You need to implement this function."
6
6
 
7
7
  let length list = failwith "You need to implement this function."
8
8
 
@@ -1,106 +1,85 @@
1
+ // This file was auto-generated based on version 2.1.0 of the canonical data.
2
+
1
3
  module ListOpsTest
2
4
 
3
- open Xunit
4
5
  open FsUnit.Xunit
6
+ open Xunit
5
7
 
6
8
  open ListOps
7
9
 
8
- let big = 100000
9
- let bigList = [1 .. big]
10
- let odd x = x % 2 = 1
11
-
12
10
  [<Fact>]
13
- let ``length of empty list`` () =
14
- length [] |> should equal 0
15
-
16
- [<Fact(Skip = "Remove to run test")>]
17
- let ``length of non-empty list`` () =
18
- length [1 .. 4] |> should equal 4
19
-
20
- [<Fact(Skip = "Remove to run test")>]
21
- let ``length of large list`` () =
22
- length [1 .. big] |> should equal big
23
-
24
- [<Fact(Skip = "Remove to run test")>]
25
- let ``reverse of empty list`` () =
26
- reverse [] |> should be Empty
27
-
28
- [<Fact(Skip = "Remove to run test")>]
29
- let ``reverse of non-empty list`` () =
30
- reverse [1 .. 100] |> should equal [100 .. -1 .. 1]
11
+ let ``append empty lists`` () =
12
+ append [] [] |> should be Empty
31
13
 
32
14
  [<Fact(Skip = "Remove to run test")>]
33
- let ``map of empty list`` () =
34
- map ((+) 1) [] |> should be Empty
15
+ let ``append empty list to list`` () =
16
+ append [] [1; 2; 3; 4] |> should equal [1; 2; 3; 4]
35
17
 
36
18
  [<Fact(Skip = "Remove to run test")>]
37
- let ``map of non-empty list`` () =
38
- map ((+) 1) [1 .. 2 .. 7] |> should equal [2 .. 2 .. 8]
19
+ let ``append non-empty lists`` () =
20
+ append [1; 2] [2; 3; 4; 5] |> should equal [1; 2; 2; 3; 4; 5]
39
21
 
40
22
  [<Fact(Skip = "Remove to run test")>]
41
- let ``filter of empty list`` () =
42
- filter id [] |> should be Empty
23
+ let ``concat empty list`` () =
24
+ concat [] |> should be Empty
43
25
 
44
26
  [<Fact(Skip = "Remove to run test")>]
45
- let ``filter of normal list`` () =
46
- filter odd [1 .. 4] |> should equal [1; 3]
27
+ let ``concat list of lists`` () =
28
+ concat [[1; 2]; [3]; []; [4; 5; 6]] |> should equal [1; 2; 3; 4; 5; 6]
47
29
 
48
30
  [<Fact(Skip = "Remove to run test")>]
49
- let ``foldl of empty list`` () =
50
- foldl (+) 0 [] |> should equal 0
31
+ let ``filter empty list`` () =
32
+ filter (fun x -> x % 2 = 1) [] |> should be Empty
51
33
 
52
34
  [<Fact(Skip = "Remove to run test")>]
53
- let ``foldl of non-empty list`` () =
54
- foldl (+) -3 [1 .. 4] |> should equal 7
35
+ let ``filter non-empty list`` () =
36
+ filter (fun x -> x % 2 = 1) [1; 2; 3; 5] |> should equal [1; 3; 5]
55
37
 
56
38
  [<Fact(Skip = "Remove to run test")>]
57
- let ``foldl of huge list`` () =
58
- foldl (+) 0 [1 .. big] |> should equal (big * (big + 1) / 2)
39
+ let ``length empty list`` () =
40
+ length [] |> should equal 0
59
41
 
60
42
  [<Fact(Skip = "Remove to run test")>]
61
- let ``foldl with non-commutative function`` () =
62
- foldl (-) 10 [1 .. 4] |> should equal 0
43
+ let ``length non-empty list`` () =
44
+ length [1; 2; 3; 4] |> should equal 4
63
45
 
64
46
  [<Fact(Skip = "Remove to run test")>]
65
- let ``foldl is not just foldr . flip`` () =
66
- foldl (fun acc item -> item :: acc) [] (List.ofSeq "asdf") |> should equal (List.ofSeq "fdsa")
47
+ let ``map empty list`` () =
48
+ map (fun x -> x + 1) [] |> should be Empty
67
49
 
68
50
  [<Fact(Skip = "Remove to run test")>]
69
- let ``foldr as id`` () =
70
- foldr (fun item acc -> item :: acc) [1 .. big] [] = bigList |> should equal true
51
+ let ``map non-empty list`` () =
52
+ map (fun x -> x + 1) [1; 3; 5; 7] |> should equal [2; 4; 6; 8]
71
53
 
72
54
  [<Fact(Skip = "Remove to run test")>]
73
- let ``foldr as append`` () =
74
- foldr (fun item acc -> item :: acc) [1 .. 99] [100 .. big] = bigList |> should equal true
55
+ let ``foldl empty list`` () =
56
+ foldl (fun x y -> x * y) 2 [] |> should equal 2
75
57
 
76
58
  [<Fact(Skip = "Remove to run test")>]
77
- let ``append of empty lists`` () =
78
- append [] [] |> should be Empty
59
+ let ``foldl direction independent function applied to non-empty list`` () =
60
+ foldl (fun x y -> x + y) 5 [1; 2; 3; 4] |> should equal 15
79
61
 
80
62
  [<Fact(Skip = "Remove to run test")>]
81
- let ``append of empty and non-empty lists`` () =
82
- append [] [1 .. 4] |> should equal [1 .. 4]
63
+ let ``foldl direction dependent function applied to non-empty list`` () =
64
+ foldl (fun x y -> x / y) 5 [2; 5] |> should equal 0
83
65
 
84
66
  [<Fact(Skip = "Remove to run test")>]
85
- let ``append of non-empty and empty lists`` () =
86
- append [1 .. 4] [] |> should equal [1 .. 4]
67
+ let ``foldr empty list`` () =
68
+ foldr (fun x y -> x * y) 2 [] |> should equal 2
87
69
 
88
70
  [<Fact(Skip = "Remove to run test")>]
89
- let ``append of non-empty lists`` () =
90
- append [1 .. 3] [4; 5] |> should equal [1 .. 5]
71
+ let ``foldr direction independent function applied to non-empty list`` () =
72
+ foldr (fun x y -> x + y) 5 [1; 2; 3; 4] |> should equal 15
91
73
 
92
74
  [<Fact(Skip = "Remove to run test")>]
93
- let ``append of large lists`` () =
94
- append [1 .. (big / 2)] [1 + big / 2 .. big] = bigList |> should equal true
75
+ let ``foldr direction dependent function applied to non-empty list`` () =
76
+ foldr (fun x y -> x / y) 5 [2; 5] |> should equal 2
95
77
 
96
78
  [<Fact(Skip = "Remove to run test")>]
97
- let ``concat of no lists`` () =
98
- concat [] |> should be Empty
79
+ let ``reverse empty list`` () =
80
+ reverse [] |> should be Empty
99
81
 
100
82
  [<Fact(Skip = "Remove to run test")>]
101
- let ``concat of list of lists`` () =
102
- concat [[1; 2]; [3]; []; [4; 5; 6]] |> should equal [1 .. 6]
83
+ let ``reverse non-empty list`` () =
84
+ reverse [1; 3; 5; 7] |> should equal [7; 5; 3; 1]
103
85
 
104
- [<Fact(Skip = "Remove to run test")>]
105
- let ``concat of large list of small lists`` () =
106
- concat (map (fun x -> [x]) [1 .. big]) = bigList |> should equal true
@@ -86,6 +86,9 @@ module String =
86
86
  | "" -> str
87
87
  | _ -> sprintf "%c%s" (Char.ToLower(str.[0])) str.[1..]
88
88
 
89
+ let replace (oldValue: string) (newValue: string) (str: string) =
90
+ str.Replace(oldValue, newValue)
91
+
89
92
  module Json =
90
93
  let rec parentsAndSelf (currentToken: JToken) =
91
94
  let rec helper acc (token: JToken) =
@@ -44,7 +44,7 @@ let formatDateTime (dateTime: DateTime) =
44
44
  let formatTimeSpan (timeSpan: TimeSpan) =
45
45
  sprintf "TimeSpan(%d, %d, %d)" timeSpan.Hours timeSpan.Minutes timeSpan.Seconds
46
46
 
47
- let normalizeJArray (jArray: JArray): obj list =
47
+ let rec normalizeJArray (jArray: JArray): obj list =
48
48
  let toBoxedList seq =
49
49
  seq
50
50
  |> Seq.map box
@@ -66,6 +66,8 @@ let normalizeJArray (jArray: JArray): obj list =
66
66
  jArray.Values<TimeSpan>() |> toBoxedList
67
67
  else if jArray.Children() |> Seq.forall (fun x -> x.Type = JTokenType.Object) then
68
68
  jArray.Children() |> Seq.map (fun jObject -> jObject.ToObject<Dictionary<string, obj>>()) |> toBoxedList
69
+ else if jArray.Children() |> Seq.forall (fun x -> x.Type = JTokenType.Array) then
70
+ jArray.Values<JArray>() |> Seq.map normalizeJArray |> toBoxedList
69
71
  else
70
72
  jArray.Values<obj>() |> toBoxedList
71
73
 
@@ -472,6 +472,27 @@ type LargestSeriesProduct() =
472
472
  type Leap() =
473
473
  inherit GeneratorExercise()
474
474
 
475
+ type ListOps() =
476
+ inherit GeneratorExercise()
477
+
478
+ let renderFunction (value: obj) =
479
+ value
480
+ |> string
481
+ |> String.replace "(" ""
482
+ |> String.replace ")" ""
483
+ |> String.replace "," ""
484
+ |> String.replace "==" "="
485
+ |> String.replace "modulo" "%"
486
+ |> sprintf "(fun %s)"
487
+
488
+ override __.RenderInput (canonicalDataCase, key, value) =
489
+ match key with
490
+ | "function" -> renderFunction value
491
+ | _ -> base.RenderInput (canonicalDataCase, key, value)
492
+
493
+ override __.RenderTestMethodName canonicalDataCase =
494
+ sprintf "%s %s" canonicalDataCase.Property canonicalDataCase.Description
495
+
475
496
  type Luhn() =
476
497
  inherit GeneratorExercise()
477
498
 
@@ -1207,6 +1207,20 @@
1207
1207
  "unlocked_by": "flatten-array",
1208
1208
  "uuid": "6b313720-104a-46c2-8290-4b4af121101f "
1209
1209
  },
1210
+ {
1211
+ "core": false,
1212
+ "difficulty": 4,
1213
+ "slug": "grep",
1214
+ "topics": [
1215
+ "algorithms",
1216
+ "arrays",
1217
+ "conditionals",
1218
+ "searching",
1219
+ "strings"
1220
+ ],
1221
+ "unlocked_by": "hamming",
1222
+ "uuid": "ec5dab72-dd96-4dce-8886-aff52a6eb090"
1223
+ },
1210
1224
  {
1211
1225
  "deprecated": true,
1212
1226
  "slug": "binary",
@@ -0,0 +1,76 @@
1
+ package main
2
+
3
+ import (
4
+ "log"
5
+ "strings"
6
+ "text/template"
7
+
8
+ "../../../gen"
9
+ )
10
+
11
+ func main() {
12
+ t := template.New("").Funcs(template.FuncMap{
13
+ "fileContentData": FileContentData,
14
+ })
15
+ t, err := t.Parse(tmpl)
16
+ if err != nil {
17
+ log.Fatal(err)
18
+ }
19
+ var j js
20
+ if err := gen.Gen("grep", &j, t); err != nil {
21
+ log.Fatal(err)
22
+ }
23
+ }
24
+
25
+ // The JSON structure we expect to be able to unmarshal into
26
+ type js struct {
27
+ Comments []string
28
+ Cases []struct {
29
+ Description string
30
+ Cases []struct {
31
+ Description string
32
+ Pattern string
33
+ Flags []string
34
+ Files []string
35
+ Expected []string
36
+ }
37
+ }
38
+ }
39
+
40
+ func FileContentData(comments []string) []string {
41
+ var start int
42
+ for i, c := range comments {
43
+ if strings.Contains(c, "contents are listed below:") {
44
+ start = i + 1
45
+ break
46
+ }
47
+ }
48
+ return comments[start:]
49
+ }
50
+
51
+ // template applied to above data structure generates the Go test cases
52
+ var tmpl = `package grep
53
+
54
+ {{.Header}}
55
+
56
+ var fileContentData = []string{ {{range $line := fileContentData .J.Comments}}{{printf "\n%q," $line}}{{end}}
57
+ }
58
+
59
+ var testCases = []struct {
60
+ description string
61
+ pattern string
62
+ flags []string
63
+ files []string
64
+ expected []string
65
+ }{
66
+ {{range .J.Cases}}
67
+ {{range .Cases}}{
68
+ description: {{printf "%q" .Description}},
69
+ pattern: {{printf "%q" .Pattern}},
70
+ flags: {{printf "%#v" .Flags}},
71
+ files: {{printf "%#v" .Files}},
72
+ expected: {{printf "%#v" .Expected}},
73
+ },
74
+ {{end}}{{end}}
75
+ }
76
+ `
@@ -0,0 +1,13 @@
1
+ ## Implementation
2
+
3
+ In package grep, Define a single Go func, Search, which accepts a pattern string,
4
+ a slice of flags which are strings, and a slice of filename strings.
5
+ Search should return a slice of strings of the output for
6
+ the given flags and filenames.
7
+
8
+ Use the following signature for func Search:
9
+
10
+ ```
11
+ func Search(pattern string, flags, files []string) []string {
12
+ ```
13
+
@@ -0,0 +1,104 @@
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
+ ## Implementation
68
+
69
+ In package grep, Define a single Go func, Search, which accepts a pattern string,
70
+ a slice of flags which are strings, and a slice of filename strings.
71
+ Search should return a slice of strings of the output for
72
+ the given flags and filenames.
73
+
74
+ Use the following signature for func Search:
75
+
76
+ ```
77
+ func Search(pattern string, flags, files []string) []string {
78
+ ```
79
+
80
+
81
+
82
+ ## Running the tests
83
+
84
+ To run the tests run the command `go test` from within the exercise directory.
85
+
86
+ If the test suite contains benchmarks, you can run these with the `-bench`
87
+ flag:
88
+
89
+ go test -bench .
90
+
91
+ Keep in mind that each reviewer will run benchmarks on a different machine, with
92
+ different specs, so the results from these benchmark tests may vary.
93
+
94
+ ## Further information
95
+
96
+ For more detailed information about the Go track, including how to get help if
97
+ you're having trouble, please visit the exercism.io [Go language page](http://exercism.io/languages/go/about).
98
+
99
+ ## Source
100
+
101
+ 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)
102
+
103
+ ## Submitting Incomplete Solutions
104
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,202 @@
1
+ package grep
2
+
3
+ // Source: exercism/problem-specifications
4
+ // Commit: af7f929 grep: Fix canonical-data.json formatting
5
+ // Problem Specifications Version: 1.0.0
6
+
7
+ var fileContentData = []string{
8
+ " ",
9
+ " iliad.txt ",
10
+ " --------------------------------------------- ",
11
+ " |Achilles sing, O Goddess! Peleus' son; | ",
12
+ " |His wrath pernicious, who ten thousand woes| ",
13
+ " |Caused to Achaia's host, sent many a soul | ",
14
+ " |Illustrious into Ades premature, | ",
15
+ " |And Heroes gave (so stood the will of Jove)| ",
16
+ " |To dogs and to all ravening fowls a prey, | ",
17
+ " |When fierce dispute had separated once | ",
18
+ " |The noble Chief Achilles from the son | ",
19
+ " |Of Atreus, Agamemnon, King of men. | ",
20
+ " --------------------------------------------- ",
21
+ " ",
22
+ " midsummer-night.txt ",
23
+ " ----------------------------------------------- ",
24
+ " |I do entreat your grace to pardon me. | ",
25
+ " |I know not by what power I am made bold, | ",
26
+ " |Nor how it may concern my modesty, | ",
27
+ " |In such a presence here to plead my thoughts;| ",
28
+ " |But I beseech your grace that I may know | ",
29
+ " |The worst that may befall me in this case, | ",
30
+ " |If I refuse to wed Demetrius. | ",
31
+ " ----------------------------------------------- ",
32
+ " ",
33
+ " paradise-lost.txt ",
34
+ " ------------------------------------------------- ",
35
+ " |Of Mans First Disobedience, and the Fruit | ",
36
+ " |Of that Forbidden Tree, whose mortal tast | ",
37
+ " |Brought Death into the World, and all our woe, | ",
38
+ " |With loss of Eden, till one greater Man | ",
39
+ " |Restore us, and regain the blissful Seat, | ",
40
+ " |Sing Heav'nly Muse, that on the secret top | ",
41
+ " |Of Oreb, or of Sinai, didst inspire | ",
42
+ " |That Shepherd, who first taught the chosen Seed| ",
43
+ " ------------------------------------------------- ",
44
+ }
45
+
46
+ var testCases = []struct {
47
+ description string
48
+ pattern string
49
+ flags []string
50
+ files []string
51
+ expected []string
52
+ }{
53
+
54
+ {
55
+ description: "One file, one match, no flags",
56
+ pattern: "Agamemnon",
57
+ flags: []string{},
58
+ files: []string{"iliad.txt"},
59
+ expected: []string{"Of Atreus, Agamemnon, King of men."},
60
+ },
61
+ {
62
+ description: "One file, one match, print line numbers flag",
63
+ pattern: "Forbidden",
64
+ flags: []string{"-n"},
65
+ files: []string{"paradise-lost.txt"},
66
+ expected: []string{"2:Of that Forbidden Tree, whose mortal tast"},
67
+ },
68
+ {
69
+ description: "One file, one match, case-insensitive flag",
70
+ pattern: "FORBIDDEN",
71
+ flags: []string{"-i"},
72
+ files: []string{"paradise-lost.txt"},
73
+ expected: []string{"Of that Forbidden Tree, whose mortal tast"},
74
+ },
75
+ {
76
+ description: "One file, one match, print file names flag",
77
+ pattern: "Forbidden",
78
+ flags: []string{"-l"},
79
+ files: []string{"paradise-lost.txt"},
80
+ expected: []string{"paradise-lost.txt"},
81
+ },
82
+ {
83
+ description: "One file, one match, match entire lines flag",
84
+ pattern: "With loss of Eden, till one greater Man",
85
+ flags: []string{"-x"},
86
+ files: []string{"paradise-lost.txt"},
87
+ expected: []string{"With loss of Eden, till one greater Man"},
88
+ },
89
+ {
90
+ description: "One file, one match, multiple flags",
91
+ pattern: "OF ATREUS, Agamemnon, KIng of MEN.",
92
+ flags: []string{"-n", "-i", "-x"},
93
+ files: []string{"iliad.txt"},
94
+ expected: []string{"9:Of Atreus, Agamemnon, King of men."},
95
+ },
96
+ {
97
+ description: "One file, several matches, no flags",
98
+ pattern: "may",
99
+ flags: []string{},
100
+ files: []string{"midsummer-night.txt"},
101
+ expected: []string{"Nor how it may concern my modesty,", "But I beseech your grace that I may know", "The worst that may befall me in this case,"},
102
+ },
103
+ {
104
+ description: "One file, several matches, print line numbers flag",
105
+ pattern: "may",
106
+ flags: []string{"-n"},
107
+ files: []string{"midsummer-night.txt"},
108
+ expected: []string{"3:Nor how it may concern my modesty,", "5:But I beseech your grace that I may know", "6:The worst that may befall me in this case,"},
109
+ },
110
+ {
111
+ description: "One file, several matches, match entire lines flag",
112
+ pattern: "may",
113
+ flags: []string{"-x"},
114
+ files: []string{"midsummer-night.txt"},
115
+ expected: []string{},
116
+ },
117
+ {
118
+ description: "One file, several matches, case-insensitive flag",
119
+ pattern: "ACHILLES",
120
+ flags: []string{"-i"},
121
+ files: []string{"iliad.txt"},
122
+ expected: []string{"Achilles sing, O Goddess! Peleus' son;", "The noble Chief Achilles from the son"},
123
+ },
124
+ {
125
+ description: "One file, several matches, inverted flag",
126
+ pattern: "Of",
127
+ flags: []string{"-v"},
128
+ files: []string{"paradise-lost.txt"},
129
+ expected: []string{"Brought Death into the World, and all our woe,", "With loss of Eden, till one greater Man", "Restore us, and regain the blissful Seat,", "Sing Heav'nly Muse, that on the secret top", "That Shepherd, who first taught the chosen Seed"},
130
+ },
131
+ {
132
+ description: "One file, no matches, various flags",
133
+ pattern: "Gandalf",
134
+ flags: []string{"-n", "-l", "-x", "-i"},
135
+ files: []string{"iliad.txt"},
136
+ expected: []string{},
137
+ },
138
+
139
+ {
140
+ description: "Multiple files, one match, no flags",
141
+ pattern: "Agamemnon",
142
+ flags: []string{},
143
+ files: []string{"iliad.txt", "midsummer-night.txt", "paradise-lost.txt"},
144
+ expected: []string{"iliad.txt:Of Atreus, Agamemnon, King of men."},
145
+ },
146
+ {
147
+ description: "Multiple files, several matches, no flags",
148
+ pattern: "may",
149
+ flags: []string{},
150
+ files: []string{"iliad.txt", "midsummer-night.txt", "paradise-lost.txt"},
151
+ expected: []string{"midsummer-night.txt:Nor how it may concern my modesty,", "midsummer-night.txt:But I beseech your grace that I may know", "midsummer-night.txt:The worst that may befall me in this case,"},
152
+ },
153
+ {
154
+ description: "Multiple files, several matches, print line numbers flag",
155
+ pattern: "that",
156
+ flags: []string{"-n"},
157
+ files: []string{"iliad.txt", "midsummer-night.txt", "paradise-lost.txt"},
158
+ expected: []string{"midsummer-night.txt:5:But I beseech your grace that I may know", "midsummer-night.txt:6:The worst that may befall me in this case,", "paradise-lost.txt:2:Of that Forbidden Tree, whose mortal tast", "paradise-lost.txt:6:Sing Heav'nly Muse, that on the secret top"},
159
+ },
160
+ {
161
+ description: "Multiple files, one match, print file names flag",
162
+ pattern: "who",
163
+ flags: []string{"-l"},
164
+ files: []string{"iliad.txt", "midsummer-night.txt", "paradise-lost.txt"},
165
+ expected: []string{"iliad.txt", "paradise-lost.txt"},
166
+ },
167
+ {
168
+ description: "Multiple files, several matches, case-insensitive flag",
169
+ pattern: "TO",
170
+ flags: []string{"-i"},
171
+ files: []string{"iliad.txt", "midsummer-night.txt", "paradise-lost.txt"},
172
+ expected: []string{"iliad.txt:Caused to Achaia's host, sent many a soul", "iliad.txt:Illustrious into Ades premature,", "iliad.txt:And Heroes gave (so stood the will of Jove)", "iliad.txt:To dogs and to all ravening fowls a prey,", "midsummer-night.txt:I do entreat your grace to pardon me.", "midsummer-night.txt:In such a presence here to plead my thoughts;", "midsummer-night.txt:If I refuse to wed Demetrius.", "paradise-lost.txt:Brought Death into the World, and all our woe,", "paradise-lost.txt:Restore us, and regain the blissful Seat,", "paradise-lost.txt:Sing Heav'nly Muse, that on the secret top"},
173
+ },
174
+ {
175
+ description: "Multiple files, several matches, inverted flag",
176
+ pattern: "a",
177
+ flags: []string{"-v"},
178
+ files: []string{"iliad.txt", "midsummer-night.txt", "paradise-lost.txt"},
179
+ expected: []string{"iliad.txt:Achilles sing, O Goddess! Peleus' son;", "iliad.txt:The noble Chief Achilles from the son", "midsummer-night.txt:If I refuse to wed Demetrius."},
180
+ },
181
+ {
182
+ description: "Multiple files, one match, match entire lines flag",
183
+ pattern: "But I beseech your grace that I may know",
184
+ flags: []string{"-x"},
185
+ files: []string{"iliad.txt", "midsummer-night.txt", "paradise-lost.txt"},
186
+ expected: []string{"midsummer-night.txt:But I beseech your grace that I may know"},
187
+ },
188
+ {
189
+ description: "Multiple files, one match, multiple flags",
190
+ pattern: "WITH LOSS OF EDEN, TILL ONE GREATER MAN",
191
+ flags: []string{"-n", "-i", "-x"},
192
+ files: []string{"iliad.txt", "midsummer-night.txt", "paradise-lost.txt"},
193
+ expected: []string{"paradise-lost.txt:4:With loss of Eden, till one greater Man"},
194
+ },
195
+ {
196
+ description: "Multiple files, no matches, various flags",
197
+ pattern: "Frodo",
198
+ flags: []string{"-n", "-l", "-x", "-i"},
199
+ files: []string{"iliad.txt", "midsummer-night.txt", "paradise-lost.txt"},
200
+ expected: []string{},
201
+ },
202
+ }