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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/csharp/exercises/accumulate/HINTS.md +1 -2
  4. data/tracks/csharp/exercises/nth-prime/HINTS.md +7 -0
  5. data/tracks/csharp/exercises/proverb/HINTS.md +3 -0
  6. data/tracks/go/exercises/trinary/trinary_test.go +1 -1
  7. data/tracks/go/exercises/twelve-days/twelve_days_test.go +6 -6
  8. data/tracks/java/.Rhistory +0 -0
  9. data/tracks/java/config.json +12 -0
  10. data/tracks/java/exercises/book-store/build.gradle +17 -0
  11. data/tracks/java/exercises/book-store/src/example/java/.keep +0 -0
  12. data/tracks/java/exercises/book-store/src/example/java/Bookstore.java +61 -0
  13. data/tracks/java/exercises/book-store/src/main/java/.keep +0 -0
  14. data/tracks/java/exercises/book-store/src/test/java/.keep +0 -0
  15. data/tracks/java/exercises/book-store/src/test/java/BookstoreTest.java +117 -0
  16. data/tracks/java/exercises/hamming/src/example/java/Hamming.java +11 -2
  17. data/tracks/java/exercises/hamming/src/test/java/HammingTest.java +9 -10
  18. data/tracks/java/exercises/isogram/build.gradle +17 -0
  19. data/tracks/java/exercises/isogram/src/example/java/IsogramChecker.java +34 -0
  20. data/tracks/java/exercises/isogram/src/main/java/.keep +0 -0
  21. data/tracks/java/exercises/isogram/src/test/java/IsogramTest.java +80 -0
  22. data/tracks/java/exercises/raindrops/src/example/java/{Raindrops.java → RaindropConverter.java} +2 -2
  23. data/tracks/java/exercises/raindrops/src/test/java/{RaindropsTest.java → RaindropConverterTest.java} +3 -3
  24. data/tracks/java/exercises/settings.gradle +2 -0
  25. data/tracks/ocaml/.vscode/launch.json +13 -0
  26. data/tracks/ocaml/config.json +5 -0
  27. data/tracks/ocaml/exercises/beer-song/test.ml +15 -7
  28. data/tracks/ocaml/exercises/phone-number/test.ml +2 -2
  29. data/tracks/ocaml/exercises/prime-factors/test.ml +20 -16
  30. data/tracks/ocaml/exercises/roman-numerals/test.ml +40 -22
  31. data/tracks/ocaml/exercises/run-length-encoding/test.ml +6 -4
  32. data/tracks/ocaml/exercises/space-age/test.ml +20 -35
  33. data/tracks/ocaml/exercises/triangle/.merlin +5 -0
  34. data/tracks/ocaml/exercises/triangle/Makefile +11 -0
  35. data/tracks/ocaml/exercises/triangle/example.ml +17 -0
  36. data/tracks/ocaml/exercises/triangle/test.ml +48 -0
  37. data/tracks/ocaml/exercises/triangle/triangle.mli +5 -0
  38. data/tracks/ocaml/tools/test-generator/.merlin +0 -1
  39. data/tracks/ocaml/tools/test-generator/Makefile +3 -0
  40. data/tracks/ocaml/tools/test-generator/src/codegen.ml +1 -1
  41. data/tracks/ocaml/tools/test-generator/src/controller.ml +22 -10
  42. data/tracks/ocaml/tools/test-generator/src/debug.ml +12 -0
  43. data/tracks/ocaml/tools/test-generator/src/special_cases.ml +8 -0
  44. data/tracks/ocaml/tools/test-generator/src/template.ml +91 -41
  45. data/tracks/ocaml/tools/test-generator/src/test_gen.ml +2 -1
  46. data/tracks/ocaml/tools/test-generator/templates/atbash-cipher/template.ml +11 -3
  47. data/tracks/ocaml/tools/test-generator/templates/beer-song/template.ml +13 -3
  48. data/tracks/ocaml/tools/test-generator/templates/difference-of-squares/template.ml +17 -3
  49. data/tracks/ocaml/tools/test-generator/templates/prime-factors/template.ml +25 -0
  50. data/tracks/ocaml/tools/test-generator/templates/roman-numerals/template.ml +15 -0
  51. data/tracks/ocaml/tools/test-generator/templates/run-length-encoding/template.ml +19 -3
  52. data/tracks/ocaml/tools/test-generator/templates/space-age/template.ml +19 -0
  53. data/tracks/ocaml/tools/test-generator/templates/triangle/template.ml +33 -0
  54. data/tracks/ocaml/tools/test-generator/test/template_test.ml +8 -7
  55. data/tracks/powershell/exercises/hamming/hamming.tests.ps1 +4 -4
  56. 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" (verse 99);
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" (verse 3);
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" (verse 2);
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" (verse 1);
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" (verse 0);
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" (lyrics ~from:99 ~until:98);
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" (lyrics ~from:2 ~until:0);
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 12 digits" >::
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 test_pairs =
15
- [([], 1L);
16
- ([2L], 2L);
17
- ([3L], 3L);
18
- ([2L; 2L], 4L);
19
- ([2L; 2L; 2L], 8L);
20
- ([3L; 3L], 9L);
21
- ([3L; 3L; 3L], 27L);
22
- ([5L; 5L; 5L; 5L], 625L);
23
- ([5L; 17L; 23L; 461L], 901255L);
24
- ([11L; 9539L; 894119L], 93819012551L)]
25
-
26
- let tests =
27
- let f (l, n) = (Int64.to_string n) >:: ae l (Prime_factors.factors_of n) in
28
- List.map ~f test_pairs
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 checks exp inp _ctx = assert_equal ~printer:Fn.id exp (to_roman inp)
5
+ let ae expected actual _ctx = assert_equal ~printer:Fn.id expected actual
6
6
 
7
- let tests =
8
- [ "1 to I" >:: checks "I" 1
9
- ; "2 to II" >:: checks "II" 2
10
- ; "3 to III" >:: checks "III" 3
11
- ; "4 to IV" >:: checks "IV" 4
12
- ; "5 to V" >:: checks "V" 5
13
- ; "6 to VI" >:: checks "VI" 6
14
- ; "9 to IX" >:: checks "IX" 9
15
- ; "27 to XXVII" >:: checks "XXVII" 27
16
- ; "48 to XLVIII" >:: checks "XLVIII" 48
17
- ; "59 to LIX" >:: checks "LIX" 59
18
- ; "93 to XCIII" >:: checks "XCIII" 93
19
- ; "141 to CXLI" >:: checks "CXLI" 141
20
- ; "163 to CLXIII" >:: checks "CLXIII" 163
21
- ; "402 to CDII" >:: checks "CDII" 402
22
- ; "575 to DLXXV" >:: checks "DLXXV" 575
23
- ; "911 to CMXI" >:: checks "CMXI" 911
24
- ; "1024 to MXXIV" >:: checks "MXXIV" 1024
25
- ; "3000 to MMM" >:: checks "MMM" 3000
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 run_length_encode_a_string_tests = [
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
- let run_length_decode_a_string_tests = [
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" (decode @@ encode "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 [run_length_encode_a_string_tests; run_length_decode_a_string_tests; encode_and_then_decode_tests]
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 aid ~d:delta exp got =
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
- ["age in Earth years">:: (fun _ ->
13
- let input = 1_000_000_000 in
14
- aid ~d:0.005 31.69 (age_on Earth input));
15
- "age in Mercury years">:: (fun _ ->
16
- let input = 2_134_835_688 in
17
- aid ~d:0.005 67.65 (age_on Earth input);
18
- aid ~d:0.005 280.88 (age_on Mercury input));
19
- "age in Venus years">:: (fun _ ->
20
- let input = 189_839_836 in
21
- aid ~d:0.005 6.02 (age_on Earth input);
22
- aid ~d:0.005 9.78 (age_on Venus input));
23
- "age in Mars years">:: (fun _ ->
24
- let input = 2_329_871_239 in
25
- aid ~d:0.005 73.83 (age_on Earth input);
26
- aid ~d:0.005 39.25 (age_on Mars input));
27
- "age in Jupiter years">:: (fun _ ->
28
- let input = 901_876_382 in
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,5 @@
1
+ PKG findlib
2
+ PKG core
3
+ PKG ounit
4
+ S *
5
+ B *
@@ -0,0 +1,11 @@
1
+ test: test.native
2
+ @./test.native
3
+
4
+ test.native: *.ml *.mli
5
+ @corebuild -r -quiet -pkg oUnit test.native
6
+
7
+ clean:
8
+ rm -rf _build
9
+ rm -f test.native
10
+
11
+ .PHONY: clean
@@ -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
+ )
@@ -0,0 +1,5 @@
1
+ val is_equilateral : (int list) -> bool
2
+
3
+ val is_isoceles : (int list) -> bool
4
+
5
+ val is_scalene : (int list) -> bool
@@ -1,5 +1,4 @@
1
1
  S src/**
2
- S interfaces/**
3
2
  S test/**
4
3
  B _build/src
5
4
  B _build/test
@@ -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 = find_nested_files "template.ml"
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 template = find_template template_file in
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 open Result.Monad_infix in
37
- Result.of_option template ("cannot recognize file for " ^ slug ^ " as a template") >>= fun template ->
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
- List.map tests ~f:(fun {name;cases} -> (name, fill_in_template template.template name cases))
46
- |> fill_suite template
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