trackler 2.2.1.74 → 2.2.1.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. checksums.yaml +4 -4
  2. data/fixtures/tracks/fruit/docs/something.md +0 -0
  3. data/lib/trackler/version.rb +1 -1
  4. data/problem-specifications/README.md +8 -4
  5. data/problem-specifications/exercises/acronym/canonical-data.json +19 -7
  6. data/problem-specifications/exercises/all-your-base/canonical-data.json +106 -64
  7. data/problem-specifications/exercises/allergies/canonical-data.json +37 -13
  8. data/tracks/c/config.json +176 -176
  9. data/tracks/clojure/config.json +17 -1
  10. data/tracks/clojure/exercises/isbn-verifier/README.md +43 -0
  11. data/tracks/clojure/exercises/isbn-verifier/project.clj +4 -0
  12. data/tracks/clojure/exercises/isbn-verifier/src/example.clj +17 -0
  13. data/tracks/clojure/exercises/isbn-verifier/src/isbn_verifier.clj +3 -0
  14. data/tracks/clojure/exercises/isbn-verifier/test/isbn_verifier_test.clj +42 -0
  15. data/tracks/clojure/exercises/proverb/README.md +15 -0
  16. data/tracks/clojure/exercises/proverb/project.clj +4 -0
  17. data/tracks/clojure/exercises/proverb/src/example.clj +15 -0
  18. data/tracks/clojure/exercises/proverb/src/proverb.clj +3 -0
  19. data/tracks/clojure/exercises/proverb/test/proverb_test.clj +14 -0
  20. data/tracks/common-lisp/docs/LEARNING.md +4 -3
  21. data/tracks/common-lisp/docs/RESOURCES.md +11 -0
  22. data/tracks/delphi/.gitignore +1 -0
  23. data/tracks/delphi/config.json +24 -0
  24. data/tracks/delphi/docs/INSTALLATION.md +1 -1
  25. data/tracks/delphi/exercises/isbn-verifier/ISBNVerifier.dpr +60 -0
  26. data/tracks/delphi/exercises/isbn-verifier/README.md +68 -0
  27. data/tracks/delphi/exercises/isbn-verifier/uISBNVerifierExample.pas +46 -0
  28. data/tracks/delphi/exercises/isbn-verifier/uTestISBNVerifier.pas +136 -0
  29. data/tracks/delphi/exercises/secret-handshake/README.md +56 -0
  30. data/tracks/delphi/exercises/secret-handshake/SecretHandshake.dpr +60 -0
  31. data/tracks/delphi/exercises/secret-handshake/uSecretHandshakeExample.pas +56 -0
  32. data/tracks/delphi/exercises/secret-handshake/uTestSecretHandshake.pas +215 -0
  33. data/tracks/ecmascript/docs/ABOUT.md +13 -9
  34. data/tracks/factor/exercises/two-fer/README.md +1 -1
  35. data/tracks/fsharp/docs/RESOURCES.md +1 -1
  36. data/tracks/fsharp/generators/{Input.fs → CanonicalData.fs} +5 -10
  37. data/tracks/fsharp/generators/Exercise.fs +11 -10
  38. data/tracks/fsharp/generators/{Output.fs → Formatting.fs} +2 -56
  39. data/tracks/fsharp/generators/Generators.fs +93 -93
  40. data/tracks/fsharp/generators/Generators.fsproj +9 -4
  41. data/tracks/fsharp/generators/Options.fs +1 -1
  42. data/tracks/fsharp/generators/Program.fs +3 -3
  43. data/tracks/fsharp/generators/Rendering.fs +57 -0
  44. data/tracks/go/exercises/all-your-base/.meta/gen.go +80 -0
  45. data/tracks/go/exercises/all-your-base/.meta/hints.md +13 -0
  46. data/tracks/go/exercises/all-your-base/README.md +16 -1
  47. data/tracks/go/exercises/all-your-base/all_your_base_test.go +12 -163
  48. data/tracks/go/exercises/all-your-base/cases_test.go +183 -0
  49. data/tracks/go/exercises/all-your-base/example.go +25 -29
  50. data/tracks/java/CONTRIBUTING.md +1 -1
  51. data/tracks/java/POLICIES.md +15 -1
  52. data/tracks/java/exercises/flatten-array/.meta/hints.md +58 -0
  53. data/tracks/java/exercises/flatten-array/README.md +62 -0
  54. data/tracks/java/exercises/hamming/src/main/java/Hamming.java +1 -1
  55. data/tracks/java/exercises/matrix/.meta/src/reference/java/Matrix.java +6 -6
  56. data/tracks/java/exercises/meetup/.meta/src/reference/java/Meetup.java +2 -2
  57. data/tracks/java/exercises/meetup/.meta/src/reference/java/MeetupSchedule.java +1 -1
  58. data/tracks/java/exercises/meetup/src/main/java/MeetupSchedule.java +1 -1
  59. data/tracks/java/exercises/pig-latin/.meta/hints.md +58 -0
  60. data/tracks/java/exercises/pig-latin/README.md +61 -0
  61. data/tracks/java/exercises/reverse-string/src/main/java/ReverseString.java +2 -2
  62. data/tracks/java/exercises/secret-handshake/README.md +1 -1
  63. data/tracks/javascript/.eslintignore +0 -3
  64. data/tracks/javascript/exercises/food-chain/example.js +50 -37
  65. data/tracks/javascript/exercises/octal/example.js +1 -1
  66. data/tracks/javascript/exercises/robot-name/robot-name.spec.js +7 -7
  67. data/tracks/javascript/package-lock.json +1846 -0
  68. data/tracks/python/docs/EXERCISE_README_INSERT.md +15 -0
  69. data/tracks/python/exercises/accumulate/README.md +15 -0
  70. data/tracks/python/exercises/acronym/README.md +15 -0
  71. data/tracks/python/exercises/all-your-base/README.md +15 -0
  72. data/tracks/python/exercises/all-your-base/all_your_base_test.py +19 -9
  73. data/tracks/python/exercises/allergies/README.md +15 -0
  74. data/tracks/python/exercises/alphametics/README.md +15 -0
  75. data/tracks/python/exercises/anagram/README.md +15 -0
  76. data/tracks/python/exercises/atbash-cipher/README.md +15 -0
  77. data/tracks/python/exercises/beer-song/README.md +16 -1
  78. data/tracks/python/exercises/binary-search-tree/README.md +16 -2
  79. data/tracks/python/exercises/binary-search/README.md +15 -0
  80. data/tracks/python/exercises/binary-search/binary_search_test.py +14 -4
  81. data/tracks/python/exercises/binary/README.md +15 -0
  82. data/tracks/python/exercises/binary/binary_test.py +14 -4
  83. data/tracks/python/exercises/bob/README.md +15 -0
  84. data/tracks/python/exercises/book-store/README.md +15 -0
  85. data/tracks/python/exercises/bracket-push/README.md +15 -0
  86. data/tracks/python/exercises/change/README.md +15 -0
  87. data/tracks/python/exercises/circular-buffer/README.md +15 -0
  88. data/tracks/python/exercises/circular-buffer/circular_buffer_test.py +15 -5
  89. data/tracks/python/exercises/circular-buffer/example.py +2 -2
  90. data/tracks/python/exercises/clock/README.md +15 -0
  91. data/tracks/python/exercises/collatz-conjecture/.meta/hints.md +1 -1
  92. data/tracks/python/exercises/collatz-conjecture/README.md +15 -0
  93. data/tracks/python/exercises/complex-numbers/README.md +15 -0
  94. data/tracks/python/exercises/connect/README.md +18 -3
  95. data/tracks/python/exercises/crypto-square/README.md +15 -0
  96. data/tracks/python/exercises/diamond/README.md +15 -0
  97. data/tracks/python/exercises/difference-of-squares/README.md +15 -0
  98. data/tracks/python/exercises/diffie-hellman/README.md +14 -0
  99. data/tracks/python/exercises/dominoes/README.md +16 -1
  100. data/tracks/python/exercises/error-handling/README.md +17 -0
  101. data/tracks/python/exercises/error-handling/error_handling_test.py +13 -3
  102. data/tracks/python/exercises/error-handling/example.py +1 -1
  103. data/tracks/python/exercises/etl/README.md +16 -1
  104. data/tracks/python/exercises/flatten-array/README.md +15 -0
  105. data/tracks/python/exercises/food-chain/README.md +15 -0
  106. data/tracks/python/exercises/forth/README.md +15 -0
  107. data/tracks/python/exercises/forth/example.py +7 -9
  108. data/tracks/python/exercises/forth/forth_test.py +107 -17
  109. data/tracks/python/exercises/gigasecond/README.md +15 -0
  110. data/tracks/python/exercises/go-counting/README.md +21 -3
  111. data/tracks/python/exercises/grade-school/README.md +15 -0
  112. data/tracks/python/exercises/grains/README.md +15 -0
  113. data/tracks/python/exercises/grains/grains_test.py +16 -6
  114. data/tracks/python/exercises/grep/README.md +15 -0
  115. data/tracks/python/exercises/hamming/README.md +15 -0
  116. data/tracks/python/exercises/hamming/hamming_test.py +12 -2
  117. data/tracks/python/exercises/hello-world/README.md +15 -0
  118. data/tracks/python/exercises/hexadecimal/README.md +15 -0
  119. data/tracks/python/exercises/hexadecimal/hexadecimal_test.py +11 -1
  120. data/tracks/python/exercises/house/README.md +16 -1
  121. data/tracks/python/exercises/isogram/README.md +15 -0
  122. data/tracks/python/exercises/kindergarten-garden/README.md +18 -3
  123. data/tracks/python/exercises/largest-series-product/README.md +15 -0
  124. data/tracks/python/exercises/largest-series-product/largest_series_product_test.py +14 -4
  125. data/tracks/python/exercises/leap/README.md +15 -0
  126. data/tracks/python/exercises/linked-list/README.md +15 -0
  127. data/tracks/python/exercises/list-ops/README.md +15 -0
  128. data/tracks/python/exercises/luhn/README.md +15 -0
  129. data/tracks/python/exercises/markdown/README.md +18 -0
  130. data/tracks/python/exercises/matrix/README.md +15 -0
  131. data/tracks/python/exercises/meetup/README.md +31 -12
  132. data/tracks/python/exercises/meetup/meetup_test.py +11 -1
  133. data/tracks/python/exercises/minesweeper/README.md +15 -0
  134. data/tracks/python/exercises/minesweeper/minesweeper_test.py +12 -2
  135. data/tracks/python/exercises/nth-prime/README.md +15 -0
  136. data/tracks/python/exercises/nth-prime/nth_prime_test.py +11 -1
  137. data/tracks/python/exercises/nucleotide-count/README.md +17 -2
  138. data/tracks/python/exercises/nucleotide-count/nucleotide_count_test.py +11 -1
  139. data/tracks/python/exercises/ocr-numbers/README.md +16 -1
  140. data/tracks/python/exercises/ocr-numbers/ocr_numbers_test.py +12 -2
  141. data/tracks/python/exercises/octal/README.md +15 -0
  142. data/tracks/python/exercises/octal/octal_test.py +16 -3
  143. data/tracks/python/exercises/palindrome-products/README.md +16 -1
  144. data/tracks/python/exercises/pangram/README.md +15 -0
  145. data/tracks/python/exercises/pascals-triangle/README.md +16 -1
  146. data/tracks/python/exercises/perfect-numbers/README.md +15 -0
  147. data/tracks/python/exercises/perfect-numbers/perfect_numbers_test.py +13 -3
  148. data/tracks/python/exercises/phone-number/README.md +16 -2
  149. data/tracks/python/exercises/phone-number/example.py +1 -1
  150. data/tracks/python/exercises/phone-number/phone_number_test.py +17 -7
  151. data/tracks/python/exercises/pig-latin/README.md +15 -0
  152. data/tracks/python/exercises/point-mutations/README.md +15 -0
  153. data/tracks/python/exercises/poker/README.md +15 -0
  154. data/tracks/python/exercises/pov/README.md +20 -2
  155. data/tracks/python/exercises/pov/example.py +2 -2
  156. data/tracks/python/exercises/pov/pov_test.py +15 -5
  157. data/tracks/python/exercises/prime-factors/README.md +15 -0
  158. data/tracks/python/exercises/protein-translation/README.md +15 -0
  159. data/tracks/python/exercises/protein-translation/protein_translation_test.py +10 -0
  160. data/tracks/python/exercises/proverb/README.md +14 -0
  161. data/tracks/python/exercises/pythagorean-triplet/README.md +15 -0
  162. data/tracks/python/exercises/pythagorean-triplet/pythagorean_triplet_test.py +11 -1
  163. data/tracks/python/exercises/queen-attack/README.md +15 -0
  164. data/tracks/python/exercises/queen-attack/queen_attack_test.py +17 -7
  165. data/tracks/python/exercises/rail-fence-cipher/README.md +15 -0
  166. data/tracks/python/exercises/raindrops/README.md +15 -0
  167. data/tracks/python/exercises/react/README.md +15 -1
  168. data/tracks/python/exercises/rectangles/README.md +24 -9
  169. data/tracks/python/exercises/rna-transcription/.meta/hints.md +1 -0
  170. data/tracks/python/exercises/rna-transcription/README.md +18 -5
  171. data/tracks/python/exercises/rna-transcription/rna_transcription_test.py +13 -3
  172. data/tracks/python/exercises/robot-name/README.md +15 -0
  173. data/tracks/python/exercises/robot-simulator/README.md +15 -0
  174. data/tracks/python/exercises/roman-numerals/README.md +15 -0
  175. data/tracks/python/exercises/rotational-cipher/README.md +15 -0
  176. data/tracks/python/exercises/run-length-encoding/README.md +15 -0
  177. data/tracks/python/exercises/saddle-points/README.md +15 -0
  178. data/tracks/python/exercises/saddle-points/saddle_points_test.py +11 -1
  179. data/tracks/python/exercises/say/README.md +15 -0
  180. data/tracks/python/exercises/say/say_test.py +12 -2
  181. data/tracks/python/exercises/scale-generator/README.md +15 -0
  182. data/tracks/python/exercises/scale-generator/example.py +3 -3
  183. data/tracks/python/exercises/scale-generator/scale_generator_test.py +11 -1
  184. data/tracks/python/exercises/scrabble-score/README.md +15 -0
  185. data/tracks/python/exercises/secret-handshake/README.md +16 -1
  186. data/tracks/python/exercises/series/README.md +15 -0
  187. data/tracks/python/exercises/series/series_test.py +12 -2
  188. data/tracks/python/exercises/sieve/README.md +15 -0
  189. data/tracks/python/exercises/simple-cipher/.meta/hints.md +6 -6
  190. data/tracks/python/exercises/simple-cipher/README.md +17 -1
  191. data/tracks/python/exercises/simple-cipher/simple_cipher_test.py +12 -2
  192. data/tracks/python/exercises/simple-linked-list/{hints.md → .meta/hints.md} +10 -10
  193. data/tracks/python/exercises/simple-linked-list/README.md +16 -0
  194. data/tracks/python/exercises/simple-linked-list/example.py +2 -2
  195. data/tracks/python/exercises/simple-linked-list/simple_linked_list_test.py +13 -3
  196. data/tracks/python/exercises/space-age/README.md +15 -0
  197. data/tracks/python/exercises/strain/README.md +16 -3
  198. data/tracks/python/exercises/sublist/README.md +15 -0
  199. data/tracks/python/exercises/sum-of-multiples/README.md +18 -3
  200. data/tracks/python/exercises/tournament/README.md +15 -0
  201. data/tracks/python/exercises/transpose/README.md +15 -0
  202. data/tracks/python/exercises/tree-building/README.md +30 -0
  203. data/tracks/python/exercises/tree-building/example.py +3 -5
  204. data/tracks/python/exercises/tree-building/tree_building_test.py +16 -6
  205. data/tracks/python/exercises/triangle/README.md +15 -0
  206. data/tracks/python/exercises/triangle/example.py +1 -1
  207. data/tracks/python/exercises/triangle/triangle_test.py +15 -5
  208. data/tracks/python/exercises/trinary/README.md +15 -0
  209. data/tracks/python/exercises/twelve-days/README.md +15 -0
  210. data/tracks/python/exercises/two-bucket/README.md +22 -7
  211. data/tracks/python/exercises/two-fer/README.md +16 -0
  212. data/tracks/python/exercises/variable-length-quantity/README.md +15 -0
  213. data/tracks/python/exercises/variable-length-quantity/variable_length_quantity_test.py +12 -2
  214. data/tracks/python/exercises/word-count/README.md +15 -0
  215. data/tracks/python/exercises/word-search/README.md +15 -0
  216. data/tracks/python/exercises/wordy/README.md +15 -0
  217. data/tracks/python/exercises/wordy/wordy_test.py +14 -4
  218. data/tracks/python/exercises/zebra-puzzle/README.md +15 -0
  219. data/tracks/python/exercises/zipper/README.md +16 -3
  220. data/tracks/rust/config.json +11 -0
  221. data/tracks/rust/exercises/saddle-points/.gitignore +8 -0
  222. data/tracks/rust/exercises/saddle-points/Cargo.toml +5 -0
  223. data/tracks/rust/exercises/saddle-points/README.md +66 -0
  224. data/tracks/rust/exercises/saddle-points/example.rs +24 -0
  225. data/tracks/rust/exercises/saddle-points/src/lib.rs +3 -0
  226. data/tracks/rust/exercises/saddle-points/tests/saddle-points.rs +60 -0
  227. metadata +38 -5
@@ -8,8 +8,9 @@
8
8
  <ItemGroup>
9
9
  <Compile Include="Common.fs" />
10
10
  <Compile Include="Options.fs" />
11
- <Compile Include="Input.fs" />
12
- <Compile Include="Output.fs" />
11
+ <Compile Include="CanonicalData.fs" />
12
+ <Compile Include="Formatting.fs" />
13
+ <Compile Include="Rendering.fs" />
13
14
  <Compile Include="Exercise.fs" />
14
15
  <Compile Include="Generators.fs" />
15
16
  <Compile Include="Program.fs" />
@@ -21,12 +22,16 @@
21
22
 
22
23
  <ItemGroup>
23
24
  <PackageReference Include="CommandLineParser" Version="2.1.1-beta" />
24
- <PackageReference Include="DotLiquid" Version="2.0.200" />
25
+ <PackageReference Include="DotLiquid" Version="2.0.232" />
25
26
  <PackageReference Include="Humanizer" Version="2.2.0" />
26
27
  <PackageReference Include="LibGit2Sharp.Portable" Version="0.24.10" />
27
28
  <PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
28
- <PackageReference Include="serilog" Version="2.5.0" />
29
+ <PackageReference Include="serilog" Version="2.6.0" />
29
30
  <PackageReference Include="serilog.sinks.literate" Version="3.0.0" />
30
31
  </ItemGroup>
31
32
 
33
+ <ItemGroup>
34
+ <PackageReference Update="FSharp.Core" Version="4.2.3" />
35
+ </ItemGroup>
36
+
32
37
  </Project>
@@ -26,4 +26,4 @@ let parseOptions argv =
26
26
  match result with
27
27
  | :? Parsed<Options> as parsed -> Result.Ok(normalizeOptions parsed.Value)
28
28
  | :? NotParsed<Options> as notParsed -> Result.Error(notParsed.Errors |> Seq.map string)
29
- | _ -> Result.Error(seq { yield "Invalid parsing result" })
29
+ | _ -> Result.Error(Seq.singleton "Invalid parsing result")
@@ -2,17 +2,17 @@
2
2
 
3
3
  open Serilog
4
4
  open Exercise
5
- open Input
5
+ open CanonicalData
6
6
  open Options
7
7
 
8
- let regenerateTestClass options =
8
+ let private regenerateTestClass options =
9
9
  let parseCanonicalData' = parseCanonicalData options
10
10
 
11
11
  fun (exercise: Exercise) ->
12
12
  let canonicalData = parseCanonicalData' exercise.Name
13
13
  exercise.Regenerate(canonicalData)
14
14
 
15
- let regenerateTestClasses options =
15
+ let private regenerateTestClasses options =
16
16
  Log.Information("Re-generating test classes...")
17
17
 
18
18
  let regenerateTestClass' = regenerateTestClass options
@@ -0,0 +1,57 @@
1
+ module Generators.Rendering
2
+
3
+ open System.Collections.Generic
4
+ open System.Reflection
5
+ open FSharp.Reflection
6
+ open DotLiquid
7
+ open DotLiquid.FileSystems
8
+ open Formatting
9
+
10
+ type OutputFilter() =
11
+ static member Format (input: string) = formatValue input
12
+
13
+ static member Indent (input: string) = indent 1 input
14
+
15
+ let private fileSystem = EmbeddedFileSystem(Assembly.GetExecutingAssembly(), "Generators.Templates")
16
+ Template.RegisterFilter(OutputFilter().GetType())
17
+ Template.FileSystem <- fileSystem :> DotLiquid.FileSystems.IFileSystem
18
+
19
+ let private registrations = Dictionary<_,_>()
20
+ let rec private registerTypeTree templateDataType =
21
+ if registrations.ContainsKey templateDataType then ()
22
+ elif FSharpType.IsRecord templateDataType then
23
+ let properties = templateDataType.GetProperties(BindingFlags.Instance ||| BindingFlags.Public)
24
+ Template.RegisterSafeType(templateDataType, [| for p in properties -> p.Name |])
25
+ registrations.[templateDataType] <- true
26
+ for p in properties do registerTypeTree p.PropertyType
27
+ elif templateDataType.IsGenericType then
28
+ let t = templateDataType.GetGenericTypeDefinition()
29
+ if t = typedefof<seq<_>> || t = typedefof<list<_>> then
30
+ registrations.[templateDataType] <- true
31
+ registerTypeTree (templateDataType.GetGenericArguments().[0])
32
+ elif t = typedefof<IDictionary<_,_>> || t = typedefof<Map<_,_>> then
33
+ registrations.[templateDataType] <- true
34
+ registerTypeTree (templateDataType.GetGenericArguments().[0])
35
+ registerTypeTree (templateDataType.GetGenericArguments().[1])
36
+ elif t = typedefof<option<_>> then
37
+ Template.RegisterSafeType(templateDataType, [|"Value"; "IsSome"; "IsNone";|])
38
+ registrations.[templateDataType] <- true
39
+ registerTypeTree (templateDataType.GetGenericArguments().[0])
40
+ elif templateDataType.IsArray then
41
+ registrations.[templateDataType] <- true
42
+ registerTypeTree (templateDataType.GetElementType())
43
+ else
44
+ let properties = templateDataType.GetProperties(BindingFlags.Instance ||| BindingFlags.Public)
45
+ Template.RegisterSafeType(templateDataType, [| for p in properties -> p.Name |])
46
+ registrations.[templateDataType] <- true
47
+ for p in properties do registerTypeTree p.PropertyType
48
+
49
+ let renderInlineTemplate template data =
50
+ data.GetType() |> registerTypeTree
51
+
52
+ let parsedTemplate = Template.Parse template
53
+ parsedTemplate.Render(Hash.FromAnonymousObject(data))
54
+
55
+ let renderPartialTemplate templateName data =
56
+ let template = sprintf "{%% include \"%s\" %%}" templateName
57
+ renderInlineTemplate template data
@@ -0,0 +1,80 @@
1
+ package main
2
+
3
+ import (
4
+ "log"
5
+ "text/template"
6
+
7
+ "../../../gen"
8
+ )
9
+
10
+ func main() {
11
+ t, err := template.New("").Parse(tmpl)
12
+ if err != nil {
13
+ log.Fatal(err)
14
+ }
15
+ var j js
16
+ if err := gen.Gen("all-your-base", &j, t); err != nil {
17
+ log.Fatal(err)
18
+ }
19
+ }
20
+
21
+ // The JSON structure we expect to be able to unmarshal into
22
+ type js struct {
23
+ Exercise string
24
+ Version string
25
+ Cases []oneCase
26
+ }
27
+
28
+ // Test cases
29
+ type oneCase struct {
30
+ Description string
31
+ Property string
32
+ InputBase int `json:"input_base"`
33
+ InputDigits []int `json:"input_digits"`
34
+ OutputBase int `json:"output_base"`
35
+ Expected interface{}
36
+ }
37
+
38
+ func (o oneCase) Result() []int {
39
+ s, ok := o.Expected.([]interface{})
40
+ if !ok {
41
+ return nil
42
+ }
43
+ var res []int
44
+ for _, v := range s {
45
+ f, _ := v.(float64)
46
+ res = append(res, int(f))
47
+ }
48
+ return res
49
+ }
50
+ func (o oneCase) Err() string {
51
+ m, ok := o.Expected.(map[string]interface{})
52
+ if !ok {
53
+ return ""
54
+ }
55
+ return m["error"].(string)
56
+ }
57
+
58
+ // Template to generate test cases.
59
+ var tmpl = `package allyourbase
60
+
61
+ {{.Header}}
62
+
63
+ var testCases = []struct {
64
+ description string
65
+ inputBase int
66
+ inputDigits []int
67
+ outputBase int
68
+ expected []int
69
+ err string
70
+ }{ {{range .J.Cases}}
71
+ {
72
+ description: {{printf "%q" .Description}},
73
+ inputBase: {{printf "%d" .InputBase}},
74
+ inputDigits: {{printf "%#v" .InputDigits}},
75
+ outputBase: {{printf "%d" .OutputBase}},
76
+ expected: {{printf "%#v" .Result}},
77
+ err: {{printf "%q" .Err}},
78
+ },{{end}}
79
+ }
80
+ `
@@ -0,0 +1,13 @@
1
+ ## Implementation
2
+
3
+ Assumptions:
4
+ 1. Zero is always represented in outputs as [0] instead of [].
5
+ 2. In no other instances are leading zeroes present in any outputs.
6
+ 3. Leading zeroes are accepted in inputs.
7
+ 4. An empty sequence of input digits is considered zero, rather than an error.
8
+
9
+ Handle problem cases by returning an error whose Error() method
10
+ returns one of following messages:
11
+ * input base must be >= 2
12
+ * output base must be >= 2
13
+ * all digits must satisfy 0 <= d < input base
@@ -6,6 +6,7 @@ Implement general base conversion. Given a number in base **a**,
6
6
  represented as a sequence of digits, convert it to base **b**.
7
7
 
8
8
  ## Note
9
+
9
10
  - Try to implement the conversion yourself.
10
11
  Do not use something else to perform the conversion for you.
11
12
 
@@ -28,9 +29,23 @@ The number 1120, *in base 3*, means:
28
29
 
29
30
  I think you got the idea!
30
31
 
31
-
32
32
  *Yes. Those three numbers above are exactly the same. Congratulations!*
33
33
 
34
+ ## Implementation
35
+
36
+ Assumptions:
37
+ 1. Zero is always represented in outputs as [0] instead of [].
38
+ 2. In no other instances are leading zeroes present in any outputs.
39
+ 3. Leading zeroes are accepted in inputs.
40
+ 4. An empty sequence of input digits is considered zero, rather than an error.
41
+
42
+ Handle problem cases by returning an error whose Error() method
43
+ returns one of following messages:
44
+ * input base must be >= 2
45
+ * output base must be >= 2
46
+ * all digits must satisfy 0 <= d < input base
47
+
48
+
34
49
  ## Running the tests
35
50
 
36
51
  To run the tests run the command `go test` from within the exercise directory.
@@ -1,177 +1,26 @@
1
1
  package allyourbase
2
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
- }
3
+ import (
4
+ "reflect"
5
+ "testing"
6
+ )
156
7
 
157
8
  func TestConvertToBase(t *testing.T) {
158
9
  for _, c := range testCases {
159
10
  output, err := ConvertToBase(c.inputBase, c.inputDigits, c.outputBase)
160
- if err != c.error {
11
+ if c.err != "" && (err == nil || c.err != err.Error()) {
161
12
  t.Fatalf(`FAIL: %s
162
- Expected error: %v
163
- Got: %v`, c.description, c.error, err)
13
+ Expected error: %s
14
+ Got: %v`, c.description, c.err, err)
164
15
  }
165
-
166
- if !digitsEqual(c.outputDigits, output) {
16
+ if !reflect.DeepEqual(c.expected, output) {
167
17
  t.Fatalf(`FAIL: %s
168
18
  Input base: %d
169
- Input digits: %v
19
+ Input digits: %#v
170
20
  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)
21
+ Expected output digits: %#v
22
+ Got: %#v`, c.description, c.inputBase, c.inputDigits, c.outputBase, c.expected, output)
175
23
  }
24
+ t.Logf("PASS: %s", c.description)
176
25
  }
177
26
  }
@@ -0,0 +1,183 @@
1
+ package allyourbase
2
+
3
+ // Source: exercism/problem-specifications
4
+ // Commit: ba6375e all-your-base: replace 'first' and 'second' with 'input' and 'output' in descriptions
5
+ // Problem Specifications Version: 2.0.1
6
+
7
+ var testCases = []struct {
8
+ description string
9
+ inputBase int
10
+ inputDigits []int
11
+ outputBase int
12
+ expected []int
13
+ err string
14
+ }{
15
+ {
16
+ description: "single bit one to decimal",
17
+ inputBase: 2,
18
+ inputDigits: []int{1},
19
+ outputBase: 10,
20
+ expected: []int{1},
21
+ err: "",
22
+ },
23
+ {
24
+ description: "binary to single decimal",
25
+ inputBase: 2,
26
+ inputDigits: []int{1, 0, 1},
27
+ outputBase: 10,
28
+ expected: []int{5},
29
+ err: "",
30
+ },
31
+ {
32
+ description: "single decimal to binary",
33
+ inputBase: 10,
34
+ inputDigits: []int{5},
35
+ outputBase: 2,
36
+ expected: []int{1, 0, 1},
37
+ err: "",
38
+ },
39
+ {
40
+ description: "binary to multiple decimal",
41
+ inputBase: 2,
42
+ inputDigits: []int{1, 0, 1, 0, 1, 0},
43
+ outputBase: 10,
44
+ expected: []int{4, 2},
45
+ err: "",
46
+ },
47
+ {
48
+ description: "decimal to binary",
49
+ inputBase: 10,
50
+ inputDigits: []int{4, 2},
51
+ outputBase: 2,
52
+ expected: []int{1, 0, 1, 0, 1, 0},
53
+ err: "",
54
+ },
55
+ {
56
+ description: "trinary to hexadecimal",
57
+ inputBase: 3,
58
+ inputDigits: []int{1, 1, 2, 0},
59
+ outputBase: 16,
60
+ expected: []int{2, 10},
61
+ err: "",
62
+ },
63
+ {
64
+ description: "hexadecimal to trinary",
65
+ inputBase: 16,
66
+ inputDigits: []int{2, 10},
67
+ outputBase: 3,
68
+ expected: []int{1, 1, 2, 0},
69
+ err: "",
70
+ },
71
+ {
72
+ description: "15-bit integer",
73
+ inputBase: 97,
74
+ inputDigits: []int{3, 46, 60},
75
+ outputBase: 73,
76
+ expected: []int{6, 10, 45},
77
+ err: "",
78
+ },
79
+ {
80
+ description: "empty list",
81
+ inputBase: 2,
82
+ inputDigits: []int{},
83
+ outputBase: 10,
84
+ expected: []int{0},
85
+ err: "",
86
+ },
87
+ {
88
+ description: "single zero",
89
+ inputBase: 10,
90
+ inputDigits: []int{0},
91
+ outputBase: 2,
92
+ expected: []int{0},
93
+ err: "",
94
+ },
95
+ {
96
+ description: "multiple zeros",
97
+ inputBase: 10,
98
+ inputDigits: []int{0, 0, 0},
99
+ outputBase: 2,
100
+ expected: []int{0},
101
+ err: "",
102
+ },
103
+ {
104
+ description: "leading zeros",
105
+ inputBase: 7,
106
+ inputDigits: []int{0, 6, 0},
107
+ outputBase: 10,
108
+ expected: []int{4, 2},
109
+ err: "",
110
+ },
111
+ {
112
+ description: "input base is one",
113
+ inputBase: 1,
114
+ inputDigits: []int{},
115
+ outputBase: 10,
116
+ expected: []int(nil),
117
+ err: "input base must be >= 2",
118
+ },
119
+ {
120
+ description: "input base is zero",
121
+ inputBase: 0,
122
+ inputDigits: []int{},
123
+ outputBase: 10,
124
+ expected: []int(nil),
125
+ err: "input base must be >= 2",
126
+ },
127
+ {
128
+ description: "input base is negative",
129
+ inputBase: -2,
130
+ inputDigits: []int{1},
131
+ outputBase: 10,
132
+ expected: []int(nil),
133
+ err: "input base must be >= 2",
134
+ },
135
+ {
136
+ description: "negative digit",
137
+ inputBase: 2,
138
+ inputDigits: []int{1, -1, 1, 0, 1, 0},
139
+ outputBase: 10,
140
+ expected: []int(nil),
141
+ err: "all digits must satisfy 0 <= d < input base",
142
+ },
143
+ {
144
+ description: "invalid positive digit",
145
+ inputBase: 2,
146
+ inputDigits: []int{1, 2, 1, 0, 1, 0},
147
+ outputBase: 10,
148
+ expected: []int(nil),
149
+ err: "all digits must satisfy 0 <= d < input base",
150
+ },
151
+ {
152
+ description: "output base is one",
153
+ inputBase: 2,
154
+ inputDigits: []int{1, 0, 1, 0, 1, 0},
155
+ outputBase: 1,
156
+ expected: []int(nil),
157
+ err: "output base must be >= 2",
158
+ },
159
+ {
160
+ description: "output base is zero",
161
+ inputBase: 10,
162
+ inputDigits: []int{7},
163
+ outputBase: 0,
164
+ expected: []int(nil),
165
+ err: "output base must be >= 2",
166
+ },
167
+ {
168
+ description: "output base is negative",
169
+ inputBase: 2,
170
+ inputDigits: []int{1},
171
+ outputBase: -7,
172
+ expected: []int(nil),
173
+ err: "output base must be >= 2",
174
+ },
175
+ {
176
+ description: "both bases are negative",
177
+ inputBase: -2,
178
+ inputDigits: []int{1},
179
+ outputBase: -7,
180
+ expected: []int(nil),
181
+ err: "input base must be >= 2",
182
+ },
183
+ }