trackler 2.0.8.22 → 2.0.8.23
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/tracks/csharp/exercises/accumulate/HINTS.md +1 -2
- data/tracks/csharp/exercises/nth-prime/HINTS.md +7 -0
- data/tracks/csharp/exercises/proverb/HINTS.md +3 -0
- data/tracks/go/exercises/trinary/trinary_test.go +1 -1
- data/tracks/go/exercises/twelve-days/twelve_days_test.go +6 -6
- data/tracks/java/.Rhistory +0 -0
- data/tracks/java/config.json +12 -0
- data/tracks/java/exercises/book-store/build.gradle +17 -0
- data/tracks/java/exercises/book-store/src/example/java/.keep +0 -0
- data/tracks/java/exercises/book-store/src/example/java/Bookstore.java +61 -0
- data/tracks/java/exercises/book-store/src/main/java/.keep +0 -0
- data/tracks/java/exercises/book-store/src/test/java/.keep +0 -0
- data/tracks/java/exercises/book-store/src/test/java/BookstoreTest.java +117 -0
- data/tracks/java/exercises/hamming/src/example/java/Hamming.java +11 -2
- data/tracks/java/exercises/hamming/src/test/java/HammingTest.java +9 -10
- data/tracks/java/exercises/isogram/build.gradle +17 -0
- data/tracks/java/exercises/isogram/src/example/java/IsogramChecker.java +34 -0
- data/tracks/java/exercises/isogram/src/main/java/.keep +0 -0
- data/tracks/java/exercises/isogram/src/test/java/IsogramTest.java +80 -0
- data/tracks/java/exercises/raindrops/src/example/java/{Raindrops.java → RaindropConverter.java} +2 -2
- data/tracks/java/exercises/raindrops/src/test/java/{RaindropsTest.java → RaindropConverterTest.java} +3 -3
- data/tracks/java/exercises/settings.gradle +2 -0
- data/tracks/ocaml/.vscode/launch.json +13 -0
- data/tracks/ocaml/config.json +5 -0
- data/tracks/ocaml/exercises/beer-song/test.ml +15 -7
- data/tracks/ocaml/exercises/phone-number/test.ml +2 -2
- data/tracks/ocaml/exercises/prime-factors/test.ml +20 -16
- data/tracks/ocaml/exercises/roman-numerals/test.ml +40 -22
- data/tracks/ocaml/exercises/run-length-encoding/test.ml +6 -4
- data/tracks/ocaml/exercises/space-age/test.ml +20 -35
- data/tracks/ocaml/exercises/triangle/.merlin +5 -0
- data/tracks/ocaml/exercises/triangle/Makefile +11 -0
- data/tracks/ocaml/exercises/triangle/example.ml +17 -0
- data/tracks/ocaml/exercises/triangle/test.ml +48 -0
- data/tracks/ocaml/exercises/triangle/triangle.mli +5 -0
- data/tracks/ocaml/tools/test-generator/.merlin +0 -1
- data/tracks/ocaml/tools/test-generator/Makefile +3 -0
- data/tracks/ocaml/tools/test-generator/src/codegen.ml +1 -1
- data/tracks/ocaml/tools/test-generator/src/controller.ml +22 -10
- data/tracks/ocaml/tools/test-generator/src/debug.ml +12 -0
- data/tracks/ocaml/tools/test-generator/src/special_cases.ml +8 -0
- data/tracks/ocaml/tools/test-generator/src/template.ml +91 -41
- data/tracks/ocaml/tools/test-generator/src/test_gen.ml +2 -1
- data/tracks/ocaml/tools/test-generator/templates/atbash-cipher/template.ml +11 -3
- data/tracks/ocaml/tools/test-generator/templates/beer-song/template.ml +13 -3
- data/tracks/ocaml/tools/test-generator/templates/difference-of-squares/template.ml +17 -3
- data/tracks/ocaml/tools/test-generator/templates/prime-factors/template.ml +25 -0
- data/tracks/ocaml/tools/test-generator/templates/roman-numerals/template.ml +15 -0
- data/tracks/ocaml/tools/test-generator/templates/run-length-encoding/template.ml +19 -3
- data/tracks/ocaml/tools/test-generator/templates/space-age/template.ml +19 -0
- data/tracks/ocaml/tools/test-generator/templates/triangle/template.ml +33 -0
- data/tracks/ocaml/tools/test-generator/test/template_test.ml +8 -7
- data/tracks/powershell/exercises/hamming/hamming.tests.ps1 +4 -4
- metadata +28 -4
@@ -25,22 +25,30 @@ let zip s1 s2 =
|
|
25
25
|
|
26
26
|
let verse_tests = [
|
27
27
|
"first generic verse" >::
|
28
|
-
ae "99 bottles of beer on the wall, 99 bottles of beer.\nTake one down and pass it around, 98 bottles of beer on the wall.\n"
|
28
|
+
ae "99 bottles of beer on the wall, 99 bottles of beer.\nTake one down and pass it around, 98 bottles of beer on the wall.\n"
|
29
|
+
(verse 99);
|
29
30
|
"last generic verse" >::
|
30
|
-
ae "3 bottles of beer on the wall, 3 bottles of beer.\nTake one down and pass it around, 2 bottles of beer on the wall.\n"
|
31
|
+
ae "3 bottles of beer on the wall, 3 bottles of beer.\nTake one down and pass it around, 2 bottles of beer on the wall.\n"
|
32
|
+
(verse 3);
|
31
33
|
"verse 2" >::
|
32
|
-
ae "2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n"
|
34
|
+
ae "2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n"
|
35
|
+
(verse 2);
|
33
36
|
"verse 1" >::
|
34
|
-
ae "1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n"
|
37
|
+
ae "1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n"
|
38
|
+
(verse 1);
|
35
39
|
"verse 0" >::
|
36
|
-
ae "No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n"
|
40
|
+
ae "No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n"
|
41
|
+
(verse 0);
|
37
42
|
]
|
38
43
|
|
44
|
+
|
39
45
|
let lyrics_tests = [
|
40
46
|
"first two verses" >::
|
41
|
-
ae "99 bottles of beer on the wall, 99 bottles of beer.\nTake one down and pass it around, 98 bottles of beer on the wall.\n\n98 bottles of beer on the wall, 98 bottles of beer.\nTake one down and pass it around, 97 bottles of beer on the wall.\n"
|
47
|
+
ae "99 bottles of beer on the wall, 99 bottles of beer.\nTake one down and pass it around, 98 bottles of beer on the wall.\n\n98 bottles of beer on the wall, 98 bottles of beer.\nTake one down and pass it around, 97 bottles of beer on the wall.\n"
|
48
|
+
(lyrics ~from:99 ~until:98);
|
42
49
|
"last three verses" >::
|
43
|
-
ae "2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n\n1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n\nNo more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n"
|
50
|
+
ae "2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n\n1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n\nNo more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n"
|
51
|
+
(lyrics ~from:2 ~until:0);
|
44
52
|
"all verses" >::
|
45
53
|
ae "99 bottles of beer on the wall, 99 bottles of beer.\nTake one down and pass it around, 98 bottles of beer on the wall.\n\n98 bottles of beer on the wall, 98 bottles of beer.\nTake one down and pass it around, 97 bottles of beer on the wall.\n\n97 bottles of beer on the wall, 97 bottles of beer.\nTake one down and pass it around, 96 bottles of beer on the wall.\n\n96 bottles of beer on the wall, 96 bottles of beer.\nTake one down and pass it around, 95 bottles of beer on the wall.\n\n95 bottles of beer on the wall, 95 bottles of beer.\nTake one down and pass it around, 94 bottles of beer on the wall.\n\n94 bottles of beer on the wall, 94 bottles of beer.\nTake one down and pass it around, 93 bottles of beer on the wall.\n\n93 bottles of beer on the wall, 93 bottles of beer.\nTake one down and pass it around, 92 bottles of beer on the wall.\n\n92 bottles of beer on the wall, 92 bottles of beer.\nTake one down and pass it around, 91 bottles of beer on the wall.\n\n91 bottles of beer on the wall, 91 bottles of beer.\nTake one down and pass it around, 90 bottles of beer on the wall.\n\n90 bottles of beer on the wall, 90 bottles of beer.\nTake one down and pass it around, 89 bottles of beer on the wall.\n\n89 bottles of beer on the wall, 89 bottles of beer.\nTake one down and pass it around, 88 bottles of beer on the wall.\n\n88 bottles of beer on the wall, 88 bottles of beer.\nTake one down and pass it around, 87 bottles of beer on the wall.\n\n87 bottles of beer on the wall, 87 bottles of beer.\nTake one down and pass it around, 86 bottles of beer on the wall.\n\n86 bottles of beer on the wall, 86 bottles of beer.\nTake one down and pass it around, 85 bottles of beer on the wall.\n\n85 bottles of beer on the wall, 85 bottles of beer.\nTake one down and pass it around, 84 bottles of beer on the wall.\n\n84 bottles of beer on the wall, 84 bottles of beer.\nTake one down and pass it around, 83 bottles of beer on the wall.\n\n83 bottles of beer on the wall, 83 bottles of beer.\nTake one down and pass it around, 82 bottles of beer on the wall.\n\n82 bottles of beer on the wall, 82 bottles of beer.\nTake one down and pass it around, 81 bottles of beer on the wall.\n\n81 bottles of beer on the wall, 81 bottles of beer.\nTake one down and pass it around, 80 bottles of beer on the wall.\n\n80 bottles of beer on the wall, 80 bottles of beer.\nTake one down and pass it around, 79 bottles of beer on the wall.\n\n79 bottles of beer on the wall, 79 bottles of beer.\nTake one down and pass it around, 78 bottles of beer on the wall.\n\n78 bottles of beer on the wall, 78 bottles of beer.\nTake one down and pass it around, 77 bottles of beer on the wall.\n\n77 bottles of beer on the wall, 77 bottles of beer.\nTake one down and pass it around, 76 bottles of beer on the wall.\n\n76 bottles of beer on the wall, 76 bottles of beer.\nTake one down and pass it around, 75 bottles of beer on the wall.\n\n75 bottles of beer on the wall, 75 bottles of beer.\nTake one down and pass it around, 74 bottles of beer on the wall.\n\n74 bottles of beer on the wall, 74 bottles of beer.\nTake one down and pass it around, 73 bottles of beer on the wall.\n\n73 bottles of beer on the wall, 73 bottles of beer.\nTake one down and pass it around, 72 bottles of beer on the wall.\n\n72 bottles of beer on the wall, 72 bottles of beer.\nTake one down and pass it around, 71 bottles of beer on the wall.\n\n71 bottles of beer on the wall, 71 bottles of beer.\nTake one down and pass it around, 70 bottles of beer on the wall.\n\n70 bottles of beer on the wall, 70 bottles of beer.\nTake one down and pass it around, 69 bottles of beer on the wall.\n\n69 bottles of beer on the wall, 69 bottles of beer.\nTake one down and pass it around, 68 bottles of beer on the wall.\n\n68 bottles of beer on the wall, 68 bottles of beer.\nTake one down and pass it around, 67 bottles of beer on the wall.\n\n67 bottles of beer on the wall, 67 bottles of beer.\nTake one down and pass it around, 66 bottles of beer on the wall.\n\n66 bottles of beer on the wall, 66 bottles of beer.\nTake one down and pass it around, 65 bottles of beer on the wall.\n\n65 bottles of beer on the wall, 65 bottles of beer.\nTake one down and pass it around, 64 bottles of beer on the wall.\n\n64 bottles of beer on the wall, 64 bottles of beer.\nTake one down and pass it around, 63 bottles of beer on the wall.\n\n63 bottles of beer on the wall, 63 bottles of beer.\nTake one down and pass it around, 62 bottles of beer on the wall.\n\n62 bottles of beer on the wall, 62 bottles of beer.\nTake one down and pass it around, 61 bottles of beer on the wall.\n\n61 bottles of beer on the wall, 61 bottles of beer.\nTake one down and pass it around, 60 bottles of beer on the wall.\n\n60 bottles of beer on the wall, 60 bottles of beer.\nTake one down and pass it around, 59 bottles of beer on the wall.\n\n59 bottles of beer on the wall, 59 bottles of beer.\nTake one down and pass it around, 58 bottles of beer on the wall.\n\n58 bottles of beer on the wall, 58 bottles of beer.\nTake one down and pass it around, 57 bottles of beer on the wall.\n\n57 bottles of beer on the wall, 57 bottles of beer.\nTake one down and pass it around, 56 bottles of beer on the wall.\n\n56 bottles of beer on the wall, 56 bottles of beer.\nTake one down and pass it around, 55 bottles of beer on the wall.\n\n55 bottles of beer on the wall, 55 bottles of beer.\nTake one down and pass it around, 54 bottles of beer on the wall.\n\n54 bottles of beer on the wall, 54 bottles of beer.\nTake one down and pass it around, 53 bottles of beer on the wall.\n\n53 bottles of beer on the wall, 53 bottles of beer.\nTake one down and pass it around, 52 bottles of beer on the wall.\n\n52 bottles of beer on the wall, 52 bottles of beer.\nTake one down and pass it around, 51 bottles of beer on the wall.\n\n51 bottles of beer on the wall, 51 bottles of beer.\nTake one down and pass it around, 50 bottles of beer on the wall.\n\n50 bottles of beer on the wall, 50 bottles of beer.\nTake one down and pass it around, 49 bottles of beer on the wall.\n\n49 bottles of beer on the wall, 49 bottles of beer.\nTake one down and pass it around, 48 bottles of beer on the wall.\n\n48 bottles of beer on the wall, 48 bottles of beer.\nTake one down and pass it around, 47 bottles of beer on the wall.\n\n47 bottles of beer on the wall, 47 bottles of beer.\nTake one down and pass it around, 46 bottles of beer on the wall.\n\n46 bottles of beer on the wall, 46 bottles of beer.\nTake one down and pass it around, 45 bottles of beer on the wall.\n\n45 bottles of beer on the wall, 45 bottles of beer.\nTake one down and pass it around, 44 bottles of beer on the wall.\n\n44 bottles of beer on the wall, 44 bottles of beer.\nTake one down and pass it around, 43 bottles of beer on the wall.\n\n43 bottles of beer on the wall, 43 bottles of beer.\nTake one down and pass it around, 42 bottles of beer on the wall.\n\n42 bottles of beer on the wall, 42 bottles of beer.\nTake one down and pass it around, 41 bottles of beer on the wall.\n\n41 bottles of beer on the wall, 41 bottles of beer.\nTake one down and pass it around, 40 bottles of beer on the wall.\n\n40 bottles of beer on the wall, 40 bottles of beer.\nTake one down and pass it around, 39 bottles of beer on the wall.\n\n39 bottles of beer on the wall, 39 bottles of beer.\nTake one down and pass it around, 38 bottles of beer on the wall.\n\n38 bottles of beer on the wall, 38 bottles of beer.\nTake one down and pass it around, 37 bottles of beer on the wall.\n\n37 bottles of beer on the wall, 37 bottles of beer.\nTake one down and pass it around, 36 bottles of beer on the wall.\n\n36 bottles of beer on the wall, 36 bottles of beer.\nTake one down and pass it around, 35 bottles of beer on the wall.\n\n35 bottles of beer on the wall, 35 bottles of beer.\nTake one down and pass it around, 34 bottles of beer on the wall.\n\n34 bottles of beer on the wall, 34 bottles of beer.\nTake one down and pass it around, 33 bottles of beer on the wall.\n\n33 bottles of beer on the wall, 33 bottles of beer.\nTake one down and pass it around, 32 bottles of beer on the wall.\n\n32 bottles of beer on the wall, 32 bottles of beer.\nTake one down and pass it around, 31 bottles of beer on the wall.\n\n31 bottles of beer on the wall, 31 bottles of beer.\nTake one down and pass it around, 30 bottles of beer on the wall.\n\n30 bottles of beer on the wall, 30 bottles of beer.\nTake one down and pass it around, 29 bottles of beer on the wall.\n\n29 bottles of beer on the wall, 29 bottles of beer.\nTake one down and pass it around, 28 bottles of beer on the wall.\n\n28 bottles of beer on the wall, 28 bottles of beer.\nTake one down and pass it around, 27 bottles of beer on the wall.\n\n27 bottles of beer on the wall, 27 bottles of beer.\nTake one down and pass it around, 26 bottles of beer on the wall.\n\n26 bottles of beer on the wall, 26 bottles of beer.\nTake one down and pass it around, 25 bottles of beer on the wall.\n\n25 bottles of beer on the wall, 25 bottles of beer.\nTake one down and pass it around, 24 bottles of beer on the wall.\n\n24 bottles of beer on the wall, 24 bottles of beer.\nTake one down and pass it around, 23 bottles of beer on the wall.\n\n23 bottles of beer on the wall, 23 bottles of beer.\nTake one down and pass it around, 22 bottles of beer on the wall.\n\n22 bottles of beer on the wall, 22 bottles of beer.\nTake one down and pass it around, 21 bottles of beer on the wall.\n\n21 bottles of beer on the wall, 21 bottles of beer.\nTake one down and pass it around, 20 bottles of beer on the wall.\n\n20 bottles of beer on the wall, 20 bottles of beer.\nTake one down and pass it around, 19 bottles of beer on the wall.\n\n19 bottles of beer on the wall, 19 bottles of beer.\nTake one down and pass it around, 18 bottles of beer on the wall.\n\n18 bottles of beer on the wall, 18 bottles of beer.\nTake one down and pass it around, 17 bottles of beer on the wall.\n\n17 bottles of beer on the wall, 17 bottles of beer.\nTake one down and pass it around, 16 bottles of beer on the wall.\n\n16 bottles of beer on the wall, 16 bottles of beer.\nTake one down and pass it around, 15 bottles of beer on the wall.\n\n15 bottles of beer on the wall, 15 bottles of beer.\nTake one down and pass it around, 14 bottles of beer on the wall.\n\n14 bottles of beer on the wall, 14 bottles of beer.\nTake one down and pass it around, 13 bottles of beer on the wall.\n\n13 bottles of beer on the wall, 13 bottles of beer.\nTake one down and pass it around, 12 bottles of beer on the wall.\n\n12 bottles of beer on the wall, 12 bottles of beer.\nTake one down and pass it around, 11 bottles of beer on the wall.\n\n11 bottles of beer on the wall, 11 bottles of beer.\nTake one down and pass it around, 10 bottles of beer on the wall.\n\n10 bottles of beer on the wall, 10 bottles of beer.\nTake one down and pass it around, 9 bottles of beer on the wall.\n\n9 bottles of beer on the wall, 9 bottles of beer.\nTake one down and pass it around, 8 bottles of beer on the wall.\n\n8 bottles of beer on the wall, 8 bottles of beer.\nTake one down and pass it around, 7 bottles of beer on the wall.\n\n7 bottles of beer on the wall, 7 bottles of beer.\nTake one down and pass it around, 6 bottles of beer on the wall.\n\n6 bottles of beer on the wall, 6 bottles of beer.\nTake one down and pass it around, 5 bottles of beer on the wall.\n\n5 bottles of beer on the wall, 5 bottles of beer.\nTake one down and pass it around, 4 bottles of beer on the wall.\n\n4 bottles of beer on the wall, 4 bottles of beer.\nTake one down and pass it around, 3 bottles of beer on the wall.\n\n3 bottles of beer on the wall, 3 bottles of beer.\nTake one down and pass it around, 2 bottles of beer on the wall.\n\n2 bottles of beer on the wall, 2 bottles of beer.\nTake one down and pass it around, 1 bottle of beer on the wall.\n\n1 bottle of beer on the wall, 1 bottle of beer.\nTake it down and pass it around, no more bottles of beer on the wall.\n\nNo more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, 99 bottles of beer on the wall.\n"
|
46
54
|
(lyrics ~from:99 ~until:0);
|
@@ -18,11 +18,11 @@ let tests = [
|
|
18
18
|
ae (Some "1234567890") (number "123 456 7890 ");
|
19
19
|
"invalid when 9 digits" >::
|
20
20
|
ae None (number "123456789");
|
21
|
-
"invalid when 11 digits" >::
|
21
|
+
"invalid when 11 digits does not start with a 1" >::
|
22
22
|
ae None (number "21234567890");
|
23
23
|
"valid when 11 digits and starting with 1" >::
|
24
24
|
ae (Some "1234567890") (number "11234567890");
|
25
|
-
"invalid when
|
25
|
+
"invalid when more than 11 digits" >::
|
26
26
|
ae None (number "321234567890");
|
27
27
|
"invalid with letters" >::
|
28
28
|
ae None (number "123-abc-7890");
|
@@ -1,31 +1,35 @@
|
|
1
1
|
open Core.Std
|
2
2
|
open OUnit2
|
3
|
+
open Prime_factors
|
3
4
|
|
4
5
|
(* Assert Equals *)
|
5
6
|
let ae exp got _test_ctxt =
|
6
7
|
let printer = List.to_string ~f:Int64.to_string in
|
7
8
|
assert_equal exp got ~printer
|
8
9
|
|
10
|
+
let to_int64s = List.map ~f:Int64.of_int
|
11
|
+
|
9
12
|
(* 64 bits integers are needed for the last number.
|
10
13
|
*
|
11
14
|
* If you happen to use a 64 bits machine normal ints would do as well, but this
|
12
15
|
* works for everybody.
|
13
16
|
*)
|
14
|
-
let
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
17
|
+
let tests = [
|
18
|
+
"no factors" >::
|
19
|
+
ae (to_int64s []) (factors_of 1L);
|
20
|
+
"prime number" >::
|
21
|
+
ae (to_int64s [2]) (factors_of 2L);
|
22
|
+
"square of a prime" >::
|
23
|
+
ae (to_int64s [3; 3]) (factors_of 9L);
|
24
|
+
"cube of a prime" >::
|
25
|
+
ae (to_int64s [2; 2; 2]) (factors_of 8L);
|
26
|
+
"product of primes and non-primes" >::
|
27
|
+
ae (to_int64s [2; 2; 3]) (factors_of 12L);
|
28
|
+
"product of primes" >::
|
29
|
+
ae (to_int64s [5; 17; 23; 461]) (factors_of 901255L);
|
30
|
+
"factors include a large prime" >::
|
31
|
+
ae (to_int64s [11; 9539; 894119]) (factors_of 93819012551L);
|
32
|
+
]
|
29
33
|
|
30
34
|
let () =
|
31
|
-
run_test_tt_main ("prime-factors tests" >::: tests)
|
35
|
+
run_test_tt_main ("prime-factors tests" >::: tests)
|
@@ -2,28 +2,46 @@ open Core.Std
|
|
2
2
|
open OUnit2
|
3
3
|
open Roman_numerals
|
4
4
|
|
5
|
-
let
|
5
|
+
let ae expected actual _ctx = assert_equal ~printer:Fn.id expected actual
|
6
6
|
|
7
|
-
let tests =
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
7
|
+
let tests = [
|
8
|
+
"1 is a single I" >::
|
9
|
+
ae "I" (to_roman 1);
|
10
|
+
"2 is two I's" >::
|
11
|
+
ae "II" (to_roman 2);
|
12
|
+
"3 is three I's" >::
|
13
|
+
ae "III" (to_roman 3);
|
14
|
+
"4, being 5 - 1, is IV" >::
|
15
|
+
ae "IV" (to_roman 4);
|
16
|
+
"5 is a single V" >::
|
17
|
+
ae "V" (to_roman 5);
|
18
|
+
"6, being 5 + 1, is VI" >::
|
19
|
+
ae "VI" (to_roman 6);
|
20
|
+
"9, being 10 - 1, is IX" >::
|
21
|
+
ae "IX" (to_roman 9);
|
22
|
+
"20 is two X's" >::
|
23
|
+
ae "XXVII" (to_roman 27);
|
24
|
+
"48 is not 50 - 2 but rather 40 + 8" >::
|
25
|
+
ae "XLVIII" (to_roman 48);
|
26
|
+
"50 is a single L" >::
|
27
|
+
ae "LIX" (to_roman 59);
|
28
|
+
"90, being 100 - 10, is XC" >::
|
29
|
+
ae "XCIII" (to_roman 93);
|
30
|
+
"100 is a single C" >::
|
31
|
+
ae "CXLI" (to_roman 141);
|
32
|
+
"60, being 50 + 10, is LX" >::
|
33
|
+
ae "CLXIII" (to_roman 163);
|
34
|
+
"400, being 500 - 100, is CD" >::
|
35
|
+
ae "CDII" (to_roman 402);
|
36
|
+
"500 is a single D" >::
|
37
|
+
ae "DLXXV" (to_roman 575);
|
38
|
+
"900, being 1000 - 100, is CM" >::
|
39
|
+
ae "CMXI" (to_roman 911);
|
40
|
+
"1000 is a single M" >::
|
41
|
+
ae "MXXIV" (to_roman 1024);
|
42
|
+
"3000 is three M's" >::
|
43
|
+
ae "MMM" (to_roman 3000);
|
44
|
+
]
|
27
45
|
|
28
46
|
let () =
|
29
|
-
run_test_tt_main ("roman-numerals test" >::: tests)
|
47
|
+
run_test_tt_main ("roman-numerals test" >::: tests)
|
@@ -4,7 +4,7 @@ open Run_length_encoding
|
|
4
4
|
|
5
5
|
let ae exp got _test_ctxt = assert_equal exp got ~printer:Fn.id
|
6
6
|
|
7
|
-
let
|
7
|
+
let encode_tests = [
|
8
8
|
"empty string" >::
|
9
9
|
ae "" (encode "");
|
10
10
|
"single characters only are encoded without count" >::
|
@@ -19,7 +19,8 @@ let run_length_encode_a_string_tests = [
|
|
19
19
|
ae "2a3b4c" (encode "aabbbcccc");
|
20
20
|
]
|
21
21
|
|
22
|
-
|
22
|
+
|
23
|
+
let decode_tests = [
|
23
24
|
"empty string" >::
|
24
25
|
ae "" (decode "");
|
25
26
|
"single characters only" >::
|
@@ -34,13 +35,14 @@ let run_length_decode_a_string_tests = [
|
|
34
35
|
ae "aabbbcccc" (decode "2a3b4c");
|
35
36
|
]
|
36
37
|
|
38
|
+
|
37
39
|
let encode_and_then_decode_tests = [
|
38
40
|
"encode followed by decode gives original string" >::
|
39
|
-
ae "zzz ZZ zZ" (
|
41
|
+
ae "zzz ZZ zZ" (encode "zzz ZZ zZ" |> decode);
|
40
42
|
]
|
41
43
|
|
42
44
|
let () =
|
43
45
|
run_test_tt_main (
|
44
46
|
"run length encoding tests" >:::
|
45
|
-
List.concat [
|
47
|
+
List.concat [encode_tests; decode_tests; encode_and_then_decode_tests]
|
46
48
|
)
|
@@ -3,44 +3,29 @@ open OUnit2
|
|
3
3
|
open Space_age
|
4
4
|
|
5
5
|
(* Assert In Delta *)
|
6
|
-
let
|
6
|
+
let ae ~delta:delta exp got _ctxt =
|
7
7
|
let msg = sprintf "Expected %f got %f, difference is greater than %f"
|
8
8
|
exp got delta in
|
9
9
|
assert_bool msg (cmp_float ~epsilon:delta exp got)
|
10
10
|
|
11
|
-
let tests =
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
aid ~d:0.005 28.58 (age_on Earth input);
|
30
|
-
aid ~d:0.005 2.41 (age_on Jupiter input));
|
31
|
-
"age in Saturn years">:: (fun _ ->
|
32
|
-
let input = 3_000_000_000 in
|
33
|
-
aid ~d:0.005 95.06 (age_on Earth input);
|
34
|
-
aid ~d:0.005 3.23 (age_on Saturn input));
|
35
|
-
"age in Neptune years">:: (fun _ ->
|
36
|
-
let input = 8_210_123_456 in
|
37
|
-
aid ~d:0.005 260.16 (age_on Earth input);
|
38
|
-
aid ~d:0.005 1.58 (age_on Neptune input));
|
39
|
-
"age in Uranus years">:: (fun _ ->
|
40
|
-
let input = 3_210_123_456 in
|
41
|
-
aid ~d:0.005 101.72 (age_on Earth input);
|
42
|
-
aid ~d:0.005 1.21 (age_on Uranus input))
|
43
|
-
]
|
11
|
+
let tests = [
|
12
|
+
"age on Earth" >::
|
13
|
+
ae ~delta:0.005 31.69 (age_on Earth 1000000000);
|
14
|
+
"age on Mercury" >::
|
15
|
+
ae ~delta:0.005 280.88 (age_on Mercury 2134835688);
|
16
|
+
"age on Venus" >::
|
17
|
+
ae ~delta:0.005 9.78 (age_on Venus 189839836);
|
18
|
+
"age on Mars" >::
|
19
|
+
ae ~delta:0.005 39.25 (age_on Mars 2329871239);
|
20
|
+
"age on Jupiter" >::
|
21
|
+
ae ~delta:0.005 2.41 (age_on Jupiter 901876382);
|
22
|
+
"age on Saturn" >::
|
23
|
+
ae ~delta:0.005 3.23 (age_on Saturn 3000000000);
|
24
|
+
"age on Uranus" >::
|
25
|
+
ae ~delta:0.005 1.21 (age_on Uranus 3210123456);
|
26
|
+
"age on Neptune" >::
|
27
|
+
ae ~delta:0.005 1.58 (age_on Neptune 8210123456);
|
28
|
+
]
|
44
29
|
|
45
30
|
let () =
|
46
|
-
run_test_tt_main ("space-age tests" >::: tests)
|
31
|
+
run_test_tt_main ("space-age tests" >::: tests)
|
@@ -0,0 +1,17 @@
|
|
1
|
+
open Core.Std
|
2
|
+
|
3
|
+
let sort_sides = function
|
4
|
+
| [_; _; _] as sides ->
|
5
|
+
let side = List.nth_exn (List.sort sides ~cmp:Int.compare) in
|
6
|
+
(side 0, side 1, side 2)
|
7
|
+
| _ -> failwith "not at triangle"
|
8
|
+
|
9
|
+
let is_triangle f sides =
|
10
|
+
let (a, b, c) = sort_sides sides in
|
11
|
+
c > 0 && c <= a + b && f a b c
|
12
|
+
|
13
|
+
let is_equilateral = is_triangle (fun a b c -> a = b && b = c)
|
14
|
+
|
15
|
+
let is_isoceles = is_triangle (fun a b c -> a = b || b = c)
|
16
|
+
|
17
|
+
let is_scalene = is_triangle (fun a b c -> a <> b && b <> c)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
open Core.Std
|
2
|
+
open OUnit2
|
3
|
+
open Triangle
|
4
|
+
|
5
|
+
let ae exp got _test_ctxt = assert_equal exp got ~printer:Bool.to_string
|
6
|
+
|
7
|
+
let equilateral_tests = [
|
8
|
+
"true if all sides are equal" >::
|
9
|
+
ae true (is_equilateral [2; 2; 2]);
|
10
|
+
"false if any side is unequal" >::
|
11
|
+
ae false (is_equilateral [2; 3; 2]);
|
12
|
+
"false if no sides are equal" >::
|
13
|
+
ae false (is_equilateral [5; 4; 6]);
|
14
|
+
"All zero sides are illegal, so the triangle is not equilateral" >::
|
15
|
+
ae false (is_equilateral [0; 0; 0]);
|
16
|
+
]
|
17
|
+
|
18
|
+
let isoceles_tests = [
|
19
|
+
"true if last two sides are equal" >::
|
20
|
+
ae true (is_isoceles [3; 4; 4]);
|
21
|
+
"true if first two sides are equal" >::
|
22
|
+
ae true (is_isoceles [4; 4; 3]);
|
23
|
+
"true if first and last sides are equal" >::
|
24
|
+
ae true (is_isoceles [4; 3; 4]);
|
25
|
+
"equilateral triangles are also isosceles" >::
|
26
|
+
ae true (is_isoceles [4; 4; 4]);
|
27
|
+
"false if no sides are equal" >::
|
28
|
+
ae false (is_isoceles [2; 3; 4]);
|
29
|
+
"Sides that violate triangle inequality are not isosceles, even if two are equal" >::
|
30
|
+
ae false (is_isoceles [1; 1; 3]);
|
31
|
+
]
|
32
|
+
|
33
|
+
let scalene_tests = [
|
34
|
+
"true if no sides are equal" >::
|
35
|
+
ae true (is_scalene [5; 4; 6]);
|
36
|
+
"false if all sides are equal" >::
|
37
|
+
ae false (is_scalene [4; 4; 4]);
|
38
|
+
"false if two sides are equal" >::
|
39
|
+
ae false (is_scalene [4; 4; 3]);
|
40
|
+
"Sides that violate triangle inequality are not scalene, even if they are all different" >::
|
41
|
+
ae false (is_scalene [7; 3; 2]);
|
42
|
+
]
|
43
|
+
|
44
|
+
let () =
|
45
|
+
run_test_tt_main (
|
46
|
+
"triangle tests" >:::
|
47
|
+
List.concat [equilateral_tests; isoceles_tests; scalene_tests]
|
48
|
+
)
|
@@ -13,6 +13,9 @@ test_gen.native: all_tests.native src/*.ml test/*.ml
|
|
13
13
|
all_tests.native: src/*.ml test/*.ml
|
14
14
|
@ocamlbuild -use-ocamlfind -tag thread -tag short_paths -cflags -strict-sequence -r -pkg core -pkg oUnit -pkg yojson -pkg ppx_deriving -pkg ppx_deriving.eq -pkg ppx_deriving.show -Is src,test all_tests.native
|
15
15
|
|
16
|
+
debug.byte: debug.byte src/*.ml
|
17
|
+
@ocamlbuild -use-ocamlfind -tag thread -tag short_paths -cflags -strict-sequence -r -pkg core -pkg yojson -pkg ppx_deriving -pkg ppx_deriving.eq -pkg ppx_deriving.show -Is src,interfaces debug.byte
|
18
|
+
|
16
19
|
clean:
|
17
20
|
rm -rf _build
|
18
21
|
rm -f test_gen.native
|
@@ -26,5 +26,5 @@ let rec replace_keys (f: edit_expected_function) (ed: edit_parameters_function)
|
|
26
26
|
let parameter_strings = ed @@ List.map ~f:(fun (k,p) -> (k,p)) c.parameters in
|
27
27
|
List.fold parameter_strings ~init:(Subst s) ~f:(fun (Subst s) (k,v) -> Subst (replace_key k v s))
|
28
28
|
|
29
|
-
let fill_in_template (f: edit_expected_function) (ed: edit_parameters_function) test_template suite_name cases =
|
29
|
+
let fill_in_template (f: edit_expected_function) (ed: edit_parameters_function) (test_template: string) (suite_name: string) (cases: case list) =
|
30
30
|
List.map cases ~f:(replace_keys f ed test_template suite_name)
|
@@ -15,7 +15,10 @@ let find_nested_files (name: string) (base: string): (string * content) list =
|
|
15
15
|
|> List.filter ~f:(fun slug -> Sys.file_exists_exn (base ^ "/" ^ slug ^ "/" ^ name))
|
16
16
|
|> List.map ~f:(fun slug -> (slug, In_channel.read_all (base ^ "/" ^ slug ^ "/" ^ name)))
|
17
17
|
|
18
|
-
let find_template_files =
|
18
|
+
let find_template_files base filter =
|
19
|
+
let all_files = find_nested_files "template.ml" base in
|
20
|
+
let filter = Option.value filter ~default:"" in
|
21
|
+
List.filter all_files ~f:(fun (slug,_) -> String.is_substring slug ~substring:filter)
|
19
22
|
|
20
23
|
let find_canonical_data_files = find_nested_files "canonical-data.json"
|
21
24
|
|
@@ -24,26 +27,35 @@ let combine_files (template_files: (string * content) list) (canonical_data_file
|
|
24
27
|
|
25
28
|
(* pangram in the canonical data is a suite but it does not really need to be as there's only one group. Convert a Suite to
|
26
29
|
a Single test in this case, to simplify the template. *)
|
27
|
-
let simplify_single_test_suite tests = match tests with
|
30
|
+
let simplify_single_test_suite (tests: tests): tests = match tests with
|
28
31
|
| Suite [{name = name; cases = cases}] -> Single cases
|
29
32
|
| x -> x
|
30
33
|
|
31
34
|
let generate_code ~(slug: string) ~(template_file: content) ~(canonical_data_file: content): (content, content) Result.t =
|
32
|
-
let
|
35
|
+
let open Result.Monad_infix in
|
36
|
+
Result.of_option ~error:("cannot recognize file for " ^ slug ^ " as a template") @@ find_template template_file >>= fun template ->
|
33
37
|
let edit_expected = edit_expected ~stringify:json_to_string ~slug in
|
34
38
|
let edit_parameters = edit_parameters ~slug in
|
35
39
|
let fill_in_template = fill_in_template edit_expected edit_parameters in
|
36
|
-
let
|
37
|
-
|
40
|
+
let file_text = template.file_text in
|
41
|
+
let file_lines = String.split_lines file_text |> List.to_array in
|
38
42
|
parse_json_text canonical_data_file (expected_key_name slug) (cases_name slug)
|
39
43
|
|> Result.map_error ~f:show_error >>| simplify_single_test_suite >>= (function
|
40
44
|
| Single cases ->
|
45
|
+
let template = to_single template.template in
|
41
46
|
fill_in_template template.template slug cases
|
42
|
-
|> fill_tests template
|
47
|
+
|> fill_tests file_text template
|
43
48
|
|> Result.return
|
44
49
|
| Suite tests ->
|
45
|
-
|
46
|
-
|
50
|
+
let suites = to_multi template.template in
|
51
|
+
let suites_by_line = List.map suites ~f:(fun s -> (file_lines.(s.suite_name_line), s)) in
|
52
|
+
let find_suite name = List.find suites_by_line ~f:(fun (l,s) -> String.is_substring l ~substring:name) |> Option.map ~f:snd in
|
53
|
+
let fill_suite_tests {name; cases} =
|
54
|
+
let suite = Result.of_option ~error:("cannot find template for suite " ^ name) (find_suite name) in
|
55
|
+
Result.map suite ~f:(fun suite -> (name, fill_in_template suite.template_part.template name cases))
|
56
|
+
in
|
57
|
+
List.map tests ~f:fill_suite_tests |> sequence >>=
|
58
|
+
fill_suite template
|
47
59
|
)
|
48
60
|
|
49
61
|
let output_tests (files: (string * content * content) list) (output_folder: string) ~(generated_folder: string): unit =
|
@@ -57,8 +69,8 @@ let output_tests (files: (string * content * content) list) (output_folder: stri
|
|
57
69
|
| Error e -> print_endline ("Failed when generating " ^ slug ^ ", error: " ^ e) in
|
58
70
|
List.iter files ~f:output1
|
59
71
|
|
60
|
-
let run ~(templates_folder: string) ~(canonical_data_folder: string) ~(output_folder: string) ~(generated_folder: string) =
|
61
|
-
let template_files = find_template_files templates_folder in
|
72
|
+
let run ~(templates_folder: string) ~(canonical_data_folder: string) ~(output_folder: string) ~(generated_folder: string) (filter: string option) =
|
73
|
+
let template_files = find_template_files templates_folder filter in
|
62
74
|
let canonical_data_files = find_canonical_data_files canonical_data_folder in
|
63
75
|
let combined = combine_files template_files canonical_data_files in
|
64
76
|
output_tests combined output_folder generated_folder
|
@@ -0,0 +1,12 @@
|
|
1
|
+
open Core.Std
|
2
|
+
open Controller
|
3
|
+
|
4
|
+
let home_dir = Option.value_exn (Sys.getenv "HOME")
|
5
|
+
|
6
|
+
let () =
|
7
|
+
Controller.run
|
8
|
+
~templates_folder:"./templates"
|
9
|
+
~canonical_data_folder:"../../../x-common/exercises"
|
10
|
+
~output_folder:"../../exercises"
|
11
|
+
~generated_folder:(home_dir ^ "/.xocaml-generated")
|
12
|
+
(Some "beer-song")
|
@@ -77,12 +77,20 @@ let edit_dominoes (ps: (string * json) list): (string * string) list =
|
|
77
77
|
| ("input", `List j) -> ("input", "[" ^ (List.map ~f:two_elt_list_to_tuple j |> String.concat ~sep:"; ") ^ "]")
|
78
78
|
| (k, v) -> (k, json_to_string v) in
|
79
79
|
List.map ps ~f:edit
|
80
|
+
|
81
|
+
let edit_space_age (ps: (string * json) list): (string * string) list =
|
82
|
+
let strip_quotes s = String.drop_prefix s 1 |> Fn.flip String.drop_suffix 1 in
|
83
|
+
let edit = function
|
84
|
+
| ("planet", v) -> ("planet", json_to_string v |> strip_quotes)
|
85
|
+
| (k, v) -> (k, json_to_string v) in
|
86
|
+
List.map ps ~f:edit
|
80
87
|
|
81
88
|
let edit_parameters ~(slug: string) (parameters: (string * json) list) = match (slug, parameters) with
|
82
89
|
| ("hello-world", ps) -> default_value ~key:"name" ~value:"None" (optional_strings ~f:(fun _x -> true) parameters)
|
83
90
|
| ("say", ps) -> edit_say ps
|
84
91
|
| ("all-your-base", ps) -> edit_all_your_base ps
|
85
92
|
| ("dominoes", ps) -> edit_dominoes ps
|
93
|
+
| ("space-age", ps) -> edit_space_age ps
|
86
94
|
| (_, ps) -> map_elements json_to_string ps
|
87
95
|
|
88
96
|
let expected_key_name slug = match slug with
|