trackler 2.0.0.8 → 2.0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (226) hide show
  1. checksums.yaml +4 -4
  2. data/common/exercises/bob/canonical-data.json +1 -20
  3. data/common/exercises/raindrops/canonical-data.json +18 -0
  4. data/common/exercises/sublist/canonical-data.json +5 -0
  5. data/lib/trackler/version.rb +1 -1
  6. data/tracks/clojure/config.json +5 -0
  7. data/tracks/clojure/exercises/pig-latin/project.clj +4 -0
  8. data/tracks/clojure/exercises/pig-latin/src/example.clj +49 -0
  9. data/tracks/clojure/exercises/pig-latin/test/pig_latin_test.clj +92 -0
  10. data/tracks/clojure/exercises/robot-name/src/example.clj +8 -11
  11. data/tracks/clojure/exercises/robot-name/test/robot_name_test.clj +23 -18
  12. data/tracks/crystal/config.json +6 -0
  13. data/tracks/crystal/exercises/acronym/spec/acronym_spec.cr +7 -7
  14. data/tracks/crystal/exercises/forth/spec/forth_spec.cr +198 -0
  15. data/tracks/crystal/exercises/forth/src/example.cr +187 -0
  16. data/tracks/crystal/exercises/hello-world/spec/hello_world_spec.cr +3 -3
  17. data/tracks/crystal/src/generator/exercises/acronym.cr +1 -1
  18. data/tracks/crystal/src/generator/exercises/exercise_generator.cr +3 -2
  19. data/tracks/crystal/src/generator/exercises/forth.cr +56 -0
  20. data/tracks/crystal/src/generator/exercises/templates/example.tt +2 -2
  21. data/tracks/crystal/src/generator/spec/exercise_generator_spec.cr +5 -3
  22. data/tracks/csharp/exercises/wordy/WordyTest.cs +2 -2
  23. data/tracks/elixir/config.json +83 -70
  24. data/tracks/fsharp/exercises/wordy/WordyTest.fs +1 -1
  25. data/tracks/go/config.json +28 -3
  26. data/tracks/go/exercises/all-your-base/all_your_base_test.go +185 -0
  27. data/tracks/go/exercises/all-your-base/example.go +60 -0
  28. data/tracks/go/exercises/isogram/example.go +15 -0
  29. data/tracks/go/exercises/isogram/isogram_test.go +50 -0
  30. data/tracks/go/exercises/ledger/ledger.go +2 -2
  31. data/tracks/go/exercises/pangram/example.go +32 -0
  32. data/tracks/go/exercises/pangram/pangram_test.go +43 -0
  33. data/tracks/go/exercises/protein-translation/example.go +59 -0
  34. data/tracks/go/exercises/protein-translation/protein_translation_test.go +69 -0
  35. data/tracks/go/exercises/tree-building/tree_building.go +1 -1
  36. data/tracks/go/exercises/twelve-days/example.go +57 -0
  37. data/tracks/go/exercises/twelve-days/twelve_days_test.go +79 -0
  38. data/tracks/haskell/.travis.yml +13 -8
  39. data/tracks/haskell/config.json +6 -0
  40. data/tracks/haskell/exercises/accumulate/stack.yaml +1 -1
  41. data/tracks/haskell/exercises/all-your-base/stack.yaml +1 -1
  42. data/tracks/haskell/exercises/allergies/stack.yaml +1 -1
  43. data/tracks/haskell/exercises/alphametics/stack.yaml +1 -1
  44. data/tracks/haskell/exercises/anagram/stack.yaml +1 -1
  45. data/tracks/haskell/exercises/atbash-cipher/stack.yaml +1 -1
  46. data/tracks/haskell/exercises/bank-account/stack.yaml +1 -1
  47. data/tracks/haskell/exercises/beer-song/stack.yaml +1 -1
  48. data/tracks/haskell/exercises/binary/stack.yaml +1 -1
  49. data/tracks/haskell/exercises/binary-search-tree/stack.yaml +1 -1
  50. data/tracks/haskell/exercises/bob/stack.yaml +1 -1
  51. data/tracks/haskell/exercises/bowling/HINTS.md +19 -0
  52. data/tracks/haskell/exercises/bowling/examples/success-standard/package.yaml +16 -0
  53. data/tracks/haskell/exercises/bowling/examples/success-standard/src/Bowling.hs +84 -0
  54. data/tracks/haskell/exercises/bowling/package.yaml +19 -0
  55. data/tracks/haskell/exercises/bowling/src/Bowling.hs +9 -0
  56. data/tracks/haskell/exercises/bowling/stack.yaml +1 -0
  57. data/tracks/haskell/exercises/bowling/test/Tests.hs +143 -0
  58. data/tracks/haskell/exercises/change/stack.yaml +1 -1
  59. data/tracks/haskell/exercises/clock/stack.yaml +1 -1
  60. data/tracks/haskell/exercises/connect/stack.yaml +1 -1
  61. data/tracks/haskell/exercises/crypto-square/stack.yaml +1 -1
  62. data/tracks/haskell/exercises/custom-set/stack.yaml +1 -1
  63. data/tracks/haskell/exercises/difference-of-squares/stack.yaml +1 -1
  64. data/tracks/haskell/exercises/dominoes/stack.yaml +1 -1
  65. data/tracks/haskell/exercises/etl/stack.yaml +1 -1
  66. data/tracks/haskell/exercises/food-chain/stack.yaml +1 -1
  67. data/tracks/haskell/exercises/forth/stack.yaml +1 -1
  68. data/tracks/haskell/exercises/gigasecond/stack.yaml +1 -1
  69. data/tracks/haskell/exercises/go-counting/stack.yaml +1 -1
  70. data/tracks/haskell/exercises/grade-school/stack.yaml +1 -1
  71. data/tracks/haskell/exercises/grains/stack.yaml +1 -1
  72. data/tracks/haskell/exercises/hamming/stack.yaml +1 -1
  73. data/tracks/haskell/exercises/hexadecimal/stack.yaml +1 -1
  74. data/tracks/haskell/exercises/house/stack.yaml +1 -1
  75. data/tracks/haskell/exercises/kindergarten-garden/stack.yaml +1 -1
  76. data/tracks/haskell/exercises/largest-series-product/stack.yaml +1 -1
  77. data/tracks/haskell/exercises/leap/stack.yaml +1 -1
  78. data/tracks/haskell/exercises/lens-person/stack.yaml +1 -1
  79. data/tracks/haskell/exercises/linked-list/stack.yaml +1 -1
  80. data/tracks/haskell/exercises/list-ops/stack.yaml +1 -1
  81. data/tracks/haskell/exercises/luhn/stack.yaml +1 -1
  82. data/tracks/haskell/exercises/matrix/stack.yaml +1 -1
  83. data/tracks/haskell/exercises/meetup/stack.yaml +1 -1
  84. data/tracks/haskell/exercises/minesweeper/stack.yaml +1 -1
  85. data/tracks/haskell/exercises/nth-prime/stack.yaml +1 -1
  86. data/tracks/haskell/exercises/nucleotide-count/stack.yaml +1 -1
  87. data/tracks/haskell/exercises/ocr-numbers/stack.yaml +1 -1
  88. data/tracks/haskell/exercises/octal/stack.yaml +1 -1
  89. data/tracks/haskell/exercises/palindrome-products/stack.yaml +1 -1
  90. data/tracks/haskell/exercises/parallel-letter-frequency/stack.yaml +1 -1
  91. data/tracks/haskell/exercises/pascals-triangle/stack.yaml +1 -1
  92. data/tracks/haskell/exercises/phone-number/stack.yaml +1 -1
  93. data/tracks/haskell/exercises/pig-latin/stack.yaml +1 -1
  94. data/tracks/haskell/exercises/pov/stack.yaml +1 -1
  95. data/tracks/haskell/exercises/prime-factors/stack.yaml +1 -1
  96. data/tracks/haskell/exercises/pythagorean-triplet/stack.yaml +1 -1
  97. data/tracks/haskell/exercises/queen-attack/stack.yaml +1 -1
  98. data/tracks/haskell/exercises/raindrops/stack.yaml +1 -1
  99. data/tracks/haskell/exercises/rna-transcription/stack.yaml +1 -1
  100. data/tracks/haskell/exercises/robot-name/stack.yaml +1 -1
  101. data/tracks/haskell/exercises/robot-simulator/stack.yaml +1 -1
  102. data/tracks/haskell/exercises/roman-numerals/stack.yaml +1 -1
  103. data/tracks/haskell/exercises/saddle-points/stack.yaml +1 -1
  104. data/tracks/haskell/exercises/say/stack.yaml +1 -1
  105. data/tracks/haskell/exercises/scrabble-score/stack.yaml +1 -1
  106. data/tracks/haskell/exercises/secret-handshake/stack.yaml +1 -1
  107. data/tracks/haskell/exercises/series/stack.yaml +1 -1
  108. data/tracks/haskell/exercises/sgf-parsing/stack.yaml +1 -1
  109. data/tracks/haskell/exercises/sieve/stack.yaml +1 -1
  110. data/tracks/haskell/exercises/simple-cipher/stack.yaml +1 -1
  111. data/tracks/haskell/exercises/simple-linked-list/stack.yaml +1 -1
  112. data/tracks/haskell/exercises/space-age/stack.yaml +1 -1
  113. data/tracks/haskell/exercises/strain/stack.yaml +1 -1
  114. data/tracks/haskell/exercises/sublist/stack.yaml +1 -1
  115. data/tracks/haskell/exercises/sum-of-multiples/stack.yaml +1 -1
  116. data/tracks/haskell/exercises/triangle/stack.yaml +1 -1
  117. data/tracks/haskell/exercises/trinary/stack.yaml +1 -1
  118. data/tracks/haskell/exercises/word-count/stack.yaml +1 -1
  119. data/tracks/haskell/exercises/wordy/stack.yaml +1 -1
  120. data/tracks/haskell/exercises/zebra-puzzle/stack.yaml +1 -1
  121. data/tracks/haskell/exercises/zipper/stack.yaml +1 -1
  122. data/tracks/java/config.json +13 -1
  123. data/tracks/java/exercises/etl/src/main/java/Etl.java +3 -3
  124. data/tracks/java/exercises/hello-world/GETTING_STARTED.md +1 -1
  125. data/tracks/java/exercises/hello-world/src/main/java/HelloWorld.java +3 -3
  126. data/tracks/java/exercises/minesweeper/build.gradle +17 -0
  127. data/tracks/java/exercises/minesweeper/src/example/java/MinesweeperBoard.java +111 -0
  128. data/tracks/java/exercises/minesweeper/src/main/java/MinesweeperBoard.java +5 -0
  129. data/tracks/java/exercises/minesweeper/src/test/java/MinesweeperBoardTest.java +295 -0
  130. data/tracks/java/exercises/nucleotide-count/src/test/java/NucleotideTest.java +67 -67
  131. data/tracks/java/exercises/series/build.gradle +18 -0
  132. data/tracks/java/exercises/series/src/example/java/Series.java +39 -0
  133. data/tracks/java/exercises/series/src/main/java/.keep +0 -0
  134. data/tracks/java/exercises/series/src/main/java/Series.java +3 -0
  135. data/tracks/java/exercises/series/src/test/java/.keep +0 -0
  136. data/tracks/java/exercises/series/src/test/java/SeriesTest.java +154 -0
  137. data/tracks/java/exercises/settings.gradle +2 -0
  138. data/tracks/javascript/exercises/custom-set/custom-set.spec.js +130 -84
  139. data/tracks/javascript/exercises/custom-set/example-gen.js +200 -0
  140. data/tracks/ocaml/Makefile +5 -1
  141. data/tracks/ocaml/config.json +2 -1
  142. data/tracks/ocaml/exercises/anagram/test.ml +35 -24
  143. data/tracks/ocaml/exercises/bob/example.ml +1 -1
  144. data/tracks/ocaml/exercises/bob/test.ml +53 -40
  145. data/tracks/ocaml/exercises/hamming/test.ml +41 -31
  146. data/tracks/ocaml/exercises/raindrops/test.ml +38 -39
  147. data/tracks/ocaml/tools/test-generator/.merlin +5 -0
  148. data/tracks/ocaml/tools/test-generator/Makefile +15 -0
  149. data/tracks/ocaml/tools/test-generator/_tags +0 -0
  150. data/tracks/ocaml/tools/test-generator/src/codegen.ml +17 -0
  151. data/tracks/ocaml/tools/test-generator/src/codegen.mli +7 -0
  152. data/tracks/ocaml/tools/test-generator/src/leap.json +39 -0
  153. data/tracks/ocaml/tools/test-generator/src/model.ml +31 -0
  154. data/tracks/ocaml/tools/test-generator/src/parser.ml +61 -0
  155. data/tracks/ocaml/tools/test-generator/src/parser.mli +9 -0
  156. data/tracks/ocaml/tools/test-generator/src/special_cases.ml +12 -0
  157. data/tracks/ocaml/tools/test-generator/src/special_cases.mli +7 -0
  158. data/tracks/ocaml/tools/test-generator/src/test_gen.ml +25 -0
  159. data/tracks/ocaml/tools/test-generator/src/test_generator.ml +62 -0
  160. data/tracks/ocaml/tools/test-generator/src/test_generator.mli +6 -0
  161. data/tracks/ocaml/tools/test-generator/src/utils.ml +32 -0
  162. data/tracks/ocaml/tools/test-generator/src/utils.mli +18 -0
  163. data/tracks/ocaml/tools/test-generator/templates/anagram/template.ml +17 -0
  164. data/tracks/ocaml/tools/test-generator/templates/bob/template.ml +15 -0
  165. data/tracks/ocaml/tools/test-generator/templates/hamming/template.ml +30 -0
  166. data/tracks/ocaml/tools/test-generator/templates/leap/template.ml +15 -0
  167. data/tracks/ocaml/tools/test-generator/templates/raindrops/template.ml +15 -0
  168. data/tracks/ocaml/tools/test-generator/templates/word-count/template.ml +19 -0
  169. data/tracks/ocaml/tools/test-generator/test/all_tests.ml +11 -0
  170. data/tracks/ocaml/tools/test-generator/test/codegen_test.ml +20 -0
  171. data/tracks/ocaml/tools/test-generator/test/model_test.ml +27 -0
  172. data/tracks/ocaml/tools/test-generator/test/parser_test.ml +73 -0
  173. data/tracks/ocaml/tools/test-generator/test/special_cases_test.ml +22 -0
  174. data/tracks/ocaml/tools/test-generator/test/test_generator_test.ml +11 -0
  175. data/tracks/ocaml/tools/test-generator/test/utils_test.ml +21 -0
  176. data/tracks/perl5/config.json +1 -1
  177. data/tracks/perl6/accumulate/accumulate.t +8 -2
  178. data/tracks/perl6/anagram/Example.pm +1 -1
  179. data/tracks/perl6/anagram/anagram.t +7 -8
  180. data/tracks/perl6/binary/Example.pm +1 -1
  181. data/tracks/perl6/binary/binary.t +7 -8
  182. data/tracks/perl6/bob/bob.t +1 -3
  183. data/tracks/perl6/config.json +1 -0
  184. data/tracks/perl6/grains/grains.t +7 -2
  185. data/tracks/perl6/leap/leap.t +3 -1
  186. data/tracks/perl6/raindrops/raindrops.t +8 -2
  187. data/tracks/perl6/rna-transcription/rna_transcription.t +8 -9
  188. data/tracks/perl6/robot-name/robot.t +8 -9
  189. data/tracks/perl6/scrabble-score/Example.pm +1 -1
  190. data/tracks/perl6/scrabble-score/scrabble_score.t +8 -2
  191. data/tracks/perl6/word-count/word_count.t +8 -2
  192. data/tracks/php/config.json +5 -0
  193. data/tracks/php/exercises/markdown/example.php +85 -0
  194. data/tracks/php/exercises/markdown/markdown.php +82 -0
  195. data/tracks/php/exercises/markdown/markdown_test.php +57 -0
  196. data/tracks/python/exercises/hamming/example.py +3 -0
  197. data/tracks/python/exercises/hamming/hamming_test.py +40 -14
  198. data/tracks/python/exercises/rna-transcription/example.py +6 -1
  199. data/tracks/python/exercises/rna-transcription/rna_transcription_test.py +9 -0
  200. data/tracks/ruby/config.json +6 -0
  201. data/tracks/ruby/exercises/dominoes/.version +1 -0
  202. data/tracks/ruby/exercises/dominoes/dominoes_test.rb +149 -0
  203. data/tracks/ruby/exercises/dominoes/example.rb +37 -0
  204. data/tracks/ruby/exercises/dominoes/example.tt +57 -0
  205. data/tracks/ruby/exercises/pangram/.version +1 -1
  206. data/tracks/ruby/exercises/pangram/example.rb +2 -2
  207. data/tracks/ruby/exercises/pangram/example.tt +5 -7
  208. data/tracks/ruby/exercises/pangram/pangram_test.rb +30 -25
  209. data/tracks/ruby/exercises/queen-attack/.version +1 -0
  210. data/tracks/ruby/exercises/queen-attack/example.rb +5 -30
  211. data/tracks/ruby/exercises/queen-attack/example.tt +22 -0
  212. data/tracks/ruby/exercises/queen-attack/queen_attack_test.rb +46 -95
  213. data/tracks/ruby/exercises/triangle/.version +1 -0
  214. data/tracks/ruby/exercises/triangle/example.rb +15 -22
  215. data/tracks/ruby/exercises/triangle/example.tt +20 -0
  216. data/tracks/ruby/exercises/triangle/triangle_test.rb +80 -40
  217. data/tracks/ruby/lib/dominoes_cases.rb +23 -0
  218. data/tracks/ruby/lib/pangram_cases.rb +19 -4
  219. data/tracks/ruby/lib/queen_attack_cases.rb +54 -0
  220. data/tracks/ruby/lib/triangle_cases.rb +51 -0
  221. data/tracks/scala/config.json +6 -0
  222. data/tracks/scala/exercises/dominoes/Example.scala +41 -0
  223. data/tracks/scala/exercises/dominoes/build.sbt +3 -0
  224. data/tracks/scala/exercises/dominoes/src/main/scala/Dominoes.scala +4 -0
  225. data/tracks/scala/exercises/dominoes/src/test/scala/DominoesSuite.scala +91 -0
  226. metadata +83 -2
@@ -0,0 +1,185 @@
1
+ package allyourbase
2
+
3
+ import "testing"
4
+
5
+ // Note: ConvertToBase should accept leading zeroes in its input,
6
+ // but never emit leading zeroes in its output.
7
+ // Exception: If the value of the output is zero, represent it with a single zero.
8
+ var testCases = []struct {
9
+ description string
10
+ inputBase uint64
11
+ outputBase uint64
12
+ inputDigits []uint64
13
+ outputDigits []uint64
14
+ error error
15
+ }{
16
+ {
17
+ description: "single bit one to decimal",
18
+ inputBase: 2,
19
+ inputDigits: []uint64{1},
20
+ outputBase: 10,
21
+ outputDigits: []uint64{1},
22
+ },
23
+ {
24
+ description: "binary to single decimal",
25
+ inputBase: 2,
26
+ inputDigits: []uint64{1, 0, 1},
27
+ outputBase: 10,
28
+ outputDigits: []uint64{5},
29
+ },
30
+ {
31
+ description: "single decimal to binary",
32
+ inputBase: 10,
33
+ inputDigits: []uint64{5},
34
+ outputBase: 2,
35
+ outputDigits: []uint64{1, 0, 1},
36
+ },
37
+ {
38
+ description: "binary to multiple decimal",
39
+ inputBase: 2,
40
+ inputDigits: []uint64{1, 0, 1, 0, 1, 0},
41
+ outputBase: 10,
42
+ outputDigits: []uint64{4, 2},
43
+ },
44
+ {
45
+ description: "decimal to binary",
46
+ inputBase: 10,
47
+ inputDigits: []uint64{4, 2},
48
+ outputBase: 2,
49
+ outputDigits: []uint64{1, 0, 1, 0, 1, 0},
50
+ },
51
+ {
52
+ description: "trinary to hexadecimal",
53
+ inputBase: 3,
54
+ inputDigits: []uint64{1, 1, 2, 0},
55
+ outputBase: 16,
56
+ outputDigits: []uint64{2, 10},
57
+ },
58
+ {
59
+ description: "hexadecimal to trinary",
60
+ inputBase: 16,
61
+ inputDigits: []uint64{2, 10},
62
+ outputBase: 3,
63
+ outputDigits: []uint64{1, 1, 2, 0},
64
+ },
65
+ {
66
+ description: "15-bit integer",
67
+ inputBase: 97,
68
+ inputDigits: []uint64{3, 46, 60},
69
+ outputBase: 73,
70
+ outputDigits: []uint64{6, 10, 45},
71
+ },
72
+ {
73
+ description: "empty list",
74
+ inputBase: 2,
75
+ inputDigits: []uint64{},
76
+ outputBase: 10,
77
+ outputDigits: []uint64{0},
78
+ error: nil,
79
+ },
80
+ {
81
+ description: "single zero",
82
+ inputBase: 10,
83
+ inputDigits: []uint64{0},
84
+ outputBase: 2,
85
+ outputDigits: []uint64{0},
86
+ },
87
+ {
88
+ description: "multiple zeros",
89
+ inputBase: 10,
90
+ inputDigits: []uint64{0, 0, 0},
91
+ outputBase: 2,
92
+ outputDigits: []uint64{0},
93
+ },
94
+ {
95
+ description: "leading zeros",
96
+ inputBase: 7,
97
+ inputDigits: []uint64{0, 6, 0},
98
+ outputBase: 10,
99
+ outputDigits: []uint64{4, 2},
100
+ },
101
+ {
102
+ description: "invalid positive digit",
103
+ inputBase: 2,
104
+ inputDigits: []uint64{1, 2, 1, 0, 1, 0},
105
+ outputBase: 10,
106
+ outputDigits: nil,
107
+ error: ErrInvalidDigit,
108
+ },
109
+ {
110
+ description: "first base is one",
111
+ inputBase: 1,
112
+ inputDigits: []uint64{},
113
+ outputBase: 10,
114
+ outputDigits: nil,
115
+ error: ErrInvalidBase,
116
+ },
117
+ {
118
+ description: "second base is one",
119
+ inputBase: 2,
120
+ inputDigits: []uint64{1, 0, 1, 0, 1, 0},
121
+ outputBase: 1,
122
+ outputDigits: nil,
123
+ error: ErrInvalidBase,
124
+ },
125
+ {
126
+ description: "first base is zero",
127
+ inputBase: 0,
128
+ inputDigits: []uint64{},
129
+ outputBase: 10,
130
+ outputDigits: nil,
131
+ error: ErrInvalidBase,
132
+ },
133
+ {
134
+ description: "second base is zero",
135
+ inputBase: 10,
136
+ inputDigits: []uint64{7},
137
+ outputBase: 0,
138
+ outputDigits: nil,
139
+ error: ErrInvalidBase,
140
+ },
141
+ }
142
+
143
+ func digitsEqual(a, b []uint64) bool {
144
+ if len(a) != len(b) {
145
+ return false
146
+ }
147
+
148
+ for i := 0; i < len(a); i++ {
149
+ if a[i] != b[i] {
150
+ return false
151
+ }
152
+ }
153
+
154
+ return true
155
+ }
156
+
157
+ func TestConvertToBase(t *testing.T) {
158
+ for _, c := range testCases {
159
+ output, err := ConvertToBase(c.inputBase, c.inputDigits, c.outputBase)
160
+ if err != c.error {
161
+ t.Fatalf(`FAIL: %s
162
+ Expected error: %v
163
+ Got: %v`, c.description, c.error, err)
164
+ }
165
+
166
+ if !digitsEqual(c.outputDigits, output) {
167
+ t.Fatalf(`FAIL: %s
168
+ Input base: %d
169
+ Input digits: %v
170
+ Output base: %d
171
+ Expected output digits: %v
172
+ Got: %v`, c.description, c.inputBase, c.inputDigits, c.outputBase, c.outputDigits, output)
173
+ } else {
174
+ t.Logf("PASS: %s", c.description)
175
+ }
176
+ }
177
+ }
178
+
179
+ const targetTestVersion = 1
180
+
181
+ func TestTestVersion(t *testing.T) {
182
+ if testVersion != targetTestVersion {
183
+ t.Errorf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
184
+ }
185
+ }
@@ -0,0 +1,60 @@
1
+ package allyourbase
2
+
3
+ import (
4
+ "errors"
5
+ "math"
6
+ )
7
+
8
+ const testVersion = 1
9
+
10
+ var (
11
+ ErrInvalidBase = errors.New("invalid base given")
12
+ ErrInvalidDigit = errors.New("invalid digit given")
13
+ )
14
+
15
+ func ConvertToBase(inputBase uint64, inputDigits []uint64, outputBase uint64) ([]uint64, error) {
16
+ if inputBase < 2 || outputBase < 2 {
17
+ return nil, ErrInvalidBase
18
+ }
19
+
20
+ for _, d := range inputDigits {
21
+ if d >= inputBase {
22
+ return nil, ErrInvalidDigit
23
+ }
24
+ }
25
+
26
+ total := toCanonicalBase(inputBase, inputDigits)
27
+ return digitsInBase(total, outputBase), nil
28
+ }
29
+
30
+ func toCanonicalBase(inputBase uint64, inputDigits []uint64) uint64 {
31
+ var total uint64
32
+
33
+ digits := len(inputDigits)
34
+ for i := digits - 1; i >= 0; i-- {
35
+ total += inputDigits[digits-1-i] * uint64(math.Pow(float64(inputBase), float64(i)))
36
+ }
37
+
38
+ return total
39
+ }
40
+
41
+ func reverse(digits []uint64) []uint64 {
42
+ var output = make([]uint64, len(digits))
43
+
44
+ for i, d := range digits {
45
+ output[len(digits)-1-i] = d
46
+ }
47
+
48
+ return output
49
+ }
50
+
51
+ func digitsInBase(total uint64, outputBase uint64) []uint64 {
52
+ var digits []uint64
53
+ for total >= outputBase {
54
+ digits = append(digits, total%outputBase)
55
+ total /= outputBase
56
+ }
57
+ digits = append(digits, total%outputBase)
58
+
59
+ return reverse(digits)
60
+ }
@@ -0,0 +1,15 @@
1
+ package isogram
2
+
3
+ import "strings"
4
+
5
+ const testVersion = 1
6
+
7
+ func IsIsogram(word string) bool {
8
+ for i, r := range strings.ToLower(word) {
9
+ if r != ' ' && r != '-' && i < strings.LastIndex(word, string(r)) {
10
+ return false
11
+ }
12
+ }
13
+
14
+ return true
15
+ }
@@ -0,0 +1,50 @@
1
+ package isogram
2
+
3
+ import "testing"
4
+
5
+ var testCases = []struct {
6
+ word string
7
+ expected bool
8
+ }{
9
+ {"duplicates", true},
10
+ {"eleven", false},
11
+ {"subdermatoglyphic", true},
12
+ {"Alphabet", false},
13
+ {"thumbscrew-japingly", true},
14
+ {"Hjelmqvist-Gryb-Zock-Pfund-Wax", true},
15
+ {"Heizölrückstoßabdämpfung", true},
16
+ {"the quick brown fox", false},
17
+ {"Emily Jung Schwartzkopf", true},
18
+ {"éléphant", false},
19
+ }
20
+
21
+ func TestIsIsogram(t *testing.T) {
22
+ for _, c := range testCases {
23
+ if IsIsogram(c.word) != c.expected {
24
+ t.Fatalf("FAIL: Word %q, expected %v, got %v", c.word, c.expected, !c.expected)
25
+ }
26
+
27
+ t.Logf("PASS: Word %q", c.word)
28
+ }
29
+ }
30
+
31
+ func BenchmarkIsIsogram(b *testing.B) {
32
+ b.StopTimer()
33
+ for _, c := range testCases {
34
+ b.StartTimer()
35
+
36
+ for i := 0; i < b.N; i++ {
37
+ IsIsogram(c.word)
38
+ }
39
+
40
+ b.StopTimer()
41
+ }
42
+ }
43
+
44
+ const targetTestVersion = 1
45
+
46
+ func TestTestVersion(t *testing.T) {
47
+ if testVersion != targetTestVersion {
48
+ t.Errorf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
49
+ }
50
+ }
@@ -201,7 +201,7 @@ func FormatLedger(currency string, locale string, entries []Entry) (string, erro
201
201
  }{e: errors.New("")}
202
202
  }
203
203
  var al int
204
- for _ = range a {
204
+ for range a {
205
205
  al++
206
206
  }
207
207
  co <- struct {
@@ -213,7 +213,7 @@ func FormatLedger(currency string, locale string, entries []Entry) (string, erro
213
213
  }(i, et)
214
214
  }
215
215
  ss := make([]string, len(entriesCopy))
216
- for _ = range entriesCopy {
216
+ for range entriesCopy {
217
217
  v := <-co
218
218
  if v.e != nil {
219
219
  return "", v.e
@@ -0,0 +1,32 @@
1
+ package pangram
2
+
3
+ import (
4
+ "strings"
5
+ )
6
+
7
+ const testVersion = 1
8
+
9
+ func IsPangram(s string) bool {
10
+ lowerString := strings.ToLower(s)
11
+ var check [26]bool
12
+ var count int
13
+ for _, c := range lowerString {
14
+ if c >= 'a' {
15
+ if c > 'z' {
16
+ continue
17
+ }
18
+ c -= 97
19
+ } else {
20
+ continue
21
+ }
22
+
23
+ if !check[c] {
24
+ if count == 25 {
25
+ return true
26
+ }
27
+ check[c] = true
28
+ count++
29
+ }
30
+ }
31
+ return false
32
+ }
@@ -0,0 +1,43 @@
1
+ package pangram
2
+
3
+ import (
4
+ "testing"
5
+ )
6
+
7
+ const targetTestVersion = 1
8
+
9
+ type testCase struct {
10
+ input string
11
+ expected bool
12
+ failureReason string
13
+ }
14
+
15
+ var testCases = []testCase{
16
+ {"", false, "sentence empty"},
17
+ {"The quick brown fox jumps over the lazy dog", true, ""},
18
+ {"a quick movement of the enemy will jeopardize five gunboats", false, "missing character 'x'"},
19
+ {"the quick brown fish jumps over the lazy dog", false, "another missing character 'x'"},
20
+ {"the 1 quick brown fox jumps over the 2 lazy dogs", true, ""},
21
+ {"7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog", false, "missing letters replaced by numbers"},
22
+ {"\"Five quacking Zephyrs jolt my wax bed.\"", true, ""},
23
+ {"Victor jagt zwölf Boxkämpfer quer über den großen Sylter Deich.", true, ""},
24
+ {"Широкая электрификация южных губерний даст мощный толчок подъёму сельского хозяйства.", false, "Panagram in alphabet other than ASCII"},
25
+ }
26
+
27
+ func TestTestVersion(t *testing.T) {
28
+ if testVersion != targetTestVersion {
29
+ t.Errorf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
30
+ }
31
+ }
32
+
33
+ func TestPangram(t *testing.T) {
34
+ for _, test := range testCases {
35
+ actual := IsPangram(test.input)
36
+ if actual != test.expected {
37
+ t.Errorf("Pangram test [%s], expected [%t], actual [%t]", test.input, test.expected, actual)
38
+ if !test.expected {
39
+ t.Logf("[%s] should not be a pangram because : %s\n", test.input, test.failureReason)
40
+ }
41
+ }
42
+ }
43
+ }
@@ -0,0 +1,59 @@
1
+ package protein
2
+
3
+ const testVersion = 1
4
+
5
+ func FromCodon(codon string) string {
6
+ switch codon {
7
+ case
8
+ "AUG":
9
+ return "Methionine"
10
+ case
11
+ "UUU",
12
+ "UUC":
13
+ return "Phenylalanine"
14
+ case
15
+ "UUA",
16
+ "UUG":
17
+ return "Leucine"
18
+ case
19
+ "UCU",
20
+ "UCC",
21
+ "UCA",
22
+ "UCG":
23
+ return "Serine"
24
+ case
25
+ "UAU",
26
+ "UAC":
27
+ return "Tyrosine"
28
+ case
29
+ "UGU",
30
+ "UGC":
31
+ return "Cysteine"
32
+ case
33
+ "UGG":
34
+ return "Tryptophan"
35
+ case
36
+ "UAA",
37
+ "UAG",
38
+ "UGA":
39
+ return "STOP"
40
+ }
41
+ return "STOP"
42
+ }
43
+
44
+ func FromRNA(s string) []string {
45
+ var res = ""
46
+ var proteins []string
47
+ for index, codon := range s {
48
+ res += string(codon)
49
+ if index > 0 && (index+1)%3 == 0 {
50
+ tempCodon := FromCodon(res)
51
+ if tempCodon == "STOP" {
52
+ break
53
+ }
54
+ proteins = append(proteins, tempCodon)
55
+ res = ""
56
+ }
57
+ }
58
+ return proteins
59
+ }
@@ -0,0 +1,69 @@
1
+ package protein
2
+
3
+ import (
4
+ "reflect"
5
+ "testing"
6
+ )
7
+
8
+ const targetTestVersion = 1
9
+
10
+ type codonCase struct {
11
+ input string
12
+ expected string
13
+ }
14
+
15
+ var codonTestCases = []codonCase{
16
+ {"AUG", "Methionine"},
17
+ {"UUU", "Phenylalanine"},
18
+ {"UUC", "Phenylalanine"},
19
+ {"UUA", "Leucine"},
20
+ {"UUG", "Leucine"},
21
+ {"UCU", "Serine"},
22
+ {"UCC", "Serine"},
23
+ {"UCA", "Serine"},
24
+ {"UCG", "Serine"},
25
+ {"UAU", "Tyrosine"},
26
+ {"UAC", "Tyrosine"},
27
+ {"UGU", "Cysteine"},
28
+ {"UGC", "Cysteine"},
29
+ {"UGG", "Tryptophan"},
30
+ {"UAA", "STOP"},
31
+ {"UAG", "STOP"},
32
+ {"UGA", "STOP"},
33
+ }
34
+
35
+ type rnaCase struct {
36
+ input string
37
+ expected []string
38
+ }
39
+
40
+ var proteinTestCases = []rnaCase{
41
+ {"AUGUUUUCUUAAAUG", []string{"Methionine", "Phenylalanine", "Serine"}},
42
+ {"AUGUUUUGG", []string{"Methionine", "Phenylalanine", "Tryptophan"}},
43
+ {"AUGUUUUAA", []string{"Methionine", "Phenylalanine"}},
44
+ {"UGGUGUUAUUAAUGGUUU", []string{"Tryptophan", "Cysteine", "Tyrosine"}},
45
+ }
46
+
47
+ func TestCodon(t *testing.T) {
48
+ for _, test := range codonTestCases {
49
+ actual := FromCodon(test.input)
50
+ if actual != test.expected {
51
+ t.Errorf("Protein Translation test [%s], expected [%s], actual [%s]", test.input, test.expected, actual)
52
+ }
53
+ }
54
+ }
55
+
56
+ func TestProtein(t *testing.T) {
57
+ for _, test := range proteinTestCases {
58
+ actual := FromRNA(test.input)
59
+ if !reflect.DeepEqual(actual, test.expected) {
60
+ t.Errorf("Protein Translation test [%s], expected %q, actual %q", test.input, test.expected, actual)
61
+ }
62
+ }
63
+ }
64
+
65
+ func TestTestVersion(t *testing.T) {
66
+ if testVersion != targetTestVersion {
67
+ t.Errorf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
68
+ }
69
+ }
@@ -63,7 +63,7 @@ func Build(records []Record) (*Node, error) {
63
63
  nn := &Node{ID: r.ID}
64
64
  newTodo = append(newTodo, nn)
65
65
  breakpoint:
66
- for _ = range []bool{false} {
66
+ for range []bool{false} {
67
67
  for i, cc := range c.Children {
68
68
  if cc.ID > r.ID {
69
69
  a := make([]*Node, len(c.Children)+1)
@@ -0,0 +1,57 @@
1
+ package twelve
2
+
3
+ import (
4
+ "fmt"
5
+ )
6
+
7
+ const testVersion = 1
8
+
9
+ var verse = map[string]string{
10
+ "first": "a Partridge in a Pear Tree.",
11
+ "twelfth": "twelve Drummers Drumming",
12
+ "eleventh": "eleven Pipers Piping",
13
+ "tenth": "ten Lords-a-Leaping",
14
+ "ninth": "nine Ladies Dancing",
15
+ "eighth": "eight Maids-a-Milking",
16
+ "seventh": "seven Swans-a-Swimming",
17
+ "sixth": "six Geese-a-Laying",
18
+ "fifth": "five Gold Rings",
19
+ "fourth": "four Calling Birds",
20
+ "third": "three French Hens",
21
+ "second": "two Turtle Doves",
22
+ }
23
+
24
+ var wording = map[int]string{
25
+ 1: "first",
26
+ 2: "second",
27
+ 3: "third",
28
+ 4: "fourth",
29
+ 5: "fifth",
30
+ 6: "sixth",
31
+ 7: "seventh",
32
+ 8: "eighth",
33
+ 9: "ninth",
34
+ 10: "tenth",
35
+ 11: "eleventh",
36
+ 12: "twelfth",
37
+ }
38
+
39
+ func Verse(i int) string {
40
+ var gifts = ""
41
+ for from := i; from > 0; from-- {
42
+ if i != 1 && from == 1 {
43
+ gifts = fmt.Sprintf("%s, and %s", gifts, verse[wording[from]])
44
+ } else {
45
+ gifts = fmt.Sprintf("%s, %s", gifts, verse[wording[from]])
46
+ }
47
+ }
48
+ return fmt.Sprintf("On the %s day of Christmas my true love gave to me%s", wording[i], gifts)
49
+ }
50
+
51
+ func Song() string {
52
+ var song = ""
53
+ for i := 1; i <= 12; i++ {
54
+ song += Verse(i) + "\n"
55
+ }
56
+ return song
57
+ }
@@ -0,0 +1,79 @@
1
+ package twelve
2
+
3
+ import (
4
+ "fmt"
5
+ "strings"
6
+ "testing"
7
+ )
8
+
9
+ const targetTestVersion = 1
10
+
11
+ type testCase struct {
12
+ input int
13
+ expected string
14
+ }
15
+
16
+ var testCases = []testCase{
17
+ {1, "On the first day of Christmas my true love gave to me, a Partridge in a Pear Tree."},
18
+ {2, "On the second day of Christmas my true love gave to me, two Turtle Doves, and a Partridge in a Pear Tree."},
19
+ {3, "On the third day of Christmas my true love gave to me, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
20
+ {4, "On the fourth day of Christmas my true love gave to me, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
21
+ {5, "On the fifth day of Christmas my true love gave to me, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
22
+ {6, "On the sixth day of Christmas my true love gave to me, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
23
+ {7, "On the seventh day of Christmas my true love gave to me, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
24
+ {8, "On the eighth day of Christmas my true love gave to me, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
25
+ {9, "On the ninth day of Christmas my true love gave to me, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
26
+ {10, "On the tenth day of Christmas my true love gave to me, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
27
+ {11, "On the eleventh day of Christmas my true love gave to me, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
28
+ {12, "On the twelfth day of Christmas my true love gave to me, twelve Drummers Drumming, eleven Pipers Piping, ten Lords-a-Leaping, nine Ladies Dancing, eight Maids-a-Milking, seven Swans-a-Swimming, six Geese-a-Laying, five Gold Rings, four Calling Birds, three French Hens, two Turtle Doves, and a Partridge in a Pear Tree."},
29
+ }
30
+
31
+ // diff compares two multi-line strings and returns a helpful comment
32
+ func diff(got, want string) string {
33
+ g := strings.Split(got, "\n")
34
+ w := strings.Split(want, "\n")
35
+ for i := 0; ; i++ {
36
+ switch {
37
+ case i < len(g) && i < len(w):
38
+ if g[i] == w[i] {
39
+ continue
40
+ }
41
+ return fmt.Sprintf("-- first difference in line %d:\n"+
42
+ "-- got : %q\n-- want: %q\n", i+1, g[i], w[i])
43
+ case i < len(g):
44
+ return fmt.Sprintf("-- got %d extra lines after line %d:\n"+
45
+ "-- first extra line: %q\n", len(g)-len(w), i, g[i])
46
+ case i < len(w):
47
+ return fmt.Sprintf("-- got %d correct lines, want %d more lines:\n"+
48
+ "-- want next: %q\n", i, len(w)-i, w[i])
49
+ default:
50
+ return "no differences found"
51
+ }
52
+ }
53
+ }
54
+
55
+ func TestSong(t *testing.T) {
56
+ var expected = ""
57
+ for _, test := range testCases {
58
+ expected += test.expected + "\n"
59
+ }
60
+ actual := Song()
61
+ if expected != actual {
62
+ t.Fatalf("Song() =\n%s\n want:\n%s\n%s", actual, expected, diff(actual, expected))
63
+ }
64
+ }
65
+
66
+ func TestVerse(t *testing.T) {
67
+ for _, test := range testCases {
68
+ actual := Verse(test.input)
69
+ if actual != test.expected {
70
+ t.Errorf("Twelve Days test [%d], expected [%s], actual [%s]", test.input, test.expected, actual)
71
+ }
72
+ }
73
+ }
74
+
75
+ func TestTestVersion(t *testing.T) {
76
+ if testVersion != targetTestVersion {
77
+ t.Errorf("Found testVersion = %v, want %v.", testVersion, targetTestVersion)
78
+ }
79
+ }