trackler 2.0.6.40 → 2.0.6.41

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/common/exercises/book-store/canonical-data.json +7 -1
  3. data/common/exercises/rotational-cipher/{cannonical-data.json → canonical-data.json} +0 -0
  4. data/lib/trackler/version.rb +1 -1
  5. data/tracks/c/config.json +9 -0
  6. data/tracks/c/exercises/triangle/makefile +16 -0
  7. data/tracks/c/exercises/triangle/src/example.c +33 -0
  8. data/tracks/c/exercises/triangle/src/example.h +15 -0
  9. data/tracks/c/exercises/triangle/src/triangle.h +10 -0
  10. data/tracks/c/exercises/triangle/test/test_triangle.c +121 -0
  11. data/tracks/c/exercises/triangle/test/vendor/unity.c +1300 -0
  12. data/tracks/c/exercises/triangle/test/vendor/unity.h +274 -0
  13. data/tracks/c/exercises/triangle/test/vendor/unity_internals.h +701 -0
  14. data/tracks/clojure/.gitignore +1 -0
  15. data/tracks/clojure/_src/clock_generator.clj +5 -0
  16. data/tracks/clojure/_src/generator.clj +72 -0
  17. data/tracks/clojure/config.json +6 -0
  18. data/tracks/clojure/exercises/clock/clock.mustache +34 -0
  19. data/tracks/clojure/exercises/clock/project.clj +4 -0
  20. data/tracks/clojure/exercises/clock/src/example.clj +19 -0
  21. data/tracks/clojure/exercises/clock/test/clock_test.clj +177 -0
  22. data/tracks/clojure/project.clj +4 -1
  23. data/tracks/csharp/exercises/poker/Example.cs +1 -1
  24. data/tracks/csharp/exercises/poker/PokerTest.cs +10 -0
  25. data/tracks/erlang/docs/INSTALLATION.md +14 -3
  26. data/tracks/erlang/docs/LEARNING.md +1 -0
  27. data/tracks/go/exercises/gigasecond/gigasecond_test.go +5 -2
  28. data/tracks/go/exercises/grade-school/example.go +2 -0
  29. data/tracks/go/exercises/grade-school/grade_school_test.go +8 -0
  30. data/tracks/go/exercises/hamming/hamming_test.go +1 -1
  31. data/tracks/go/exercises/hello-world/hello_test.go +6 -4
  32. data/tracks/haskell/exercises/accumulate/src/Accumulate.hs +1 -1
  33. data/tracks/haskell/exercises/anagram/src/Anagram.hs +1 -1
  34. data/tracks/java/bin/journey-test.sh +21 -4
  35. data/tracks/java/exercises/allergies/src/example/java/Allergen.java +20 -0
  36. data/tracks/java/exercises/hamming/src/test/java/HammingTest.java +10 -3
  37. data/tracks/java/exercises/luhn/src/example/java/LuhnValidator.java +19 -11
  38. data/tracks/java/exercises/luhn/src/test/java/LuhnValidatorTest.java +43 -1
  39. data/tracks/java/exercises/meetup/src/example/java/MeetupSchedule.java +8 -0
  40. data/tracks/java/exercises/meetup/src/test/java/MeetupTest.java +91 -91
  41. data/tracks/java/exercises/perfect-numbers/src/example/java/Classification.java +5 -0
  42. data/tracks/java/exercises/robot-simulator/src/example/java/GridPosition.java +29 -0
  43. data/tracks/java/exercises/robot-simulator/src/example/java/Orientation.java +5 -0
  44. data/tracks/java/exercises/secret-handshake/src/example/java/Signal.java +5 -0
  45. data/tracks/java/exercises/sublist/src/example/java/Relationship.java +5 -0
  46. data/tracks/java/exercises/triangle/src/example/java/TriangleException.java +5 -0
  47. data/tracks/java/exercises/triangle/src/example/java/TriangleKind.java +5 -0
  48. data/tracks/julia/config.json +10 -1
  49. data/tracks/julia/exercises/atbash-cipher/runtests.jl +36 -36
  50. data/tracks/julia/exercises/pangram/example.jl +2 -0
  51. data/tracks/julia/exercises/pangram/pangram.jl +4 -0
  52. data/tracks/julia/exercises/pangram/runtests.jl +40 -0
  53. data/tracks/perl5/exercises/bob/Example.pm +1 -1
  54. data/tracks/perl5/exercises/bob/bob.t +27 -31
  55. data/tracks/php/exercises/accumulate/accumulate_test.php +1 -1
  56. data/tracks/php/exercises/acronym/acronym_test.php +1 -1
  57. data/tracks/php/exercises/allergies/allergies_test.php +1 -1
  58. data/tracks/php/exercises/anagram/anagram_test.php +1 -1
  59. data/tracks/php/exercises/atbash-cipher/atbash-cipher_test.php +1 -1
  60. data/tracks/php/exercises/beer-song/beer-song_test.php +1 -1
  61. data/tracks/php/exercises/binary/binary_test.php +2 -2
  62. data/tracks/php/exercises/bob/bob_test.php +1 -1
  63. data/tracks/php/exercises/book-store/book-store_test.php +1 -1
  64. data/tracks/php/exercises/bowling/bowling_test.php +1 -1
  65. data/tracks/php/exercises/bracket-push/bracket-push_test.php +1 -1
  66. data/tracks/php/exercises/change/change_test.php +3 -3
  67. data/tracks/php/exercises/clock/clock_test.php +1 -1
  68. data/tracks/php/exercises/connect/connect_test.php +1 -1
  69. data/tracks/php/exercises/difference-of-squares/difference-of-squares_test.php +1 -1
  70. data/tracks/php/exercises/etl/etl_test.php +1 -1
  71. data/tracks/php/exercises/gigasecond/gigasecond_test.php +1 -1
  72. data/tracks/php/exercises/grains/grains_test.php +1 -1
  73. data/tracks/php/exercises/hamming/hamming_test.php +2 -2
  74. data/tracks/php/exercises/hello-world/hello-world_test.php +1 -1
  75. data/tracks/php/exercises/isogram/isogram_test.php +1 -1
  76. data/tracks/php/exercises/largest-series-product/largest-series-product_test.php +1 -1
  77. data/tracks/php/exercises/leap/leap_test.php +1 -1
  78. data/tracks/php/exercises/markdown/markdown_test.php +1 -1
  79. data/tracks/php/exercises/minesweeper/minesweeper_test.php +7 -7
  80. data/tracks/php/exercises/nucleotide-count/nucleotide-count_test.php +1 -1
  81. data/tracks/php/exercises/ocr-numbers/ocr-numbers_test.php +1 -1
  82. data/tracks/php/exercises/pangram/pangram_test.php +1 -1
  83. data/tracks/php/exercises/phone-number/phone-number_test.php +1 -1
  84. data/tracks/php/exercises/pig-latin/pig-latin_test.php +1 -1
  85. data/tracks/php/exercises/raindrops/raindrops_test.php +1 -1
  86. data/tracks/php/exercises/rna-transcription/rna-transcription_test.php +1 -1
  87. data/tracks/php/exercises/robot-name/robot-name_test.php +1 -1
  88. data/tracks/php/exercises/robot-simulator/robot-simulator_test.php +1 -1
  89. data/tracks/php/exercises/roman-numerals/roman-numerals_test.php +1 -1
  90. data/tracks/php/exercises/sieve/sieve_test.php +1 -1
  91. data/tracks/php/exercises/space-age/space-age_test.php +1 -1
  92. data/tracks/php/exercises/triangle/triangle_test.php +1 -1
  93. data/tracks/php/exercises/trinary/trinary_test.php +1 -1
  94. data/tracks/php/exercises/variable-length-quantity/variable-length-quantity_test.php +3 -3
  95. data/tracks/php/exercises/word-count/word-count_test.php +1 -1
  96. data/tracks/php/exercises/wordy/wordy_test.php +3 -3
  97. data/tracks/python/config.json +3 -13
  98. data/tracks/python/exercises/rectangles/rectangles_count_test.py +15 -22
  99. data/tracks/scala/config.json +684 -665
  100. data/tracks/scala/exercises/binary-search/build.sbt +3 -0
  101. data/tracks/scala/exercises/binary-search/example.scala +23 -0
  102. data/tracks/scala/exercises/binary-search/src/main/scala/BinarySearch.scala +0 -0
  103. data/tracks/scala/exercises/binary-search/src/test/scala/BinarySearchTest.scala +63 -0
  104. data/tracks/scala/exercises/strain/build.sbt +3 -0
  105. data/tracks/scala/exercises/strain/example.scala +22 -0
  106. data/tracks/scala/exercises/strain/src/main/scala/Strain.scala +0 -0
  107. data/tracks/scala/exercises/strain/src/test/scala/StrainTest.scala +78 -0
  108. data/tracks/scala/testgen/src/main/scala/AllYourBaseTestGenerator.scala +13 -20
  109. data/tracks/scala/testgen/src/main/scala/BinarySearchTestGenerator.scala +48 -0
  110. data/tracks/scala/testgen/src/main/scala/BowlingTestGenerator.scala +24 -32
  111. data/tracks/scala/testgen/src/main/scala/CustomSetTestGenerator.scala +148 -112
  112. data/tracks/scala/testgen/src/main/scala/TestBuilder.scala +86 -0
  113. metadata +30 -3
  114. data/tracks/java/exercises/allergies/src/example/java/Allergen.java +0 -1
  115. data/tracks/java/exercises/meetup/src/example/java/MeetupSchedule.java +0 -1
  116. data/tracks/java/exercises/perfect-numbers/src/example/java/Classification.java +0 -1
  117. data/tracks/java/exercises/robot-simulator/src/example/java/GridPosition.java +0 -1
  118. data/tracks/java/exercises/robot-simulator/src/example/java/Orientation.java +0 -1
  119. data/tracks/java/exercises/secret-handshake/src/example/java/Signal.java +0 -1
  120. data/tracks/java/exercises/sublist/src/example/java/Relationship.java +0 -1
  121. data/tracks/java/exercises/triangle/src/example/java/TriangleException.java +0 -1
  122. data/tracks/java/exercises/triangle/src/example/java/TriangleKind.java +0 -1
@@ -4,6 +4,7 @@
4
4
  tmp
5
5
  bin/configlet
6
6
  bin/configlet.exe
7
+ x-common
7
8
 
8
9
  pom.xml
9
10
  pom.xml.asc
@@ -0,0 +1,5 @@
1
+ (ns clock-generator)
2
+
3
+ (defn munge-data
4
+ [test-data]
5
+ test-data)
@@ -0,0 +1,72 @@
1
+ (ns generator
2
+ (:require [cheshire.core :as json]
3
+ [clojure.java.shell :refer [sh]]
4
+ [clojure.java.io :refer [reader]]
5
+ [stencil.core :as stencil])
6
+ (:import (java.io File IOException)))
7
+
8
+ (defn file-exists?
9
+ "Helper function to determine if a given file exists."
10
+ [path]
11
+ (.exists (File. path)))
12
+
13
+ (defn warn-and-exit
14
+ "Wrapper function to warn with the given message and then exit with a non-zero return"
15
+ [message]
16
+ (println message)
17
+ (System/exit 1))
18
+
19
+ (defn clone-test-data
20
+ "Clone the x-common repo from github"
21
+ []
22
+ (sh "git" "clone" "git@github.com:exercism/x-common"))
23
+
24
+ (defn load-test-data
25
+ "Clones and loads the test data for the given exercise"
26
+ [exercise-name]
27
+ (when-not (file-exists? "x-common")
28
+ (clone-test-data))
29
+ (let [test-data-filename (format "x-common/exercises/%s/canonical-data.json" exercise-name)]
30
+ (when-not (file-exists? test-data-filename)
31
+ (warn-and-exit
32
+ (format "Could not find test data for %s (looking in %s)"
33
+ exercise-name test-data-filename)))
34
+ (json/parse-stream (reader test-data-filename))))
35
+
36
+ (defn munge-test-data
37
+ "Loads the generator namespace for the exercise and calls the munge-data function on the given test-data."
38
+ [exercise-name test-data]
39
+ (let [exercise-ns (symbol (str exercise-name "-generator"))]
40
+ (try
41
+ (require [exercise-ns])
42
+ (if-let [munge-data-fn (ns-resolve exercise-ns (symbol "munge-data"))]
43
+ (munge-data-fn test-data)
44
+ (do
45
+ (println (format "No munge-data function defined in %s" exercise-ns))
46
+ (println (format "Skipping any munging of canonical-data for %s" exercise-name))
47
+ test-data))
48
+ (catch IOException e
49
+ (println (format "Could not require %s due to an exception:\n\t%s" exercise-ns (.getMessage e)))
50
+ (println (format "Skipping any munging of canonical-data for %s" exercise-name))
51
+ test-data))))
52
+
53
+ (defn generate-test-data
54
+ "Munges the test-data and renders the test for the exercise using the test template."
55
+ [exercise-name test-template-path test-data]
56
+ (let [munged-test-data (munge-test-data exercise-name test-data)
57
+ template (slurp test-template-path)]
58
+ (spit
59
+ (format "exercises/%s/test/%s_test.clj" exercise-name exercise-name)
60
+ (stencil/render-string template munged-test-data))))
61
+
62
+ (defn -main
63
+ "Uses the test template for the exercise and test data to generate test cases."
64
+ [exercise-name & args]
65
+ (let [test-template-path (format "exercises/%s/%s.mustache" exercise-name exercise-name)
66
+ test-data (load-test-data exercise-name)]
67
+ (if (file-exists? test-template-path)
68
+ (do
69
+ (generate-test-data exercise-name test-template-path test-data)
70
+ (println (format "Generated tests for %s exercise using template %s" exercise-name test-template-path)))
71
+ (warn-and-exit (format "No exercise test template found at '%s'" test-template-path))))
72
+ (shutdown-agents))
@@ -7,6 +7,7 @@
7
7
 
8
8
  ],
9
9
  "ignored": [
10
+ "_src",
10
11
  "_test",
11
12
  "docs",
12
13
  "target",
@@ -61,6 +62,11 @@
61
62
  "slug": "phone-number",
62
63
  "topics": []
63
64
  },
65
+ {
66
+ "difficulty": 1,
67
+ "slug": "clock",
68
+ "topics": []
69
+ },
64
70
  {
65
71
  "difficulty": 1,
66
72
  "slug": "grade-school",
@@ -0,0 +1,34 @@
1
+ (ns clock-test
2
+ (:require [clock :refer :all]
3
+ [clojure.test :refer [deftest testing is]]))
4
+
5
+ (deftest create-clock-test
6
+ {{#create}}
7
+ {{#cases}}
8
+
9
+ (testing "{{{description}}}"
10
+ (let [test-clock (clock->string (clock {{{hour}}} {{{minute}}}))]
11
+ (is (= test-clock "{{{expected}}}")))){{/cases}}{{/create}})
12
+
13
+ (deftest add-time-test
14
+ {{#add}}
15
+ {{#cases}}
16
+
17
+ (testing "{{{description}}}"
18
+ (let [test-clock (clock->string (add-time (clock {{{hour}}} {{{minute}}}) {{{add}}}))]
19
+ (is (= test-clock "{{{expected}}}")))){{/cases}}{{/add}})
20
+
21
+ (deftest equal-clock-test
22
+ {{#equal}}
23
+ {{#cases}}
24
+ (testing "{{{description}}}"
25
+ (let [{{#clock1}}clock1 (clock {{{hour}}} {{{minute}}}){{/clock1}}
26
+ {{#clock2}}clock2 (clock {{{hour}}} {{{minute}}}){{/clock2}}]
27
+ {{#expected}}
28
+ (is (= clock1 clock2))))
29
+ {{/expected}}
30
+ {{^expected}}
31
+ (is (not= clock1 clock2))))
32
+ {{/expected}}
33
+ {{/cases}}
34
+ {{/equal}})
@@ -0,0 +1,4 @@
1
+ (defproject clock "0.1.0-SNAPSHOT"
2
+ :description "clock exercise."
3
+ :url "https://github.com/exercism/xclojure/tree/master/exercises/clock"
4
+ :dependencies [[org.clojure/clojure "1.8.0"]])
@@ -0,0 +1,19 @@
1
+ (ns clock)
2
+
3
+ (defn clock
4
+ "Return a 24 hour clock representation of the given hours and minutes."
5
+ [in-hour in-minute]
6
+ (let [total-minutes (mod (+ (* in-hour 60) in-minute) (* 60 24))
7
+ hours (mod (quot total-minutes 60) 24)
8
+ minutes (mod total-minutes 60)]
9
+ {:hour hours :minute minutes}))
10
+
11
+ (defn clock->string
12
+ "Print the HH:MM representation of a clock."
13
+ [in-clock]
14
+ (format "%02d:%02d" (:hour in-clock) (:minute in-clock)))
15
+
16
+ (defn add-time
17
+ "Add minutes to the given clock."
18
+ [in-clock minutes-to-add]
19
+ (clock (:hour in-clock) (+ (:minute in-clock) minutes-to-add)))
@@ -0,0 +1,177 @@
1
+ (ns clock-test
2
+ (:require [clock :refer :all]
3
+ [clojure.test :refer [deftest testing is]]))
4
+
5
+ (deftest create-clock-test
6
+
7
+ (testing "on the hour"
8
+ (let [test-clock (clock->string (clock 8 0))]
9
+ (is (= test-clock "08:00"))))
10
+ (testing "past the hour"
11
+ (let [test-clock (clock->string (clock 11 9))]
12
+ (is (= test-clock "11:09"))))
13
+ (testing "midnight is zero hours"
14
+ (let [test-clock (clock->string (clock 24 0))]
15
+ (is (= test-clock "00:00"))))
16
+ (testing "hour rolls over"
17
+ (let [test-clock (clock->string (clock 25 0))]
18
+ (is (= test-clock "01:00"))))
19
+ (testing "hour rolls over continuously"
20
+ (let [test-clock (clock->string (clock 100 0))]
21
+ (is (= test-clock "04:00"))))
22
+ (testing "sixty minutes is next hour"
23
+ (let [test-clock (clock->string (clock 1 60))]
24
+ (is (= test-clock "02:00"))))
25
+ (testing "minutes roll over"
26
+ (let [test-clock (clock->string (clock 0 160))]
27
+ (is (= test-clock "02:40"))))
28
+ (testing "minutes roll over continuously"
29
+ (let [test-clock (clock->string (clock 0 1723))]
30
+ (is (= test-clock "04:43"))))
31
+ (testing "hour and minutes roll over"
32
+ (let [test-clock (clock->string (clock 25 160))]
33
+ (is (= test-clock "03:40"))))
34
+ (testing "hour and minutes roll over continuously"
35
+ (let [test-clock (clock->string (clock 201 3001))]
36
+ (is (= test-clock "11:01"))))
37
+ (testing "hour and minutes roll over to exactly midnight"
38
+ (let [test-clock (clock->string (clock 72 8640))]
39
+ (is (= test-clock "00:00"))))
40
+ (testing "negative hour"
41
+ (let [test-clock (clock->string (clock -1 15))]
42
+ (is (= test-clock "23:15"))))
43
+ (testing "negative hour rolls over"
44
+ (let [test-clock (clock->string (clock -25 0))]
45
+ (is (= test-clock "23:00"))))
46
+ (testing "negative hour rolls over continuously"
47
+ (let [test-clock (clock->string (clock -91 0))]
48
+ (is (= test-clock "05:00"))))
49
+ (testing "negative minutes"
50
+ (let [test-clock (clock->string (clock 1 -40))]
51
+ (is (= test-clock "00:20"))))
52
+ (testing "negative minutes roll over"
53
+ (let [test-clock (clock->string (clock 1 -160))]
54
+ (is (= test-clock "22:20"))))
55
+ (testing "negative minutes roll over continuously"
56
+ (let [test-clock (clock->string (clock 1 -4820))]
57
+ (is (= test-clock "16:40"))))
58
+ (testing "negative hour and minutes both roll over"
59
+ (let [test-clock (clock->string (clock -25 -160))]
60
+ (is (= test-clock "20:20"))))
61
+ (testing "negative hour and minutes both roll over continuously"
62
+ (let [test-clock (clock->string (clock -121 -5810))]
63
+ (is (= test-clock "22:10")))))
64
+
65
+ (deftest add-time-test
66
+
67
+ (testing "add minutes"
68
+ (let [test-clock (clock->string (add-time (clock 10 0) 3))]
69
+ (is (= test-clock "10:03"))))
70
+ (testing "add no minutes"
71
+ (let [test-clock (clock->string (add-time (clock 6 41) 0))]
72
+ (is (= test-clock "06:41"))))
73
+ (testing "add to next hour"
74
+ (let [test-clock (clock->string (add-time (clock 0 45) 40))]
75
+ (is (= test-clock "01:25"))))
76
+ (testing "add more than one hour"
77
+ (let [test-clock (clock->string (add-time (clock 10 0) 61))]
78
+ (is (= test-clock "11:01"))))
79
+ (testing "add more than two hours with carry"
80
+ (let [test-clock (clock->string (add-time (clock 0 45) 160))]
81
+ (is (= test-clock "03:25"))))
82
+ (testing "add across midnight"
83
+ (let [test-clock (clock->string (add-time (clock 23 59) 2))]
84
+ (is (= test-clock "00:01"))))
85
+ (testing "add more than one day (1500 min = 25 hrs)"
86
+ (let [test-clock (clock->string (add-time (clock 5 32) 1500))]
87
+ (is (= test-clock "06:32"))))
88
+ (testing "add more than two days"
89
+ (let [test-clock (clock->string (add-time (clock 1 1) 3500))]
90
+ (is (= test-clock "11:21"))))
91
+ (testing "subtract minutes"
92
+ (let [test-clock (clock->string (add-time (clock 10 3) -3))]
93
+ (is (= test-clock "10:00"))))
94
+ (testing "subtract to previous hour"
95
+ (let [test-clock (clock->string (add-time (clock 10 3) -30))]
96
+ (is (= test-clock "09:33"))))
97
+ (testing "subtract more than an hour"
98
+ (let [test-clock (clock->string (add-time (clock 10 3) -70))]
99
+ (is (= test-clock "08:53"))))
100
+ (testing "subtract across midnight"
101
+ (let [test-clock (clock->string (add-time (clock 0 3) -4))]
102
+ (is (= test-clock "23:59"))))
103
+ (testing "subtract more than two hours"
104
+ (let [test-clock (clock->string (add-time (clock 0 0) -160))]
105
+ (is (= test-clock "21:20"))))
106
+ (testing "subtract more than two hours with borrow"
107
+ (let [test-clock (clock->string (add-time (clock 6 15) -160))]
108
+ (is (= test-clock "03:35"))))
109
+ (testing "subtract more than one day (1500 min = 25 hrs)"
110
+ (let [test-clock (clock->string (add-time (clock 5 32) -1500))]
111
+ (is (= test-clock "04:32"))))
112
+ (testing "subtract more than two days"
113
+ (let [test-clock (clock->string (add-time (clock 2 20) -3000))]
114
+ (is (= test-clock "00:20")))))
115
+
116
+ (deftest equal-clock-test
117
+ (testing "clocks with same time"
118
+ (let [clock1 (clock 15 37)
119
+ clock2 (clock 15 37)]
120
+ (is (= clock1 clock2))))
121
+ (testing "clocks a minute apart"
122
+ (let [clock1 (clock 15 36)
123
+ clock2 (clock 15 37)]
124
+ (is (not= clock1 clock2))))
125
+ (testing "clocks an hour apart"
126
+ (let [clock1 (clock 14 37)
127
+ clock2 (clock 15 37)]
128
+ (is (not= clock1 clock2))))
129
+ (testing "clocks with hour overflow"
130
+ (let [clock1 (clock 10 37)
131
+ clock2 (clock 34 37)]
132
+ (is (= clock1 clock2))))
133
+ (testing "clocks with hour overflow by several days"
134
+ (let [clock1 (clock 3 11)
135
+ clock2 (clock 99 11)]
136
+ (is (= clock1 clock2))))
137
+ (testing "clocks with negative hour"
138
+ (let [clock1 (clock 22 40)
139
+ clock2 (clock -2 40)]
140
+ (is (= clock1 clock2))))
141
+ (testing "clocks with negative hour that wraps"
142
+ (let [clock1 (clock 17 3)
143
+ clock2 (clock -31 3)]
144
+ (is (= clock1 clock2))))
145
+ (testing "clocks with negative hour that wraps multiple times"
146
+ (let [clock1 (clock 13 49)
147
+ clock2 (clock -83 49)]
148
+ (is (= clock1 clock2))))
149
+ (testing "clocks with minute overflow"
150
+ (let [clock1 (clock 0 1)
151
+ clock2 (clock 0 1441)]
152
+ (is (= clock1 clock2))))
153
+ (testing "clocks with minute overflow by several days"
154
+ (let [clock1 (clock 2 2)
155
+ clock2 (clock 2 4322)]
156
+ (is (= clock1 clock2))))
157
+ (testing "clocks with negative minute"
158
+ (let [clock1 (clock 2 40)
159
+ clock2 (clock 3 -20)]
160
+ (is (= clock1 clock2))))
161
+ (testing "clocks with negative minute that wraps"
162
+ (let [clock1 (clock 4 10)
163
+ clock2 (clock 5 -1490)]
164
+ (is (= clock1 clock2))))
165
+ (testing "clocks with negative minute that wraps multiple times"
166
+ (let [clock1 (clock 6 15)
167
+ clock2 (clock 6 -4305)]
168
+ (is (= clock1 clock2))))
169
+ (testing "clocks with negative hours and minutes"
170
+ (let [clock1 (clock 7 32)
171
+ clock2 (clock -12 -268)]
172
+ (is (= clock1 clock2))))
173
+ (testing "clocks with negative hours and minutes that wrap"
174
+ (let [clock1 (clock 18 7)
175
+ clock2 (clock -54 -11513)]
176
+ (is (= clock1 clock2))))
177
+ )
@@ -2,5 +2,8 @@
2
2
  :description "Exercism Exercises in Clojure"
3
3
  :url "https://github.com/exercism/xclojure"
4
4
  :test-paths ["_test"]
5
+ :source-paths ["_src"]
6
+ :aliases {"generate" ["run" "-m" "generator"]}
5
7
  :dependencies [[org.clojure/clojure "1.8.0"]
6
- [cheshire "5.5.0"]])
8
+ [cheshire "5.5.0"]
9
+ [stencil "0.5.0"]])
@@ -52,7 +52,7 @@ public static class Poker
52
52
 
53
53
  if (ranks.SequenceEqual(new[] { 14, 5, 4, 3, 2 }))
54
54
  {
55
- ranks = new[] { 1, 2, 3, 4, 5 };
55
+ ranks = new[] { 5, 4, 3, 2, 1 };
56
56
  }
57
57
 
58
58
  var flush = suits.Distinct().Count() == 1;
@@ -168,4 +168,14 @@ public class PokerTest
168
168
  Assert.That(Poker.BestHands(new[] { spadeStraightTo9, diamondStraightTo9, threeOf4 }),
169
169
  Is.EqualTo(new[] { spadeStraightTo9, diamondStraightTo9 }));
170
170
  }
171
+
172
+ [Ignore("Remove to run test")]
173
+ [Test]
174
+ public void Straight_to_5_against_a_pair_of_jacks()
175
+ {
176
+ const string straightTo5 = "2S 4D 5C 3S AS";
177
+ const string twoJacks = "JD 8D 7D JC 5D";
178
+ Assert.That(Poker.BestHands(new[] { straightTo5, twoJacks }),
179
+ Is.EqualTo(new[] { straightTo5 }));
180
+ }
171
181
  }
@@ -1,3 +1,6 @@
1
+ If you have any trouble installing erlang please consider joining the
2
+ [gitter support channel](https://gitter.im/exercism/xerlang)
3
+
1
4
  ### Homebrew for Mac OS X
2
5
 
3
6
  Update your Homebrew to latest:
@@ -18,8 +21,15 @@ via `brew` are welcome).
18
21
 
19
22
  ### On Linux
20
23
 
21
- Fedora 17+ and Fedora Rawhide: `sudo yum -y install erlang`
22
- Arch Linux : Erlang is available on AUR via `yaourt -S erlang`
24
+ * Fedora 17+ and Fedora Rawhide: `sudo yum -y install erlang`
25
+ * Arch Linux: Erlang is available on AUR via `yaourt -S erlang`
26
+ * Ubuntu/Debian: `sudo apt-get install erlang`
27
+
28
+ It may happen that the packages above are dated. At least for ubuntu 16.04
29
+ it should still be able to run the tests. If your package gets to old (older
30
+ than OTP 17.0) please consider a build from source or using [`kerl`](https://github.com/kerl/kerl)
31
+ or [`asdf-vm`](https://github.com/asdf-vm/asdf) and [`asdf-erlang`](https://github.com/asdf-vm/asdf-erlang)
32
+ instead (follow installation instructions in the corresponding repositories).
23
33
 
24
34
  Also fetch the latest `rebar3` from rebar3.org and put it somewhere in
25
35
  your `$PATH` and make it executable. (PRs that describe this better or
@@ -37,4 +47,5 @@ choco install rebar3
37
47
 
38
48
  ### Installing from Source
39
49
 
40
- Get [Erlang OTP 17.1](http://www.erlang.org/download.html)
50
+ Get [a recent Erlang OTP](http://www.erlang.org/download.html) and follow their
51
+ [build-instructions](https://github.com/erlang/otp/blob/maint/HOWTO/INSTALL.md).
@@ -1,5 +1,6 @@
1
1
  Exercism provides exercises and feedback but can be difficult to jump into for those learning Erlang for the first time. These resources can help you get started:
2
2
 
3
+ * [Exercism related BEAM support channel on gitter](https://gitter.im/exercism/xerlang)
3
4
  * [Erlang Documentation](http://www.erlang.org/doc.html)
4
5
  * [Learn You Some Erlang for Great Good](http://learnyousomeerlang.com)
5
6
  * [StackOverflow](http://stackoverflow.com/)
@@ -16,10 +16,13 @@ const (
16
16
  fmtDT = "2006-01-02T15:04:05"
17
17
  )
18
18
 
19
- func TestAddGigasecond(t *testing.T) {
19
+ func TestTestVersion(t *testing.T) {
20
20
  if testVersion != targetTestVersion {
21
- t.Fatalf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
21
+ t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
22
22
  }
23
+ }
24
+
25
+ func TestAddGigasecond(t *testing.T) {
23
26
  for _, tc := range addCases {
24
27
  in := parse(tc.in, t)
25
28
  want := parse(tc.want, t)
@@ -2,6 +2,8 @@ package school
2
2
 
3
3
  import "sort"
4
4
 
5
+ const testVersion = 1
6
+
5
7
  type School map[int][]string
6
8
 
7
9
  func New() *School {
@@ -19,6 +19,14 @@ import (
19
19
  "testing"
20
20
  )
21
21
 
22
+ const targetTestVersion = 1
23
+
24
+ func TestTestVersion(t *testing.T) {
25
+ if testVersion != targetTestVersion {
26
+ t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
27
+ }
28
+ }
29
+
22
30
  func TestNewSchoolIsEmpty(t *testing.T) {
23
31
  if len(New().Enrollment()) != 0 {
24
32
  t.Error("New school not empty")
@@ -6,7 +6,7 @@ const targetTestVersion = 5
6
6
 
7
7
  func TestTestVersion(t *testing.T) {
8
8
  if testVersion != targetTestVersion {
9
- t.Errorf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
9
+ t.Fatalf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
10
10
  }
11
11
  }
12
12
 
@@ -9,6 +9,12 @@ import "testing"
9
9
 
10
10
  const targetTestVersion = 3
11
11
 
12
+ func TestTestVersion(t *testing.T) {
13
+ if testVersion != targetTestVersion {
14
+ t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
15
+ }
16
+ }
17
+
12
18
  func TestHelloWorld(t *testing.T) {
13
19
  tests := []struct {
14
20
  name, expected string
@@ -22,8 +28,4 @@ func TestHelloWorld(t *testing.T) {
22
28
  t.Fatalf("HelloWorld(%s) = %v, want %v", test.name, observed, test.expected)
23
29
  }
24
30
  }
25
-
26
- if testVersion != targetTestVersion {
27
- t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
28
- }
29
31
  }
@@ -1,4 +1,4 @@
1
1
  module Accumulate (accumulate) where
2
2
 
3
3
  accumulate :: (a -> b) -> [a] -> [b]
4
- accumulate = error "You need to implement this function."
4
+ accumulate f xs = error "You need to implement this function."
@@ -1,4 +1,4 @@
1
1
  module Anagram (anagramsFor) where
2
2
 
3
3
  anagramsFor :: String -> [String] -> [String]
4
- anagramsFor = error "You need to implement this function."
4
+ anagramsFor xs xss = error "You need to implement this function."
@@ -72,6 +72,8 @@ get_operating_system() {
72
72
  echo "linux";;
73
73
  (Windows*)
74
74
  echo "windows";;
75
+ (MINGW*)
76
+ echo "windows";;
75
77
  (*)
76
78
  echo "linux";;
77
79
  esac
@@ -102,10 +104,25 @@ download_exercism_cli() {
102
104
  # "curl..." :: HTTP 302 headers, including "Location" -- URL to redirect to.
103
105
  # "awk..." :: pluck last path segment from "Location" (i.e. the version number)
104
106
  local version="$(curl --head --silent ${latest} | awk -v FS=/ '/Location:/{print $NF}' | tr -d '\r')"
105
- local download_url=${CLI_RELEASES}/download/${version}/exercism-${os}-${arch}.tgz
107
+
108
+ local download_url_suffix
109
+ local unzip_command
110
+ local unzip_from_file_option
111
+ if [[ ${os} == "windows" ]] ; then
112
+ download_url_suffix="zip"
113
+ unzip_command="unzip -d"
114
+ unzip_from_file_option=""
115
+ else
116
+ download_url_suffix="tgz"
117
+ unzip_command="tar xz -C"
118
+ unzip_from_file_option="-f"
119
+ fi
120
+ local download_url=${CLI_RELEASES}/download/${version}/exercism-${os}-${arch}.${download_url_suffix}
106
121
 
107
122
  mkdir -p ${exercism_home}
108
- curl -s --location ${download_url} | tar xz -C ${exercism_home}
123
+ local temp=`mktemp`
124
+ curl -s --location ${download_url} > ${temp}
125
+ ${unzip_command} ${exercism_home} ${unzip_from_file_option} ${temp}
109
126
  echo "<<< download_exercism_cli()"
110
127
  }
111
128
 
@@ -192,8 +209,8 @@ solve_all_exercises() {
192
209
 
193
210
  local xjava=$( pwd )
194
211
  local exercism_cli="./exercism --config ${exercism_configfile}"
195
- local exercises=`cat config.json | jq '.problems []' --raw-output`
196
- local total_exercises=`cat config.json | jq '.problems | length'`
212
+ local exercises=`cat config.json | jq '.exercises[].slug + " "' --join-output`
213
+ local total_exercises=`cat config.json | jq '.exercises | length'`
197
214
  local current_exercise_number=1
198
215
  local tempfile="${TMPDIR:-/tmp}/journey-test.sh-unignore_all_tests.txt"
199
216
 
@@ -0,0 +1,20 @@
1
+ public enum Allergen {
2
+ EGGS(1),
3
+ PEANUTS(2),
4
+ SHELLFISH(4),
5
+ STRAWBERRIES(8),
6
+ TOMATOES(16),
7
+ CHOCOLATE(32),
8
+ POLLEN(64),
9
+ CATS(128);
10
+
11
+ private final int score;
12
+
13
+ Allergen(int score) {
14
+ this.score = score;
15
+ }
16
+
17
+ public int getScore() {
18
+ return score;
19
+ }
20
+ }
@@ -3,10 +3,15 @@ import static org.junit.Assert.*;
3
3
 
4
4
  import org.junit.Test;
5
5
  import org.junit.Ignore;
6
+ import org.junit.Rule;
7
+ import org.junit.rules.ExpectedException;
6
8
 
7
9
  public class HammingTest {
8
10
 
9
11
 
12
+ @Rule
13
+ public ExpectedException thrown = ExpectedException.none();
14
+
10
15
  @Test
11
16
  public void testNoDifferenceBetweenIdenticalStrands() {
12
17
  assertThat(Hamming.compute("A", "A"), is(0));
@@ -37,14 +42,16 @@ public class HammingTest {
37
42
  }
38
43
 
39
44
  @Ignore
40
- @Test(expected = IllegalArgumentException.class)
45
+ @Test
41
46
  public void testValidatesFirstStrandNotLonger() {
42
- Hamming.compute("AAAG", "AAA");
47
+ thrown.expect(IllegalArgumentException.class);
48
+ Hamming.compute("AAAG", "AAA");
43
49
  }
44
50
 
45
51
  @Ignore
46
- @Test(expected = IllegalArgumentException.class)
52
+ @Test
47
53
  public void testValidatesOtherStrandNotLonger() {
54
+ thrown.expect(IllegalArgumentException.class);
48
55
  Hamming.compute("AAA", "AAAG");
49
56
  }
50
57
 
@@ -9,10 +9,17 @@ final class LuhnValidator {
9
9
  boolean isValid(final String candidate) {
10
10
  final String sanitizedCandidate = SPACE_PATTERN.matcher(candidate).replaceAll("");
11
11
 
12
+ if (sanitizedCandidate.length() <= 1) {
13
+ return false;
14
+ }
15
+
16
+ // We need to alter every second digit counting from the right. Reversing makes this easy!
17
+ final String reversedSanitizedCandidate = reverse(sanitizedCandidate);
18
+
12
19
  final List<Integer> computedDigits = new ArrayList<>();
13
20
 
14
- for (int charIndex = 0; charIndex < sanitizedCandidate.length(); charIndex++) {
15
- int inputDigit = Character.digit(sanitizedCandidate.charAt(charIndex), 10);
21
+ for (int charIndex = 0; charIndex < reversedSanitizedCandidate.length(); charIndex++) {
22
+ int inputDigit = Character.digit(reversedSanitizedCandidate.charAt(charIndex), 10);
16
23
 
17
24
  /*
18
25
  * Character.digit returns a negative int if the supplied character does not represent a digit with respect
@@ -23,21 +30,22 @@ final class LuhnValidator {
23
30
  }
24
31
 
25
32
  if (charIndex % 2 == 1) {
26
- /*
27
- * Since our doubled input digit must lie in [2, 18], the operation
28
- *
29
- * "subtract 9 from the doubled input digit if it exceeds 9 in value"
30
- *
31
- * is equivalent to applying the modulo operation below universally.
32
- */
33
- inputDigit = (2 * inputDigit) % 9;
33
+ inputDigit = 2 * inputDigit;
34
+
35
+ if (inputDigit > 9) {
36
+ inputDigit -= 9;
37
+ }
34
38
  }
35
39
 
36
40
  computedDigits.add(inputDigit);
37
41
  }
38
42
 
39
43
  final int digitSum = computedDigits.stream().mapToInt(Integer::intValue).sum();
40
- return digitSum > 0 && digitSum % 10 == 0;
44
+ return digitSum % 10 == 0;
45
+ }
46
+
47
+ private String reverse(final String string) {
48
+ return new StringBuilder(string).reverse().toString();
41
49
  }
42
50
 
43
51
  }