trackler 2.2.1.75 → 2.2.1.76
Sign up to get free protection for your applications and to get access to all the features.
- 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
|