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.
- checksums.yaml +4 -4
- data/fixtures/tracks/fruit/docs/something.md +0 -0
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/README.md +8 -4
- data/problem-specifications/exercises/acronym/canonical-data.json +19 -7
- data/problem-specifications/exercises/all-your-base/canonical-data.json +106 -64
- data/problem-specifications/exercises/allergies/canonical-data.json +37 -13
- data/tracks/c/config.json +176 -176
- data/tracks/clojure/config.json +17 -1
- data/tracks/clojure/exercises/isbn-verifier/README.md +43 -0
- data/tracks/clojure/exercises/isbn-verifier/project.clj +4 -0
- data/tracks/clojure/exercises/isbn-verifier/src/example.clj +17 -0
- data/tracks/clojure/exercises/isbn-verifier/src/isbn_verifier.clj +3 -0
- data/tracks/clojure/exercises/isbn-verifier/test/isbn_verifier_test.clj +42 -0
- data/tracks/clojure/exercises/proverb/README.md +15 -0
- data/tracks/clojure/exercises/proverb/project.clj +4 -0
- data/tracks/clojure/exercises/proverb/src/example.clj +15 -0
- data/tracks/clojure/exercises/proverb/src/proverb.clj +3 -0
- data/tracks/clojure/exercises/proverb/test/proverb_test.clj +14 -0
- data/tracks/common-lisp/docs/LEARNING.md +4 -3
- data/tracks/common-lisp/docs/RESOURCES.md +11 -0
- data/tracks/delphi/.gitignore +1 -0
- data/tracks/delphi/config.json +24 -0
- data/tracks/delphi/docs/INSTALLATION.md +1 -1
- data/tracks/delphi/exercises/isbn-verifier/ISBNVerifier.dpr +60 -0
- data/tracks/delphi/exercises/isbn-verifier/README.md +68 -0
- data/tracks/delphi/exercises/isbn-verifier/uISBNVerifierExample.pas +46 -0
- data/tracks/delphi/exercises/isbn-verifier/uTestISBNVerifier.pas +136 -0
- data/tracks/delphi/exercises/secret-handshake/README.md +56 -0
- data/tracks/delphi/exercises/secret-handshake/SecretHandshake.dpr +60 -0
- data/tracks/delphi/exercises/secret-handshake/uSecretHandshakeExample.pas +56 -0
- data/tracks/delphi/exercises/secret-handshake/uTestSecretHandshake.pas +215 -0
- data/tracks/ecmascript/docs/ABOUT.md +13 -9
- data/tracks/factor/exercises/two-fer/README.md +1 -1
- data/tracks/fsharp/docs/RESOURCES.md +1 -1
- data/tracks/fsharp/generators/{Input.fs → CanonicalData.fs} +5 -10
- data/tracks/fsharp/generators/Exercise.fs +11 -10
- data/tracks/fsharp/generators/{Output.fs → Formatting.fs} +2 -56
- data/tracks/fsharp/generators/Generators.fs +93 -93
- data/tracks/fsharp/generators/Generators.fsproj +9 -4
- data/tracks/fsharp/generators/Options.fs +1 -1
- data/tracks/fsharp/generators/Program.fs +3 -3
- data/tracks/fsharp/generators/Rendering.fs +57 -0
- data/tracks/go/exercises/all-your-base/.meta/gen.go +80 -0
- data/tracks/go/exercises/all-your-base/.meta/hints.md +13 -0
- data/tracks/go/exercises/all-your-base/README.md +16 -1
- data/tracks/go/exercises/all-your-base/all_your_base_test.go +12 -163
- data/tracks/go/exercises/all-your-base/cases_test.go +183 -0
- data/tracks/go/exercises/all-your-base/example.go +25 -29
- data/tracks/java/CONTRIBUTING.md +1 -1
- data/tracks/java/POLICIES.md +15 -1
- data/tracks/java/exercises/flatten-array/.meta/hints.md +58 -0
- data/tracks/java/exercises/flatten-array/README.md +62 -0
- data/tracks/java/exercises/hamming/src/main/java/Hamming.java +1 -1
- data/tracks/java/exercises/matrix/.meta/src/reference/java/Matrix.java +6 -6
- data/tracks/java/exercises/meetup/.meta/src/reference/java/Meetup.java +2 -2
- data/tracks/java/exercises/meetup/.meta/src/reference/java/MeetupSchedule.java +1 -1
- data/tracks/java/exercises/meetup/src/main/java/MeetupSchedule.java +1 -1
- data/tracks/java/exercises/pig-latin/.meta/hints.md +58 -0
- data/tracks/java/exercises/pig-latin/README.md +61 -0
- data/tracks/java/exercises/reverse-string/src/main/java/ReverseString.java +2 -2
- data/tracks/java/exercises/secret-handshake/README.md +1 -1
- data/tracks/javascript/.eslintignore +0 -3
- data/tracks/javascript/exercises/food-chain/example.js +50 -37
- data/tracks/javascript/exercises/octal/example.js +1 -1
- data/tracks/javascript/exercises/robot-name/robot-name.spec.js +7 -7
- data/tracks/javascript/package-lock.json +1846 -0
- data/tracks/python/docs/EXERCISE_README_INSERT.md +15 -0
- data/tracks/python/exercises/accumulate/README.md +15 -0
- data/tracks/python/exercises/acronym/README.md +15 -0
- data/tracks/python/exercises/all-your-base/README.md +15 -0
- data/tracks/python/exercises/all-your-base/all_your_base_test.py +19 -9
- data/tracks/python/exercises/allergies/README.md +15 -0
- data/tracks/python/exercises/alphametics/README.md +15 -0
- data/tracks/python/exercises/anagram/README.md +15 -0
- data/tracks/python/exercises/atbash-cipher/README.md +15 -0
- data/tracks/python/exercises/beer-song/README.md +16 -1
- data/tracks/python/exercises/binary-search-tree/README.md +16 -2
- data/tracks/python/exercises/binary-search/README.md +15 -0
- data/tracks/python/exercises/binary-search/binary_search_test.py +14 -4
- data/tracks/python/exercises/binary/README.md +15 -0
- data/tracks/python/exercises/binary/binary_test.py +14 -4
- data/tracks/python/exercises/bob/README.md +15 -0
- data/tracks/python/exercises/book-store/README.md +15 -0
- data/tracks/python/exercises/bracket-push/README.md +15 -0
- data/tracks/python/exercises/change/README.md +15 -0
- data/tracks/python/exercises/circular-buffer/README.md +15 -0
- data/tracks/python/exercises/circular-buffer/circular_buffer_test.py +15 -5
- data/tracks/python/exercises/circular-buffer/example.py +2 -2
- data/tracks/python/exercises/clock/README.md +15 -0
- data/tracks/python/exercises/collatz-conjecture/.meta/hints.md +1 -1
- data/tracks/python/exercises/collatz-conjecture/README.md +15 -0
- data/tracks/python/exercises/complex-numbers/README.md +15 -0
- data/tracks/python/exercises/connect/README.md +18 -3
- data/tracks/python/exercises/crypto-square/README.md +15 -0
- data/tracks/python/exercises/diamond/README.md +15 -0
- data/tracks/python/exercises/difference-of-squares/README.md +15 -0
- data/tracks/python/exercises/diffie-hellman/README.md +14 -0
- data/tracks/python/exercises/dominoes/README.md +16 -1
- data/tracks/python/exercises/error-handling/README.md +17 -0
- data/tracks/python/exercises/error-handling/error_handling_test.py +13 -3
- data/tracks/python/exercises/error-handling/example.py +1 -1
- data/tracks/python/exercises/etl/README.md +16 -1
- data/tracks/python/exercises/flatten-array/README.md +15 -0
- data/tracks/python/exercises/food-chain/README.md +15 -0
- data/tracks/python/exercises/forth/README.md +15 -0
- data/tracks/python/exercises/forth/example.py +7 -9
- data/tracks/python/exercises/forth/forth_test.py +107 -17
- data/tracks/python/exercises/gigasecond/README.md +15 -0
- data/tracks/python/exercises/go-counting/README.md +21 -3
- data/tracks/python/exercises/grade-school/README.md +15 -0
- data/tracks/python/exercises/grains/README.md +15 -0
- data/tracks/python/exercises/grains/grains_test.py +16 -6
- data/tracks/python/exercises/grep/README.md +15 -0
- data/tracks/python/exercises/hamming/README.md +15 -0
- data/tracks/python/exercises/hamming/hamming_test.py +12 -2
- data/tracks/python/exercises/hello-world/README.md +15 -0
- data/tracks/python/exercises/hexadecimal/README.md +15 -0
- data/tracks/python/exercises/hexadecimal/hexadecimal_test.py +11 -1
- data/tracks/python/exercises/house/README.md +16 -1
- data/tracks/python/exercises/isogram/README.md +15 -0
- data/tracks/python/exercises/kindergarten-garden/README.md +18 -3
- data/tracks/python/exercises/largest-series-product/README.md +15 -0
- data/tracks/python/exercises/largest-series-product/largest_series_product_test.py +14 -4
- data/tracks/python/exercises/leap/README.md +15 -0
- data/tracks/python/exercises/linked-list/README.md +15 -0
- data/tracks/python/exercises/list-ops/README.md +15 -0
- data/tracks/python/exercises/luhn/README.md +15 -0
- data/tracks/python/exercises/markdown/README.md +18 -0
- data/tracks/python/exercises/matrix/README.md +15 -0
- data/tracks/python/exercises/meetup/README.md +31 -12
- data/tracks/python/exercises/meetup/meetup_test.py +11 -1
- data/tracks/python/exercises/minesweeper/README.md +15 -0
- data/tracks/python/exercises/minesweeper/minesweeper_test.py +12 -2
- data/tracks/python/exercises/nth-prime/README.md +15 -0
- data/tracks/python/exercises/nth-prime/nth_prime_test.py +11 -1
- data/tracks/python/exercises/nucleotide-count/README.md +17 -2
- data/tracks/python/exercises/nucleotide-count/nucleotide_count_test.py +11 -1
- data/tracks/python/exercises/ocr-numbers/README.md +16 -1
- data/tracks/python/exercises/ocr-numbers/ocr_numbers_test.py +12 -2
- data/tracks/python/exercises/octal/README.md +15 -0
- data/tracks/python/exercises/octal/octal_test.py +16 -3
- data/tracks/python/exercises/palindrome-products/README.md +16 -1
- data/tracks/python/exercises/pangram/README.md +15 -0
- data/tracks/python/exercises/pascals-triangle/README.md +16 -1
- data/tracks/python/exercises/perfect-numbers/README.md +15 -0
- data/tracks/python/exercises/perfect-numbers/perfect_numbers_test.py +13 -3
- data/tracks/python/exercises/phone-number/README.md +16 -2
- data/tracks/python/exercises/phone-number/example.py +1 -1
- data/tracks/python/exercises/phone-number/phone_number_test.py +17 -7
- data/tracks/python/exercises/pig-latin/README.md +15 -0
- data/tracks/python/exercises/point-mutations/README.md +15 -0
- data/tracks/python/exercises/poker/README.md +15 -0
- data/tracks/python/exercises/pov/README.md +20 -2
- data/tracks/python/exercises/pov/example.py +2 -2
- data/tracks/python/exercises/pov/pov_test.py +15 -5
- data/tracks/python/exercises/prime-factors/README.md +15 -0
- data/tracks/python/exercises/protein-translation/README.md +15 -0
- data/tracks/python/exercises/protein-translation/protein_translation_test.py +10 -0
- data/tracks/python/exercises/proverb/README.md +14 -0
- data/tracks/python/exercises/pythagorean-triplet/README.md +15 -0
- data/tracks/python/exercises/pythagorean-triplet/pythagorean_triplet_test.py +11 -1
- data/tracks/python/exercises/queen-attack/README.md +15 -0
- data/tracks/python/exercises/queen-attack/queen_attack_test.py +17 -7
- data/tracks/python/exercises/rail-fence-cipher/README.md +15 -0
- data/tracks/python/exercises/raindrops/README.md +15 -0
- data/tracks/python/exercises/react/README.md +15 -1
- data/tracks/python/exercises/rectangles/README.md +24 -9
- data/tracks/python/exercises/rna-transcription/.meta/hints.md +1 -0
- data/tracks/python/exercises/rna-transcription/README.md +18 -5
- data/tracks/python/exercises/rna-transcription/rna_transcription_test.py +13 -3
- data/tracks/python/exercises/robot-name/README.md +15 -0
- data/tracks/python/exercises/robot-simulator/README.md +15 -0
- data/tracks/python/exercises/roman-numerals/README.md +15 -0
- data/tracks/python/exercises/rotational-cipher/README.md +15 -0
- data/tracks/python/exercises/run-length-encoding/README.md +15 -0
- data/tracks/python/exercises/saddle-points/README.md +15 -0
- data/tracks/python/exercises/saddle-points/saddle_points_test.py +11 -1
- data/tracks/python/exercises/say/README.md +15 -0
- data/tracks/python/exercises/say/say_test.py +12 -2
- data/tracks/python/exercises/scale-generator/README.md +15 -0
- data/tracks/python/exercises/scale-generator/example.py +3 -3
- data/tracks/python/exercises/scale-generator/scale_generator_test.py +11 -1
- data/tracks/python/exercises/scrabble-score/README.md +15 -0
- data/tracks/python/exercises/secret-handshake/README.md +16 -1
- data/tracks/python/exercises/series/README.md +15 -0
- data/tracks/python/exercises/series/series_test.py +12 -2
- data/tracks/python/exercises/sieve/README.md +15 -0
- data/tracks/python/exercises/simple-cipher/.meta/hints.md +6 -6
- data/tracks/python/exercises/simple-cipher/README.md +17 -1
- data/tracks/python/exercises/simple-cipher/simple_cipher_test.py +12 -2
- data/tracks/python/exercises/simple-linked-list/{hints.md → .meta/hints.md} +10 -10
- data/tracks/python/exercises/simple-linked-list/README.md +16 -0
- data/tracks/python/exercises/simple-linked-list/example.py +2 -2
- data/tracks/python/exercises/simple-linked-list/simple_linked_list_test.py +13 -3
- data/tracks/python/exercises/space-age/README.md +15 -0
- data/tracks/python/exercises/strain/README.md +16 -3
- data/tracks/python/exercises/sublist/README.md +15 -0
- data/tracks/python/exercises/sum-of-multiples/README.md +18 -3
- data/tracks/python/exercises/tournament/README.md +15 -0
- data/tracks/python/exercises/transpose/README.md +15 -0
- data/tracks/python/exercises/tree-building/README.md +30 -0
- data/tracks/python/exercises/tree-building/example.py +3 -5
- data/tracks/python/exercises/tree-building/tree_building_test.py +16 -6
- data/tracks/python/exercises/triangle/README.md +15 -0
- data/tracks/python/exercises/triangle/example.py +1 -1
- data/tracks/python/exercises/triangle/triangle_test.py +15 -5
- data/tracks/python/exercises/trinary/README.md +15 -0
- data/tracks/python/exercises/twelve-days/README.md +15 -0
- data/tracks/python/exercises/two-bucket/README.md +22 -7
- data/tracks/python/exercises/two-fer/README.md +16 -0
- data/tracks/python/exercises/variable-length-quantity/README.md +15 -0
- data/tracks/python/exercises/variable-length-quantity/variable_length_quantity_test.py +12 -2
- data/tracks/python/exercises/word-count/README.md +15 -0
- data/tracks/python/exercises/word-search/README.md +15 -0
- data/tracks/python/exercises/wordy/README.md +15 -0
- data/tracks/python/exercises/wordy/wordy_test.py +14 -4
- data/tracks/python/exercises/zebra-puzzle/README.md +15 -0
- data/tracks/python/exercises/zipper/README.md +16 -3
- data/tracks/rust/config.json +11 -0
- data/tracks/rust/exercises/saddle-points/.gitignore +8 -0
- data/tracks/rust/exercises/saddle-points/Cargo.toml +5 -0
- data/tracks/rust/exercises/saddle-points/README.md +66 -0
- data/tracks/rust/exercises/saddle-points/example.rs +24 -0
- data/tracks/rust/exercises/saddle-points/src/lib.rs +3 -0
- data/tracks/rust/exercises/saddle-points/tests/saddle-points.rs +60 -0
- 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="
|
|
12
|
-
<Compile Include="
|
|
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.
|
|
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.
|
|
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(
|
|
29
|
+
| _ -> Result.Error(Seq.singleton "Invalid parsing result")
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
open Serilog
|
|
4
4
|
open Exercise
|
|
5
|
-
open
|
|
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
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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.
|
|
11
|
+
if c.err != "" && (err == nil || c.err != err.Error()) {
|
|
161
12
|
t.Fatalf(`FAIL: %s
|
|
162
|
-
Expected error: %
|
|
163
|
-
Got: %v`, c.description, c.
|
|
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:
|
|
19
|
+
Input digits: %#v
|
|
170
20
|
Output base: %d
|
|
171
|
-
Expected output digits:
|
|
172
|
-
Got:
|
|
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
|
+
}
|