trackler 2.2.1.75 → 2.2.1.76
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/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/alphametics/canonical-data.json +18 -1
- data/problem-specifications/exercises/anagram/canonical-data.json +72 -39
- data/problem-specifications/exercises/binary/canonical-data.json +47 -17
- data/tracks/clojure/exercises/beer-song/src/beer_song.clj +11 -0
- data/tracks/erlang/config.json +10 -0
- data/tracks/erlang/exercises/raindrops/README.md +67 -0
- data/tracks/erlang/exercises/raindrops/rebar.config +30 -0
- data/tracks/erlang/exercises/raindrops/src/example.erl +30 -0
- data/tracks/erlang/exercises/raindrops/src/raindrops.app.src +9 -0
- data/tracks/erlang/exercises/raindrops/src/raindrops.erl +8 -0
- data/tracks/erlang/exercises/raindrops/test/raindrops_tests.erl +50 -0
- data/tracks/fsharp/exercises/bob/BobTest.fs +2 -2
- data/tracks/fsharp/exercises/bob/Example.fs +10 -4
- data/tracks/fsharp/exercises/book-store/BookStoreTest.fs +5 -1
- data/tracks/fsharp/exercises/rna-transcription/RnaTranscriptionTest.fs +1 -13
- data/tracks/fsharp/generators/CanonicalData.fs +14 -7
- data/tracks/fsharp/generators/Exercise.fs +84 -18
- data/tracks/fsharp/generators/Generators.fs +65 -62
- data/tracks/fsharp/generators/Generators.fsproj +0 -4
- data/tracks/fsharp/generators/Options.fs +51 -17
- data/tracks/fsharp/generators/Program.fs +34 -7
- data/tracks/fsharp/generators/Rendering.fs +2 -1
- data/tracks/go/config.json +11 -0
- data/tracks/go/exercises/reverse-string/.meta/gen.go +52 -0
- data/tracks/go/exercises/reverse-string/README.md +31 -0
- data/tracks/go/exercises/reverse-string/cases_test.go +37 -0
- data/tracks/go/exercises/reverse-string/example.go +10 -0
- data/tracks/go/exercises/reverse-string/reverse_string_test.go +25 -0
- data/tracks/haskell/exercises/bob/README.md +2 -0
- data/tracks/haskell/exercises/bob/examples/success-standard/src/Bob.hs +7 -3
- data/tracks/haskell/exercises/bob/package.yaml +1 -1
- data/tracks/haskell/exercises/bob/test/Tests.hs +1 -1
- data/tracks/haskell/exercises/isbn-verifier/README.md +25 -20
- data/tracks/haskell/exercises/pov/README.md +0 -2
- data/tracks/haskell/exercises/secret-handshake/README.md +1 -1
- data/tracks/haskell/exercises/simple-cipher/README.md +4 -6
- data/tracks/java/config.json +12 -0
- data/tracks/java/exercises/beer-song/README.md +1 -1
- data/tracks/java/exercises/house/README.md +1 -1
- data/tracks/java/exercises/isbn-verifier/README.md +27 -21
- data/tracks/java/exercises/kindergarten-garden/README.md +3 -3
- data/tracks/java/exercises/meetup/README.md +16 -12
- data/tracks/java/exercises/nucleotide-count/README.md +2 -2
- data/tracks/java/exercises/palindrome-products/README.md +1 -1
- data/tracks/java/exercises/parallel-letter-frequency/.meta/HINTS.md +3 -0
- data/tracks/java/exercises/parallel-letter-frequency/.meta/src/reference/java/ParallelLetterFrequency.java +45 -0
- data/tracks/java/exercises/parallel-letter-frequency/README.md +30 -0
- data/tracks/java/exercises/parallel-letter-frequency/build.gradle +18 -0
- data/tracks/java/exercises/parallel-letter-frequency/src/main/java/.keep +0 -0
- data/tracks/java/exercises/parallel-letter-frequency/src/test/java/ParallelLetterFrequencyTest.java +235 -0
- data/tracks/java/exercises/pig-latin/README.md +1 -0
- data/tracks/java/exercises/protein-translation/README.md +4 -2
- data/tracks/java/exercises/rectangles/README.md +9 -9
- data/tracks/java/exercises/settings.gradle +1 -0
- data/tracks/java/exercises/simple-cipher/README.md +4 -6
- data/tracks/java/exercises/sum-of-multiples/README.md +3 -3
- data/tracks/objective-c/config.json +11 -0
- data/tracks/objective-c/exercises/two-fer/TwoFerExample.h +15 -0
- data/tracks/objective-c/exercises/two-fer/TwoFerExample.m +21 -0
- data/tracks/objective-c/exercises/two-fer/TwoFerTest.m +31 -0
- data/tracks/objective-c/xcodeProject/ObjectiveC.xcodeproj/project.pbxproj +18 -0
- data/tracks/rust/exercises/bob/Cargo.toml +1 -1
- data/tracks/rust/exercises/bob/README.md +2 -0
- data/tracks/rust/exercises/bob/example.rs +1 -0
- data/tracks/rust/exercises/bob/tests/bob.rs +1 -1
- data/tracks/rust/exercises/isbn-verifier/README.md +25 -20
- data/tracks/typescript/config.json +13 -0
- data/tracks/typescript/exercises/atbash-cipher/README.md +60 -0
- data/tracks/typescript/exercises/atbash-cipher/atbash-cipher.example.ts +32 -0
- data/tracks/typescript/exercises/atbash-cipher/atbash-cipher.test.ts +73 -0
- data/tracks/typescript/exercises/atbash-cipher/atbash-cipher.ts +0 -0
- data/tracks/typescript/exercises/atbash-cipher/package.json +36 -0
- data/tracks/typescript/exercises/atbash-cipher/tsconfig.json +22 -0
- data/tracks/typescript/exercises/atbash-cipher/tslint.json +127 -0
- data/tracks/typescript/exercises/atbash-cipher/yarn.lock +2624 -0
- metadata +31 -2
@@ -0,0 +1,30 @@
|
|
1
|
+
%% Erlang compiler options
|
2
|
+
{erl_opts, [debug_info]}.
|
3
|
+
|
4
|
+
{deps, [{erl_exercism, "0.1.1"}]}.
|
5
|
+
|
6
|
+
{dialyzer, [
|
7
|
+
{warnings, [underspecs, no_return]},
|
8
|
+
{get_warnings, true},
|
9
|
+
{plt_apps, top_level_deps}, % top_level_deps | all_deps
|
10
|
+
{plt_extra_apps, []},
|
11
|
+
{plt_location, local}, % local | "/my/file/name"
|
12
|
+
{plt_prefix, "rebar3"},
|
13
|
+
{base_plt_apps, [stdlib, kernel, crypto]},
|
14
|
+
{base_plt_location, global}, % global | "/my/file/name"
|
15
|
+
{base_plt_prefix, "rebar3"}
|
16
|
+
]}.
|
17
|
+
|
18
|
+
%% eunit:test(Tests)
|
19
|
+
{eunit_tests, []}.
|
20
|
+
%% Options for eunit:test(Tests, Opts)
|
21
|
+
{eunit_opts, [verbose]}.
|
22
|
+
|
23
|
+
%% == xref ==
|
24
|
+
|
25
|
+
{xref_warnings, true}.
|
26
|
+
|
27
|
+
%% xref checks to run
|
28
|
+
{xref_checks, [undefined_function_calls, undefined_functions,
|
29
|
+
locals_not_used, exports_not_used,
|
30
|
+
deprecated_function_calls, deprecated_functions]}.
|
@@ -0,0 +1,30 @@
|
|
1
|
+
-module(example).
|
2
|
+
|
3
|
+
-export([convert/1, test_version/0]).
|
4
|
+
|
5
|
+
convert(Number) when Number rem 3 == 0 ->
|
6
|
+
pling(Number);
|
7
|
+
convert(Number) when Number rem 5 == 0 ->
|
8
|
+
plang(Number);
|
9
|
+
convert(Number) when Number rem 7 == 0 ->
|
10
|
+
plong(Number);
|
11
|
+
convert(Number) ->
|
12
|
+
integer_to_list(Number).
|
13
|
+
|
14
|
+
pling(Number) when Number rem 5 == 0 ->
|
15
|
+
"Pling" ++ plang(Number);
|
16
|
+
pling(Number) when Number rem 7 == 0 ->
|
17
|
+
"Pling" ++ plong(Number);
|
18
|
+
pling(_) ->
|
19
|
+
"Pling".
|
20
|
+
|
21
|
+
plang(Number) when Number rem 7 == 0 ->
|
22
|
+
"Plang" ++ plong(Number);
|
23
|
+
plang(_) ->
|
24
|
+
"Plang".
|
25
|
+
|
26
|
+
plong(_) ->
|
27
|
+
"Plong".
|
28
|
+
|
29
|
+
test_version() ->
|
30
|
+
1.
|
@@ -0,0 +1,50 @@
|
|
1
|
+
-module(raindrops_tests).
|
2
|
+
|
3
|
+
-include_lib("erl_exercism/include/exercism.hrl").
|
4
|
+
-include_lib("eunit/include/eunit.hrl").
|
5
|
+
|
6
|
+
% test cases adapted from `x-common//canonical-data.json` @ version: 1.0.0
|
7
|
+
|
8
|
+
sound_of_1_is_1_test() ->
|
9
|
+
?assert( raindrops:convert(1) =:= "1").
|
10
|
+
sound_of_3_is_Pling_test() ->
|
11
|
+
?assert( raindrops:convert(3) =:= "Pling").
|
12
|
+
sound_of_5_is_Plang_test() ->
|
13
|
+
?assert( raindrops:convert(5) =:= "Plang").
|
14
|
+
sound_of_7_is_Plong_test() ->
|
15
|
+
?assert( raindrops:convert(7) =:= "Plong").
|
16
|
+
|
17
|
+
sound_of_6_is_Pling_test() ->
|
18
|
+
?assert( raindrops:convert(6) =:= "Pling").
|
19
|
+
sound_of_2_to_the_power_3_is_8_test() ->
|
20
|
+
?assert( raindrops:convert(8) =:= "8").
|
21
|
+
sound_of_9_is_Pling_test() ->
|
22
|
+
?assert( raindrops:convert(9) =:= "Pling").
|
23
|
+
sound_of_10_is_Plang_test() ->
|
24
|
+
?assert( raindrops:convert(10) =:= "Plang").
|
25
|
+
sound_of_14_is_Plong_test() ->
|
26
|
+
?assert( raindrops:convert(14) =:= "Plong").
|
27
|
+
|
28
|
+
sound_of_15_is_PlingPlang_test() ->
|
29
|
+
?assert( raindrops:convert(15) =:= "PlingPlang").
|
30
|
+
sound_of_21_is_PlingPlong_test() ->
|
31
|
+
?assert( raindrops:convert(21) =:= "PlingPlong").
|
32
|
+
sound_of_25_is_Plang_test() ->
|
33
|
+
?assert( raindrops:convert(25) =:= "Plang").
|
34
|
+
|
35
|
+
sound_of_27_is_Pling_test() ->
|
36
|
+
?assert( raindrops:convert(27) =:= "Pling").
|
37
|
+
sound_of_35_is_PlangPlong_test() ->
|
38
|
+
?assert( raindrops:convert(35) =:= "PlangPlong").
|
39
|
+
sound_of_49_is_Plong_test() ->
|
40
|
+
?assert( raindrops:convert(49) =:= "Plong").
|
41
|
+
|
42
|
+
sound_of_52_is_52_test() ->
|
43
|
+
?assert( raindrops:convert(52) =:= "52").
|
44
|
+
sound_of_105_is_PlingPlangPlong_test() ->
|
45
|
+
?assert( raindrops:convert(105) =:= "PlingPlangPlong").
|
46
|
+
sound_of_3125_is_Plang_test() ->
|
47
|
+
?assert( raindrops:convert(3125) =:= "Plang").
|
48
|
+
|
49
|
+
version_test() ->
|
50
|
+
?assertMatch(1, raindrops:test_version()).
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// This file was auto-generated based on version 1.
|
1
|
+
// This file was auto-generated based on version 1.1.0 of the canonical data.
|
2
2
|
|
3
3
|
module BobTest
|
4
4
|
|
@@ -41,7 +41,7 @@ let ``Using acronyms in regular speech`` () =
|
|
41
41
|
|
42
42
|
[<Fact(Skip = "Remove to run test")>]
|
43
43
|
let ``Forceful question`` () =
|
44
|
-
response "WHAT THE HELL WERE YOU THINKING?" |> should equal "
|
44
|
+
response "WHAT THE HELL WERE YOU THINKING?" |> should equal "Calm down, I know what I'm doing!"
|
45
45
|
|
46
46
|
[<Fact(Skip = "Remove to run test")>]
|
47
47
|
let ``Shouting numbers`` () =
|
@@ -8,7 +8,13 @@ let response (input: string) =
|
|
8
8
|
let isQuestion = input.Trim().EndsWith "?"
|
9
9
|
|
10
10
|
match input with
|
11
|
-
| _ when isEmpty ->
|
12
|
-
|
13
|
-
| _ when isQuestion ->
|
14
|
-
|
11
|
+
| _ when isEmpty ->
|
12
|
+
"Fine. Be that way!"
|
13
|
+
| _ when isYell && isQuestion ->
|
14
|
+
"Calm down, I know what I'm doing!"
|
15
|
+
| _ when isYell ->
|
16
|
+
"Whoa, chill out!"
|
17
|
+
| _ when isQuestion ->
|
18
|
+
"Sure."
|
19
|
+
| _ ->
|
20
|
+
"Whatever."
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// This file was auto-generated based on version 1.0
|
1
|
+
// This file was auto-generated based on version 1.1.0 of the canonical data.
|
2
2
|
|
3
3
|
module BookStoreTest
|
4
4
|
|
@@ -59,3 +59,7 @@ let ``Three copies of first book and 2 each of remaining`` () =
|
|
59
59
|
let ``Three each of first 2 books and 2 each of remaining books`` () =
|
60
60
|
total [1; 1; 2; 2; 3; 3; 4; 4; 5; 5; 1; 2] |> should equal 75.20
|
61
61
|
|
62
|
+
[<Fact(Skip = "Remove to run test")>]
|
63
|
+
let ``Four groups of four are cheaper than two groups each of five and three`` () =
|
64
|
+
total [1; 1; 2; 2; 3; 3; 4; 5; 1; 1; 2; 2; 3; 3; 4; 5] |> should equal 102.40
|
65
|
+
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// This file was auto-generated based on version 1.0
|
1
|
+
// This file was auto-generated based on version 1.1.0 of the canonical data.
|
2
2
|
|
3
3
|
module RnaTranscriptionTest
|
4
4
|
|
@@ -27,15 +27,3 @@ let ``RNA complement of adenine is uracil`` () =
|
|
27
27
|
let ``RNA complement`` () =
|
28
28
|
toRna "ACGTGGTCTTAA" |> should equal (Some "UGCACCAGAAUU")
|
29
29
|
|
30
|
-
[<Fact(Skip = "Remove to run test")>]
|
31
|
-
let ``Correctly handles invalid input (RNA instead of DNA)`` () =
|
32
|
-
toRna "U" |> should equal None
|
33
|
-
|
34
|
-
[<Fact(Skip = "Remove to run test")>]
|
35
|
-
let ``Correctly handles completely invalid DNA input`` () =
|
36
|
-
toRna "XXX" |> should equal None
|
37
|
-
|
38
|
-
[<Fact(Skip = "Remove to run test")>]
|
39
|
-
let ``Correctly handles partially invalid DNA input`` () =
|
40
|
-
toRna "ACGTXXXCTTAA" |> should equal None
|
41
|
-
|
@@ -37,15 +37,11 @@ let private updateToLatestVersion options =
|
|
37
37
|
Log.Information("Updated repository to latest version.");
|
38
38
|
|
39
39
|
let private downloadData options =
|
40
|
-
if options.
|
40
|
+
if options.CacheCanonicalData then
|
41
41
|
()
|
42
42
|
else
|
43
43
|
cloneRepository options
|
44
|
-
updateToLatestVersion options
|
45
|
-
|
46
|
-
let private readCanonicalData options exercise =
|
47
|
-
let exerciseCanonicalDataPath = Path.Combine(options.CanonicalDataDirectory, "exercises", exercise, "canonical-data.json")
|
48
|
-
File.ReadAllText(exerciseCanonicalDataPath)
|
44
|
+
updateToLatestVersion options
|
49
45
|
|
50
46
|
type CanonicalDataConverter() =
|
51
47
|
inherit JsonConverter()
|
@@ -87,7 +83,18 @@ type CanonicalDataConverter() =
|
|
87
83
|
override __.CanConvert(objectType: Type) = objectType = typeof<CanonicalData>
|
88
84
|
|
89
85
|
let private convertCanonicalData canonicalDataContents =
|
90
|
-
JsonConvert.DeserializeObject<CanonicalData>(canonicalDataContents, CanonicalDataConverter())
|
86
|
+
JsonConvert.DeserializeObject<CanonicalData>(canonicalDataContents, CanonicalDataConverter())
|
87
|
+
|
88
|
+
let private canonicalDataFile options exercise =
|
89
|
+
Path.Combine(options.CanonicalDataDirectory, "exercises", exercise, "canonical-data.json")
|
90
|
+
|
91
|
+
let private readCanonicalData options exercise =
|
92
|
+
canonicalDataFile options exercise
|
93
|
+
|> File.ReadAllText
|
94
|
+
|
95
|
+
let hasCanonicalData options exercise =
|
96
|
+
canonicalDataFile options exercise
|
97
|
+
|> File.Exists
|
91
98
|
|
92
99
|
let parseCanonicalData options =
|
93
100
|
downloadData options
|
@@ -3,14 +3,19 @@ module Generators.Exercise
|
|
3
3
|
open System
|
4
4
|
open System.IO
|
5
5
|
open System.Reflection
|
6
|
+
open Newtonsoft.Json
|
6
7
|
open Newtonsoft.Json.Linq
|
7
8
|
open Humanizer
|
8
9
|
open Serilog
|
9
10
|
open Formatting
|
10
11
|
open Rendering
|
12
|
+
open CanonicalData
|
13
|
+
|
14
|
+
let private exerciseNameFromType (exerciseType: Type) = exerciseType.Name.Kebaberize()
|
11
15
|
|
12
16
|
[<AbstractClass>]
|
13
|
-
type
|
17
|
+
type GeneratorExercise() =
|
18
|
+
|
14
19
|
// Allow changes in canonical data
|
15
20
|
abstract member MapCanonicalData : CanonicalData -> CanonicalData
|
16
21
|
abstract member MapCanonicalDataCase : CanonicalDataCase -> CanonicalDataCase
|
@@ -56,7 +61,7 @@ type Exercise() =
|
|
56
61
|
abstract member UseFullMethodName : CanonicalDataCase -> bool
|
57
62
|
abstract member AdditionalNamespaces : string list
|
58
63
|
|
59
|
-
member this.Name = this.GetType()
|
64
|
+
member this.Name = this.GetType() |> exerciseNameFromType
|
60
65
|
member this.TestModuleName = this.GetType().Name.Pascalize() |> sprintf "%sTest"
|
61
66
|
member this.TestedModuleName = this.GetType().Name.Pascalize()
|
62
67
|
|
@@ -66,8 +71,6 @@ type Exercise() =
|
|
66
71
|
Directory.CreateDirectory(Path.GetDirectoryName(testClassPath)) |> ignore
|
67
72
|
File.WriteAllText(testClassPath, contents)
|
68
73
|
|
69
|
-
Log.Information("Generated tests for {Exercise} exercise in {TestClassPath}", this.Name, testClassPath);
|
70
|
-
|
71
74
|
member this.Regenerate(canonicalData) =
|
72
75
|
canonicalData
|
73
76
|
|> this.MapCanonicalData
|
@@ -233,23 +236,86 @@ type Exercise() =
|
|
233
236
|
default __.UseFullMethodName _ = false
|
234
237
|
|
235
238
|
default __.AdditionalNamespaces = []
|
239
|
+
|
240
|
+
type CustomExercise() =
|
241
|
+
|
242
|
+
member this.Name = this.GetType().Name.Kebaberize()
|
243
|
+
|
244
|
+
type MissingDataExercise = { Name: string }
|
245
|
+
|
246
|
+
type UnimplementedExercise = { Name: string }
|
247
|
+
|
248
|
+
type Exercise =
|
249
|
+
| Generator of GeneratorExercise
|
250
|
+
| Custom of CustomExercise
|
251
|
+
| MissingData of MissingDataExercise
|
252
|
+
| Unimplemented of UnimplementedExercise
|
253
|
+
|
254
|
+
let exerciseName exercise =
|
255
|
+
match exercise with
|
256
|
+
| Generator generator -> generator.Name
|
257
|
+
| Custom custom -> custom.Name
|
258
|
+
| Unimplemented unimplemented -> unimplemented.Name
|
259
|
+
| MissingData missingData -> missingData.Name
|
260
|
+
|
261
|
+
type ConfigExercise = { Slug: string }
|
262
|
+
|
263
|
+
type Config = { Exercises: ConfigExercise[] }
|
264
|
+
|
265
|
+
let private exerciseNames =
|
266
|
+
let configFilePath = "../config.json"
|
267
|
+
let configFileContents = File.ReadAllText configFilePath
|
268
|
+
let config = JsonConvert.DeserializeObject<Config>(configFileContents)
|
269
|
+
|
270
|
+
config.Exercises
|
271
|
+
|> Seq.map (fun exercise -> exercise.Slug)
|
272
|
+
|> Seq.sort
|
273
|
+
|> Seq.toList
|
236
274
|
|
237
|
-
let
|
275
|
+
let private isConcreteType (ty: Type) = not ty.IsAbstract
|
238
276
|
|
239
|
-
|
240
|
-
not exerciseType.IsAbstract && typeof<Exercise>.IsAssignableFrom(exerciseType)
|
277
|
+
let private isGeneratorExercise (ty: Type) = typeof<GeneratorExercise>.IsAssignableFrom(ty)
|
241
278
|
|
242
|
-
|
243
|
-
String.equals exercise exerciseType.Name ||
|
244
|
-
String.equals exercise (exerciseType.Name.Kebaberize())
|
279
|
+
let private isCustomExercise (ty: Type) = typeof<CustomExercise>.IsAssignableFrom(ty)
|
245
280
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
| Some exercise -> isConcreteExercise exerciseType && isFilteredExercise exercise exerciseType
|
281
|
+
let private concreteAssemblyTypes =
|
282
|
+
Assembly.GetEntryAssembly().GetTypes()
|
283
|
+
|> Array.filter isConcreteType
|
250
284
|
|
251
|
-
|
285
|
+
let private exerciseTypeByName<'T> exerciseType =
|
286
|
+
(exerciseNameFromType exerciseType, Activator.CreateInstance(exerciseType) :?> 'T)
|
252
287
|
|
253
|
-
|
254
|
-
|
255
|
-
|
288
|
+
let private exerciseTypesByName<'T> predicate =
|
289
|
+
concreteAssemblyTypes
|
290
|
+
|> Array.filter predicate
|
291
|
+
|> Array.map exerciseTypeByName<'T>
|
292
|
+
|> Map.ofArray
|
293
|
+
|
294
|
+
let private generatorExercises = exerciseTypesByName<GeneratorExercise> isGeneratorExercise
|
295
|
+
|
296
|
+
let private customExercises = exerciseTypesByName<CustomExercise> isCustomExercise
|
297
|
+
|
298
|
+
let private tryFindGeneratorExercise exerciseName =
|
299
|
+
generatorExercises
|
300
|
+
|> Map.tryFind exerciseName
|
301
|
+
|> Option.map Generator
|
302
|
+
|
303
|
+
let private tryFindCustomExercise exerciseName =
|
304
|
+
customExercises
|
305
|
+
|> Map.tryFind exerciseName
|
306
|
+
|> Option.map Custom
|
307
|
+
|
308
|
+
let private tryFindUnimplementedExercise options exerciseName =
|
309
|
+
match hasCanonicalData options exerciseName with
|
310
|
+
| true -> Unimplemented { Name = exerciseName } |> Some
|
311
|
+
| false -> None
|
312
|
+
|
313
|
+
let private createExercise options exerciseName =
|
314
|
+
tryFindGeneratorExercise exerciseName
|
315
|
+
|> Option.orElse (tryFindCustomExercise exerciseName)
|
316
|
+
|> Option.orElse (tryFindUnimplementedExercise options exerciseName)
|
317
|
+
|> Option.orElse (MissingData { Name = exerciseName } |> Some)
|
318
|
+
|
319
|
+
let createExercises options =
|
320
|
+
exerciseNames
|
321
|
+
|> List.choose (createExercise options)
|
@@ -7,13 +7,13 @@ open Formatting
|
|
7
7
|
open Exercise
|
8
8
|
|
9
9
|
type Acronym() =
|
10
|
-
inherit
|
10
|
+
inherit GeneratorExercise()
|
11
11
|
|
12
12
|
type AtbashCipher() =
|
13
|
-
inherit
|
13
|
+
inherit GeneratorExercise()
|
14
14
|
|
15
15
|
type AllYourBase() =
|
16
|
-
inherit
|
16
|
+
inherit GeneratorExercise()
|
17
17
|
|
18
18
|
override __.RenderExpected (_, _, value) =
|
19
19
|
value
|
@@ -23,7 +23,7 @@ type AllYourBase() =
|
|
23
23
|
override this.PropertiesWithIdentifier canonicalDataCase = this.Properties canonicalDataCase
|
24
24
|
|
25
25
|
type Allergies() =
|
26
|
-
inherit
|
26
|
+
inherit GeneratorExercise()
|
27
27
|
|
28
28
|
let toAllergen (jToken: JToken) = sprintf "Allergen.%s" (jToken.ToString() |> String.humanize)
|
29
29
|
|
@@ -59,7 +59,7 @@ type Allergies() =
|
|
59
59
|
| _ -> base.RenderInput (canonicalDataCase, key, value)
|
60
60
|
|
61
61
|
type Alphametics() =
|
62
|
-
inherit
|
62
|
+
inherit GeneratorExercise()
|
63
63
|
|
64
64
|
member __.formatMap<'TKey, 'TValue> (value: obj) =
|
65
65
|
if isNull value then
|
@@ -82,19 +82,19 @@ type Alphametics() =
|
|
82
82
|
override this.PropertiesWithIdentifier canonicalDataCase = this.Properties canonicalDataCase
|
83
83
|
|
84
84
|
type Anagram() =
|
85
|
-
inherit
|
85
|
+
inherit GeneratorExercise()
|
86
86
|
|
87
87
|
override __.PropertiesWithIdentifier _ = ["candidates"]
|
88
88
|
|
89
89
|
type ArmstrongNumbers() =
|
90
|
-
inherit
|
90
|
+
inherit GeneratorExercise()
|
91
91
|
|
92
92
|
override __.RenderInput (_, _, value) =
|
93
93
|
(value :?> JToken).Value("number")
|
94
94
|
|> formatValue
|
95
95
|
|
96
96
|
type BeerSong() =
|
97
|
-
inherit
|
97
|
+
inherit GeneratorExercise()
|
98
98
|
|
99
99
|
override __.PropertiesUsedAsSutParameter _ = ["startBottles"; "takeDown"]
|
100
100
|
|
@@ -107,7 +107,7 @@ type BeerSong() =
|
|
107
107
|
|> formatMultiLineList
|
108
108
|
|
109
109
|
type BinarySearch() =
|
110
|
-
inherit
|
110
|
+
inherit GeneratorExercise()
|
111
111
|
|
112
112
|
override __.PropertiesWithIdentifier _ = ["array"; "value"; "expected"]
|
113
113
|
|
@@ -123,10 +123,10 @@ type BinarySearch() =
|
|
123
123
|
base.RenderValueWithoutIdentifier (canonicalDataCase, key, value)
|
124
124
|
|
125
125
|
type Bob() =
|
126
|
-
inherit
|
126
|
+
inherit GeneratorExercise()
|
127
127
|
|
128
128
|
type BookStore() =
|
129
|
-
inherit
|
129
|
+
inherit GeneratorExercise()
|
130
130
|
|
131
131
|
let formatFloat (value:obj) = value :?> float |> sprintf "%.2f"
|
132
132
|
|
@@ -136,10 +136,10 @@ type BookStore() =
|
|
136
136
|
base.PropertiesUsedAsSutParameter canonicalDataCase |> List.except ["targetgrouping"]
|
137
137
|
|
138
138
|
type BracketPush() =
|
139
|
-
inherit
|
139
|
+
inherit GeneratorExercise()
|
140
140
|
|
141
141
|
type Change() =
|
142
|
-
inherit
|
142
|
+
inherit GeneratorExercise()
|
143
143
|
|
144
144
|
override __.RenderExpected (_, _, value) =
|
145
145
|
let convertToOption = if value :? JArray then Option.ofObj else Option.ofNonNegativeInt
|
@@ -156,7 +156,7 @@ type Change() =
|
|
156
156
|
| _ -> None
|
157
157
|
|
158
158
|
type Clock() =
|
159
|
-
inherit
|
159
|
+
inherit GeneratorExercise()
|
160
160
|
|
161
161
|
let createClock (value:obj) clockId =
|
162
162
|
let clock = value :?> JObject
|
@@ -196,7 +196,7 @@ type Clock() =
|
|
196
196
|
base.RenderSut canonicalDataCase
|
197
197
|
|
198
198
|
type Connect() =
|
199
|
-
inherit
|
199
|
+
inherit GeneratorExercise()
|
200
200
|
|
201
201
|
override __.RenderExpected (_, _, value) =
|
202
202
|
match string value with
|
@@ -215,7 +215,7 @@ type Connect() =
|
|
215
215
|
override this.PropertiesWithIdentifier canonicalDataCase = this.PropertiesUsedAsSutParameter canonicalDataCase
|
216
216
|
|
217
217
|
type CollatzConjecture() =
|
218
|
-
inherit
|
218
|
+
inherit GeneratorExercise()
|
219
219
|
|
220
220
|
override __.RenderExpected (_, _, value) =
|
221
221
|
value
|
@@ -224,13 +224,16 @@ type CollatzConjecture() =
|
|
224
224
|
|> parenthesizeOption
|
225
225
|
|
226
226
|
type CryptoSquare() =
|
227
|
-
inherit
|
227
|
+
inherit GeneratorExercise()
|
228
|
+
|
229
|
+
type Diamond() =
|
230
|
+
inherit CustomExercise()
|
228
231
|
|
229
232
|
type DifferenceOfSquares() =
|
230
|
-
inherit
|
233
|
+
inherit GeneratorExercise()
|
231
234
|
|
232
235
|
type Dominoes() =
|
233
|
-
inherit
|
236
|
+
inherit GeneratorExercise()
|
234
237
|
|
235
238
|
let formatAsTuple (value:obj) =
|
236
239
|
let twoElementList = value :?> JArray |> normalizeJArray
|
@@ -245,7 +248,7 @@ type Dominoes() =
|
|
245
248
|
override this.PropertiesWithIdentifier canonicalDataCase = this.PropertiesUsedAsSutParameter canonicalDataCase
|
246
249
|
|
247
250
|
type Etl() =
|
248
|
-
inherit
|
251
|
+
inherit GeneratorExercise()
|
249
252
|
|
250
253
|
member __.formatMap<'TKey, 'TValue> (value: obj) =
|
251
254
|
let input = value :?> JObject
|
@@ -267,7 +270,7 @@ type Etl() =
|
|
267
270
|
override this.PropertiesWithIdentifier canonicalDataCase = this.Properties canonicalDataCase
|
268
271
|
|
269
272
|
type FoodChain() =
|
270
|
-
inherit
|
273
|
+
inherit GeneratorExercise()
|
271
274
|
|
272
275
|
override __.PropertiesUsedAsSutParameter _ = ["startVerse"; "endVerse"]
|
273
276
|
|
@@ -280,7 +283,7 @@ type FoodChain() =
|
|
280
283
|
|> formatMultiLineList
|
281
284
|
|
282
285
|
type Forth() =
|
283
|
-
inherit
|
286
|
+
inherit GeneratorExercise()
|
284
287
|
|
285
288
|
override __.PropertiesWithIdentifier _ = ["expected"]
|
286
289
|
|
@@ -297,7 +300,7 @@ type Forth() =
|
|
297
300
|
override __.UseFullMethodName _ = true
|
298
301
|
|
299
302
|
type Gigasecond() =
|
300
|
-
inherit
|
303
|
+
inherit GeneratorExercise()
|
301
304
|
|
302
305
|
override __.RenderExpected (_, _, value) = value :?> DateTime |> formatDateTime |> parenthesize
|
303
306
|
|
@@ -309,7 +312,7 @@ type Gigasecond() =
|
|
309
312
|
override __.AdditionalNamespaces = [typeof<DateTime>.Namespace]
|
310
313
|
|
311
314
|
type Grains() =
|
312
|
-
inherit
|
315
|
+
inherit GeneratorExercise()
|
313
316
|
|
314
317
|
override __.PropertiesWithIdentifier _ = ["expected"]
|
315
318
|
|
@@ -321,7 +324,7 @@ type Grains() =
|
|
321
324
|
| x -> sprintf "Ok %sUL" x
|
322
325
|
|
323
326
|
type Hamming() =
|
324
|
-
inherit
|
327
|
+
inherit GeneratorExercise()
|
325
328
|
|
326
329
|
override __.RenderExpected (_, _, value) =
|
327
330
|
value
|
@@ -330,10 +333,10 @@ type Hamming() =
|
|
330
333
|
|> parenthesizeOption
|
331
334
|
|
332
335
|
type HelloWorld() =
|
333
|
-
inherit
|
336
|
+
inherit GeneratorExercise()
|
334
337
|
|
335
338
|
type House() =
|
336
|
-
inherit
|
339
|
+
inherit GeneratorExercise()
|
337
340
|
|
338
341
|
override __.PropertiesUsedAsSutParameter _ = ["startVerse"; "endVerse"]
|
339
342
|
|
@@ -346,13 +349,13 @@ type House() =
|
|
346
349
|
|> formatMultiLineList
|
347
350
|
|
348
351
|
type IsbnVerifier() =
|
349
|
-
inherit
|
352
|
+
inherit GeneratorExercise()
|
350
353
|
|
351
354
|
type Isogram() =
|
352
|
-
inherit
|
355
|
+
inherit GeneratorExercise()
|
353
356
|
|
354
357
|
type KindergartenGarden() =
|
355
|
-
inherit
|
358
|
+
inherit GeneratorExercise()
|
356
359
|
|
357
360
|
let toPlant (jToken: JToken) = sprintf "Plant.%s" (jToken.ToString() |> String.humanize)
|
358
361
|
|
@@ -366,7 +369,7 @@ type KindergartenGarden() =
|
|
366
369
|
override __.UseFullMethodName _ = true
|
367
370
|
|
368
371
|
type LargestSeriesProduct() =
|
369
|
-
inherit
|
372
|
+
inherit GeneratorExercise()
|
370
373
|
|
371
374
|
override this.PropertiesWithIdentifier canonicalDataCase = this.PropertiesUsedAsSutParameter canonicalDataCase
|
372
375
|
|
@@ -377,13 +380,13 @@ type LargestSeriesProduct() =
|
|
377
380
|
|> parenthesizeOption
|
378
381
|
|
379
382
|
type Leap() =
|
380
|
-
inherit
|
383
|
+
inherit GeneratorExercise()
|
381
384
|
|
382
385
|
type Luhn() =
|
383
|
-
inherit
|
386
|
+
inherit GeneratorExercise()
|
384
387
|
|
385
388
|
type Markdown() =
|
386
|
-
inherit
|
389
|
+
inherit GeneratorExercise()
|
387
390
|
|
388
391
|
override __.ToTestMethod (index, canonicalDataCase) =
|
389
392
|
{ base.ToTestMethod (index, canonicalDataCase) with Skip = false }
|
@@ -391,7 +394,7 @@ type Markdown() =
|
|
391
394
|
override this.PropertiesWithIdentifier canonicalDataCase = this.Properties canonicalDataCase
|
392
395
|
|
393
396
|
type Meetup() =
|
394
|
-
inherit
|
397
|
+
inherit GeneratorExercise()
|
395
398
|
|
396
399
|
override __.RenderExpected (canonicalDataCase, _, _) =
|
397
400
|
let year = canonicalDataCase.Properties.["year"] :?> int64 |> int
|
@@ -417,7 +420,7 @@ type Meetup() =
|
|
417
420
|
override this.AdditionalNamespaces = [typeof<DateTime>.Namespace]
|
418
421
|
|
419
422
|
type Minesweeper() =
|
420
|
-
inherit
|
423
|
+
inherit GeneratorExercise()
|
421
424
|
|
422
425
|
override __.RenderValueWithoutIdentifier (_, _, value) =
|
423
426
|
value :?> JArray
|
@@ -433,7 +436,7 @@ type Minesweeper() =
|
|
433
436
|
| false -> None
|
434
437
|
|
435
438
|
type NthPrime() =
|
436
|
-
inherit
|
439
|
+
inherit GeneratorExercise()
|
437
440
|
|
438
441
|
override __.RenderExpected (_, _, value) =
|
439
442
|
value
|
@@ -442,7 +445,7 @@ type NthPrime() =
|
|
442
445
|
|> parenthesizeOption
|
443
446
|
|
444
447
|
type NucleotideCount() =
|
445
|
-
inherit
|
448
|
+
inherit GeneratorExercise()
|
446
449
|
|
447
450
|
member __.formatMap<'TKey, 'TValue> (value: obj) =
|
448
451
|
match Option.ofNonError value with
|
@@ -466,7 +469,7 @@ type NucleotideCount() =
|
|
466
469
|
override this.PropertiesWithIdentifier canonicalDataCase = this.Properties canonicalDataCase
|
467
470
|
|
468
471
|
type OcrNumbers() =
|
469
|
-
inherit
|
472
|
+
inherit GeneratorExercise()
|
470
473
|
|
471
474
|
override this.PropertiesWithIdentifier canonicalDataCase = this.PropertiesUsedAsSutParameter canonicalDataCase
|
472
475
|
|
@@ -483,10 +486,10 @@ type OcrNumbers() =
|
|
483
486
|
|> formatMultiLineList
|
484
487
|
|
485
488
|
type Pangram() =
|
486
|
-
inherit
|
489
|
+
inherit GeneratorExercise()
|
487
490
|
|
488
491
|
type PalindromeProducts() =
|
489
|
-
inherit
|
492
|
+
inherit GeneratorExercise()
|
490
493
|
|
491
494
|
let toFactors (value: obj) =
|
492
495
|
let jArray = value :?> JArray
|
@@ -514,7 +517,7 @@ type PalindromeProducts() =
|
|
514
517
|
override __.PropertiesUsedAsSutParameter _ = ["input_min"; "input_max"]
|
515
518
|
|
516
519
|
type PascalsTriangle() =
|
517
|
-
inherit
|
520
|
+
inherit GeneratorExercise()
|
518
521
|
|
519
522
|
override __.PropertiesWithIdentifier _ = ["expected"]
|
520
523
|
|
@@ -544,7 +547,7 @@ type PascalsTriangle() =
|
|
544
547
|
override __.ToTestMethodBodyAssertTemplate _ = "AssertEqual"
|
545
548
|
|
546
549
|
type PerfectNumbers() =
|
547
|
-
inherit
|
550
|
+
inherit GeneratorExercise()
|
548
551
|
|
549
552
|
let toClassification value = string value |> String.humanize
|
550
553
|
|
@@ -556,7 +559,7 @@ type PerfectNumbers() =
|
|
556
559
|
|> parenthesizeOption
|
557
560
|
|
558
561
|
type PhoneNumber() =
|
559
|
-
inherit
|
562
|
+
inherit GeneratorExercise()
|
560
563
|
|
561
564
|
override __.RenderExpected (_, _, value) =
|
562
565
|
value
|
@@ -565,21 +568,21 @@ type PhoneNumber() =
|
|
565
568
|
|> parenthesizeOption
|
566
569
|
|
567
570
|
type PigLatin() =
|
568
|
-
inherit
|
571
|
+
inherit GeneratorExercise()
|
569
572
|
|
570
573
|
type Poker() =
|
571
|
-
inherit
|
574
|
+
inherit GeneratorExercise()
|
572
575
|
|
573
576
|
override __.PropertiesWithIdentifier _ = ["input"; "expected"]
|
574
577
|
|
575
578
|
type PrimeFactors() =
|
576
|
-
inherit
|
579
|
+
inherit GeneratorExercise()
|
577
580
|
|
578
581
|
override __.RenderInput (canonicalDataCase, key, value) =
|
579
582
|
base.RenderInput (canonicalDataCase, key, value) |> sprintf "%sL"
|
580
583
|
|
581
584
|
type Proverb() =
|
582
|
-
inherit
|
585
|
+
inherit GeneratorExercise()
|
583
586
|
|
584
587
|
override __.PropertiesWithIdentifier _ = ["input"; "expected"]
|
585
588
|
|
@@ -595,7 +598,7 @@ type Proverb() =
|
|
595
598
|
| false -> None
|
596
599
|
|
597
600
|
type QueenAttack() =
|
598
|
-
inherit
|
601
|
+
inherit GeneratorExercise()
|
599
602
|
|
600
603
|
override __.MapCanonicalDataCaseProperty (canonicalDataCase, key, value) =
|
601
604
|
match canonicalDataCase.Property, key, value with
|
@@ -614,17 +617,17 @@ type QueenAttack() =
|
|
614
617
|
override __.PropertiesWithIdentifier _ = ["white_queen"; "black_queen"]
|
615
618
|
|
616
619
|
type RailFenceCipher() =
|
617
|
-
inherit
|
620
|
+
inherit GeneratorExercise()
|
618
621
|
|
619
622
|
override __.PropertiesUsedAsSutParameter _ = ["rails"; "msg"]
|
620
623
|
|
621
624
|
override this.PropertiesWithIdentifier canonicalDataCase = this.Properties canonicalDataCase
|
622
625
|
|
623
626
|
type Raindrops() =
|
624
|
-
inherit
|
627
|
+
inherit GeneratorExercise()
|
625
628
|
|
626
629
|
type Rectangles() =
|
627
|
-
inherit
|
630
|
+
inherit GeneratorExercise()
|
628
631
|
|
629
632
|
member private __.GetPadding n =
|
630
633
|
String.replicate n " "
|
@@ -653,10 +656,10 @@ type Rectangles() =
|
|
653
656
|
base.RenderValueWithoutIdentifier (canonicalDataCase, key, value)
|
654
657
|
|
655
658
|
type ReverseString() =
|
656
|
-
inherit
|
659
|
+
inherit GeneratorExercise()
|
657
660
|
|
658
661
|
type RobotSimulator() =
|
659
|
-
inherit
|
662
|
+
inherit GeneratorExercise()
|
660
663
|
|
661
664
|
let resultIdentifierName = "actual"
|
662
665
|
|
@@ -748,16 +751,16 @@ type RobotSimulator() =
|
|
748
751
|
sprintf "%s - %s" canonicalDataCase.Property (canonicalDataCase.Description |> String.upperCaseFirst)
|
749
752
|
|
750
753
|
type RotationalCipher() =
|
751
|
-
inherit
|
754
|
+
inherit GeneratorExercise()
|
752
755
|
|
753
756
|
type RnaTranscription() =
|
754
|
-
inherit
|
757
|
+
inherit GeneratorExercise()
|
755
758
|
|
756
759
|
override __.RenderExpected (_, _, value) =
|
757
760
|
value |> Option.ofObj |> formatValue |> parenthesizeOption
|
758
761
|
|
759
762
|
type RunLengthEncoding() =
|
760
|
-
inherit
|
763
|
+
inherit GeneratorExercise()
|
761
764
|
|
762
765
|
override this.RenderSut canonicalDataCase =
|
763
766
|
match canonicalDataCase.Property with
|
@@ -775,13 +778,13 @@ type RunLengthEncoding() =
|
|
775
778
|
sprintf "%s %s" canonicalDataCase.Property canonicalDataCase.Description |> String.upperCaseFirst
|
776
779
|
|
777
780
|
type RomanNumerals() =
|
778
|
-
inherit
|
781
|
+
inherit GeneratorExercise()
|
779
782
|
|
780
783
|
type ScrabbleScore() =
|
781
|
-
inherit
|
784
|
+
inherit GeneratorExercise()
|
782
785
|
|
783
786
|
type SpiralMatrix() =
|
784
|
-
inherit
|
787
|
+
inherit GeneratorExercise()
|
785
788
|
|
786
789
|
override __.RenderExpected (_, _, value) =
|
787
790
|
(value :?> JArray)
|
@@ -790,7 +793,7 @@ type SpiralMatrix() =
|
|
790
793
|
|> formatMultiLineList
|
791
794
|
|
792
795
|
type TwelveDays() =
|
793
|
-
inherit
|
796
|
+
inherit GeneratorExercise()
|
794
797
|
|
795
798
|
override __.PropertiesUsedAsSutParameter _ = ["startVerse"; "endVerse"]
|
796
799
|
|
@@ -803,7 +806,7 @@ type TwelveDays() =
|
|
803
806
|
|> formatMultiLineList
|
804
807
|
|
805
808
|
type TwoFer() =
|
806
|
-
inherit
|
809
|
+
inherit GeneratorExercise()
|
807
810
|
|
808
811
|
override __.RenderInput (_, _, value) =
|
809
812
|
value |> Option.ofObj |> formatValue |> parenthesizeOption
|