trackler 2.2.1.74 → 2.2.1.75

Sign up to get free protection for your applications and to get access to all the features.
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
+ }