trackler 2.2.1.19 → 2.2.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/tracks/bash/config.json +11 -0
  4. data/tracks/bash/docs/ABOUT.md +5 -0
  5. data/tracks/bash/exercises/word-count/README.md +24 -0
  6. data/tracks/bash/exercises/word-count/example.awk +12 -0
  7. data/tracks/bash/exercises/word-count/example.sh +21 -0
  8. data/tracks/bash/exercises/word-count/word_count_test.sh +84 -0
  9. data/tracks/coffeescript/config/maintainers.json +5 -11
  10. data/tracks/csharp/.travis.yml +3 -0
  11. data/tracks/delphi/config/maintainers.json +1 -1
  12. data/tracks/ecmascript/config.json +108 -108
  13. data/tracks/elixir/exercises/phone-number/phone_number_test.exs +21 -1
  14. data/tracks/factor/docs/SNIPPET.txt +5 -0
  15. data/tracks/idris/docs/TESTS.md +7 -0
  16. data/tracks/java/config.json +47 -47
  17. data/tracks/javascript/config.json +103 -103
  18. data/tracks/julia/config.json +121 -121
  19. data/tracks/julia/docs/RESOURCES.md +1 -1
  20. data/tracks/julia/docs/SNIPPET.txt +8 -0
  21. data/tracks/objective-c/config.json +2 -3
  22. data/tracks/objective-c/exercises/rna-transcription/RNATranscriptionExample.m +11 -32
  23. data/tracks/ocaml/.travis-ci.sh +1 -1
  24. data/tracks/ocaml/.travis.yml +1 -1
  25. data/tracks/ocaml/README.md +1 -1
  26. data/tracks/ocaml/exercises/change/test.ml +24 -21
  27. data/tracks/ocaml/tools/test-generator/src/codegen.ml +3 -7
  28. data/tracks/ocaml/tools/test-generator/src/controller.ml +4 -5
  29. data/tracks/ocaml/tools/test-generator/src/languages.ml +4 -3
  30. data/tracks/ocaml/tools/test-generator/src/model.ml +1 -2
  31. data/tracks/ocaml/tools/test-generator/src/ocaml_special_cases.ml +19 -18
  32. data/tracks/ocaml/tools/test-generator/src/parser.ml +12 -17
  33. data/tracks/ocaml/tools/test-generator/src/purescript_special_cases.ml +11 -3
  34. data/tracks/ocaml/tools/test-generator/test/codegen_test.ml +2 -3
  35. data/tracks/ocaml/tools/test-generator/test/ocaml_special_cases_test.ml +12 -4
  36. data/tracks/ocaml/tools/test-generator/test/parser_test.ml +10 -10
  37. data/tracks/purescript/exercises/bob/test/Main.purs +5 -5
  38. data/tracks/ruby/bin/generate +1 -1
  39. data/tracks/ruby/docs/24pullrequests.md +1 -1
  40. data/tracks/ruby/exercises/all-your-base/all_your_base_test.rb +24 -24
  41. data/tracks/ruby/exercises/alphametics/.meta/generator/test_template.erb +1 -1
  42. data/tracks/ruby/exercises/bowling/.meta/generator/test_template.erb +1 -1
  43. data/tracks/ruby/exercises/bowling/bowling_test.rb +10 -10
  44. data/tracks/ruby/exercises/change/.meta/.version +1 -1
  45. data/tracks/ruby/exercises/change/.meta/solutions/change.rb +1 -1
  46. data/tracks/ruby/exercises/change/change_test.rb +7 -2
  47. data/tracks/ruby/exercises/collatz-conjecture/.meta/generator/collatz_conjecture_case.rb +1 -1
  48. data/tracks/ruby/exercises/connect/.meta/generator/test_template.erb +1 -1
  49. data/tracks/ruby/exercises/dominoes/.meta/generator/test_template.erb +1 -1
  50. data/tracks/ruby/exercises/hamming/.meta/generator/hamming_case.rb +5 -1
  51. data/tracks/ruby/exercises/hamming/hamming_test.rb +7 -7
  52. data/tracks/ruby/exercises/leap/.meta/generator/test_template.erb +1 -1
  53. data/tracks/ruby/exercises/pangram/.meta/.version +1 -1
  54. data/tracks/ruby/exercises/pangram/.meta/solutions/pangram.rb +1 -1
  55. data/tracks/ruby/exercises/pangram/pangram_test.rb +3 -3
  56. data/tracks/ruby/exercises/rna-transcription/rna_transcription_test.rb +4 -4
  57. data/tracks/ruby/exercises/roman-numerals/.meta/solutions/roman_numerals.rb +1 -1
  58. data/tracks/ruby/exercises/space-age/.meta/generator/test_template.erb +1 -1
  59. data/tracks/ruby/lib/generator/test_template.erb +1 -1
  60. data/tracks/ruby/lib/generator/underscore.rb +1 -1
  61. data/tracks/ruby/lib/helper.rb +4 -4
  62. data/tracks/ruby/test/fixtures/{xruby → ruby}/exercises/alpha-beta/.meta/generator/test_template.erb +1 -1
  63. data/tracks/ruby/test/fixtures/{xruby → ruby}/exercises/alpha/.meta/.version +0 -0
  64. data/tracks/ruby/test/fixtures/{xruby → ruby}/exercises/alpha/.meta/generator/alpha_case.rb +0 -0
  65. data/tracks/ruby/test/fixtures/{xruby → ruby}/exercises/alpha/.meta/generator/test_template.erb +1 -1
  66. data/tracks/ruby/test/fixtures/{xruby → ruby}/exercises/alpha/.meta/solutions/alpha.rb +0 -0
  67. data/tracks/ruby/test/fixtures/{xruby → ruby}/exercises/beta/.meta/.version +0 -0
  68. data/tracks/ruby/test/fixtures/{xruby → ruby}/exercises/beta/.meta/generator/beta_case.rb +0 -0
  69. data/tracks/ruby/test/fixtures/{xruby → ruby}/lib/generator/test_template.erb +1 -1
  70. data/tracks/ruby/test/generator/files/track_files_test.rb +4 -4
  71. data/tracks/ruby/test/generator/implementation_test.rb +1 -1
  72. data/tracks/ruby/test/generator/template_values_test.rb +1 -1
  73. data/tracks/scala/exercises/rail-fence-cipher/src/main/scala/{RailFenceCipher.scala → .keep} +0 -0
  74. data/tracks/scala/exercises/rail-fence-cipher/src/test/scala/RailFenceCipherTest.scala +16 -23
  75. data/tracks/scala/exercises/say/src/test/scala/SayTest.scala +20 -33
  76. data/tracks/scala/testgen/src/main/scala/RailFenceCipherTestGenerator.scala +9 -53
  77. data/tracks/scala/testgen/src/main/scala/SayTestGenerator.scala +50 -0
  78. data/tracks/sml/bin/generate +1 -1
  79. data/tracks/sml/config.json +30 -0
  80. data/tracks/sml/exercises/all-your-base/README.md +61 -0
  81. data/tracks/sml/exercises/all-your-base/all-your-base.sml +2 -0
  82. data/tracks/sml/exercises/all-your-base/example.sml +36 -0
  83. data/tracks/sml/exercises/all-your-base/test.sml +75 -0
  84. data/tracks/sml/exercises/all-your-base/testlib.sml +159 -0
  85. data/tracks/sml/exercises/difference-of-squares/example.sml +3 -6
  86. data/tracks/sml/exercises/list-ops/README.md +40 -0
  87. data/tracks/sml/exercises/list-ops/example.sml +34 -0
  88. data/tracks/sml/exercises/list-ops/list-ops.sml +23 -0
  89. data/tracks/sml/exercises/list-ops/test.sml +85 -0
  90. data/tracks/sml/exercises/list-ops/testlib.sml +159 -0
  91. data/tracks/sml/exercises/prime-factors/README.md +66 -0
  92. data/tracks/sml/exercises/prime-factors/example.sml +15 -0
  93. data/tracks/sml/exercises/prime-factors/prime-factors.sml +2 -0
  94. data/tracks/sml/exercises/prime-factors/test.sml +35 -0
  95. data/tracks/sml/exercises/prime-factors/testlib.sml +159 -0
  96. metadata +34 -11
@@ -0,0 +1,40 @@
1
+ # List Ops
2
+
3
+ Implement basic list operations.
4
+
5
+ In functional languages list operations like `length`, `map`, and
6
+ `reduce` are very common. Implement a series of basic list operations,
7
+ without using existing functions.
8
+
9
+ ## Loading your exercise implementation in PolyML
10
+
11
+ ```
12
+ $ poly --use {exercise}.sml
13
+ ```
14
+
15
+ Or:
16
+
17
+ ```
18
+ $ poly
19
+ > use "{exercise}.sml";
20
+ ```
21
+
22
+ **Note:** You have to replace {exercise}.
23
+
24
+ ## Running the tests
25
+
26
+ ```
27
+ $ poly -q --use test.sml
28
+ ```
29
+
30
+ ## Feedback, Issues, Pull Requests
31
+
32
+ The [exercism/sml](https://github.com/exercism/sml) repository on
33
+ GitHub is the home for all of the Standard ML exercises.
34
+
35
+ If you have feedback about an exercise, or want to help implementing a new
36
+ one, head over there and create an issue. We'll do our best to help you!
37
+
38
+
39
+ ## Submitting Incomplete Solutions
40
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,34 @@
1
+ fun concat [] = []
2
+ | concat [[]] = []
3
+ | concat ([] :: xss) = concat xss
4
+ | concat ((x :: xs) :: xss) = x :: concat (xs :: xss)
5
+
6
+ fun reverse xs =
7
+ let
8
+ fun reverse' acc [] = acc
9
+ | reverse' acc (x :: xs) = reverse' (x :: acc) xs
10
+ in
11
+ reverse' [] xs
12
+ end
13
+
14
+ fun filter (predicate, []) = []
15
+ | filter (predicate, (x :: xs)) =
16
+ if predicate x
17
+ then x :: filter (predicate, xs)
18
+ else filter (predicate, xs)
19
+
20
+ fun map (f, []) = []
21
+ | map (f, x :: xs) = f x :: map (f, xs)
22
+
23
+ fun append (xs, []) = xs
24
+ | append ([], ys) = ys
25
+ | append (x :: xs, ys) = x :: append(xs, ys)
26
+
27
+ fun length [] = 0
28
+ | length (x :: xs) = 1 + length xs
29
+
30
+ fun foldl (_, acc, []) = acc
31
+ | foldl (f, acc, (x :: xs)) = foldl (f, (f (acc, x)), xs)
32
+
33
+ fun foldr (f, acc, []) = acc
34
+ | foldr (f, acc, (x::xs)) = f (x, (foldr (f, acc, xs)))
@@ -0,0 +1,23 @@
1
+ fun concat (lists: int list list): int list =
2
+ raise Fail "'concat' is not implemented"
3
+
4
+ fun reverse (list: int list): int list =
5
+ raise Fail "'reverse' is not implemented"
6
+
7
+ fun filter (function: int -> bool, list: int list): int list =
8
+ raise Fail "'filter' is not implemented"
9
+
10
+ fun map (function: int -> int, list: int list): int list =
11
+ raise Fail "'map' is not implemented"
12
+
13
+ fun append (list1: int list, list2: int list): int list =
14
+ raise Fail "'append' is not implemented"
15
+
16
+ fun length (ns: int list): int =
17
+ raise Fail "'length' is not implemented"
18
+
19
+ fun foldl (function: int * int -> int, initial: int, list: int list): int =
20
+ raise Fail "'foldl' is not implemented"
21
+
22
+ fun foldr (function: int * int -> int, initial: int, list: int list): int =
23
+ raise Fail "'foldr' is not implemented"
@@ -0,0 +1,85 @@
1
+ (* version 2.0.0 *)
2
+
3
+ use "testlib.sml";
4
+ use "list-ops.sml";
5
+
6
+ infixr |>
7
+ fun x |> f = f x
8
+
9
+ val testsuite =
10
+ describe "list-ops" [
11
+ describe "append entries to a list and return the new list" [
12
+ test "empty lists"
13
+ (fn _ => append ([], []) |> Expect.equalTo []),
14
+
15
+ test "empty list to list"
16
+ (fn _ => append ([], [1, 2, 3, 4]) |> Expect.equalTo [1, 2, 3, 4]),
17
+
18
+ test "non-empty lists"
19
+ (fn _ => append ([1, 2], [2, 3, 4, 5]) |> Expect.equalTo [1, 2, 2, 3, 4, 5])
20
+ ],
21
+
22
+ describe "concat lists and lists of list into a new list" [
23
+ test "empty list"
24
+ (fn _ => concat ([]) |> Expect.equalTo []),
25
+
26
+ test "list of lists"
27
+ (fn _ => concat ([[1, 2], [3], [], [4, 5, 6]]) |> Expect.equalTo [1, 2, 3, 4, 5, 6])
28
+ ],
29
+
30
+ describe "filter list returning only values that satisfy the filter function" [
31
+ test "empty list"
32
+ (fn _ => filter (fn n => n mod 2 = 1, []) |> Expect.equalTo []),
33
+
34
+ test "non-empty list"
35
+ (fn _ => filter (fn n => n mod 2 = 1, [1, 2, 3, 5]) |> Expect.equalTo [1, 3, 5])
36
+ ],
37
+
38
+ describe "returns the length of a list" [
39
+ test "empty list"
40
+ (fn _ => length ([]) |> Expect.equalTo 0),
41
+
42
+ test "non-empty list"
43
+ (fn _ => length ([1, 2, 3, 4]) |> Expect.equalTo 4)
44
+ ],
45
+
46
+ describe "return a list of elements whos values equal the list value transformed by the mapping function" [
47
+ test "empty list"
48
+ (fn _ => map (fn n => n + 1, []) |> Expect.equalTo []),
49
+
50
+ test "non-empty list"
51
+ (fn _ => map (fn n => n + 1, [1, 3, 5, 7]) |> Expect.equalTo [2, 4, 6, 8])
52
+ ],
53
+
54
+ describe "folds (reduces) the given list from the left with a function" [
55
+ test "empty list"
56
+ (fn _ => foldl (fn (x, y) => x * y, 2, []) |> Expect.equalTo 2),
57
+
58
+ test "direction independent function applied to non-empty list"
59
+ (fn _ => foldl (fn (x, y) => x + y, 5, [1, 2, 3, 4]) |> Expect.equalTo 15),
60
+
61
+ test "direction dependent function applied to non-empty list"
62
+ (fn _ => foldl (fn (x, y) => x div y, 5, [2, 5]) |> Expect.equalTo 0)
63
+ ],
64
+
65
+ describe "folds (reduces) the given list from the right with a function" [
66
+ test "empty list"
67
+ (fn _ => foldr (fn (x, y) => x * y, 2, []) |> Expect.equalTo 2),
68
+
69
+ test "direction independent function applied to non-empty list"
70
+ (fn _ => foldr (fn (x, y) => x + y, 5, [1, 2, 3, 4]) |> Expect.equalTo 15),
71
+
72
+ test "direction dependent function applied to non-empty list"
73
+ (fn _ => foldr (fn (x, y) => x div y, 5, [2, 5]) |> Expect.equalTo 2)
74
+ ],
75
+
76
+ describe "reverse the elements of the list" [
77
+ test "empty list"
78
+ (fn _ => reverse ([]) |> Expect.equalTo []),
79
+
80
+ test "non-empty list"
81
+ (fn _ => reverse ([1, 3, 5, 7]) |> Expect.equalTo [7, 5, 3, 1])
82
+ ]
83
+ ]
84
+
85
+ val _ = Test.run testsuite
@@ -0,0 +1,159 @@
1
+ structure Expect =
2
+ struct
3
+ datatype expectation = Pass | Fail of string * string
4
+
5
+ local
6
+ fun failEq b a =
7
+ Fail ("Expected: " ^ b, "Got: " ^ a)
8
+
9
+ fun failExn b a =
10
+ Fail ("Expected: " ^ b, "Raised: " ^ a)
11
+
12
+ fun exnName (e: exn): string = General.exnName e
13
+ in
14
+ fun truthy a =
15
+ if a
16
+ then Pass
17
+ else failEq "true" "false"
18
+
19
+ fun falsy a =
20
+ if a
21
+ then failEq "false" "true"
22
+ else Pass
23
+
24
+ fun equalTo b a =
25
+ if a = b
26
+ then Pass
27
+ else failEq (PolyML.makestring b) (PolyML.makestring a)
28
+
29
+ fun nearTo b a =
30
+ if Real.== (a, b)
31
+ then Pass
32
+ else failEq (Real.toString b) (Real.toString a)
33
+
34
+ fun anyError f =
35
+ (
36
+ f ();
37
+ failExn "an exception" "Nothing"
38
+ ) handle _ => Pass
39
+
40
+ fun error e f =
41
+ (
42
+ f ();
43
+ failExn (exnName e) "Nothing"
44
+ ) handle e' => if exnMessage e' = exnMessage e
45
+ then Pass
46
+ else failExn (exnMessage e) (exnMessage e')
47
+ end
48
+ end
49
+
50
+ structure TermColor =
51
+ struct
52
+ datatype color = Red | Green | Yellow | Normal
53
+
54
+ fun f Red = "\027[31m"
55
+ | f Green = "\027[32m"
56
+ | f Yellow = "\027[33m"
57
+ | f Normal = "\027[0m"
58
+
59
+ fun colorize color s = (f color) ^ s ^ (f Normal)
60
+
61
+ val redit = colorize Red
62
+
63
+ val greenit = colorize Green
64
+
65
+ val yellowit = colorize Yellow
66
+ end
67
+
68
+ structure Test =
69
+ struct
70
+ datatype testnode = TestGroup of string * testnode list
71
+ | Test of string * (unit -> Expect.expectation)
72
+
73
+ local
74
+ datatype evaluation = Success of string
75
+ | Failure of string * string * string
76
+ | Error of string * string
77
+
78
+ fun indent n s = (implode (List.tabulate (n, fn _ => #" "))) ^ s
79
+
80
+ fun fmt indentlvl ev =
81
+ let
82
+ val check = TermColor.greenit "\226\156\148 " (* ✔ *)
83
+ val cross = TermColor.redit "\226\156\150 " (* ✖ *)
84
+ val indentlvl = indentlvl * 2
85
+ in
86
+ case ev of
87
+ Success descr => indent indentlvl (check ^ descr)
88
+ | Failure (descr, exp, got) =>
89
+ String.concatWith "\n" [indent indentlvl (cross ^ descr),
90
+ indent (indentlvl + 2) exp,
91
+ indent (indentlvl + 2) got]
92
+ | Error (descr, reason) =>
93
+ String.concatWith "\n" [indent indentlvl (cross ^ descr),
94
+ indent (indentlvl + 2) (TermColor.redit reason)]
95
+ end
96
+
97
+ fun eval (TestGroup _) = raise Fail "Only a 'Test' can be evaluated"
98
+ | eval (Test (descr, thunk)) =
99
+ (
100
+ case thunk () of
101
+ Expect.Pass => ((1, 0, 0), Success descr)
102
+ | Expect.Fail (s, s') => ((0, 1, 0), Failure (descr, s, s'))
103
+ )
104
+ handle e => ((0, 0, 1), Error (descr, "Unexpected error: " ^ exnMessage e))
105
+
106
+ fun flatten depth testnode =
107
+ let
108
+ fun sum (x, y, z) (a, b, c) = (x + a, y + b, z + c)
109
+
110
+ fun aux (t, (counter, acc)) =
111
+ let
112
+ val (counter', texts) = flatten (depth + 1) t
113
+ in
114
+ (sum counter' counter, texts :: acc)
115
+ end
116
+ in
117
+ case testnode of
118
+ TestGroup (descr, ts) =>
119
+ let
120
+ val (counter, texts) = foldr aux ((0, 0, 0), []) ts
121
+ in
122
+ (counter, (indent (depth * 2) descr) :: List.concat texts)
123
+ end
124
+ | Test _ =>
125
+ let
126
+ val (counter, evaluation) = eval testnode
127
+ in
128
+ (counter, [fmt depth evaluation])
129
+ end
130
+ end
131
+
132
+ fun println s = print (s ^ "\n")
133
+ in
134
+ fun run suite =
135
+ let
136
+ val ((succeeded, failed, errored), texts) = flatten 0 suite
137
+
138
+ val summary = String.concatWith ", " [
139
+ TermColor.greenit ((Int.toString succeeded) ^ " passed"),
140
+ TermColor.redit ((Int.toString failed) ^ " failed"),
141
+ TermColor.redit ((Int.toString errored) ^ " errored"),
142
+ (Int.toString (succeeded + failed + errored)) ^ " total"
143
+ ]
144
+
145
+ val status = if failed = 0 andalso errored = 0
146
+ then OS.Process.success
147
+ else OS.Process.failure
148
+
149
+ in
150
+ List.app println texts;
151
+ println "";
152
+ println ("Tests: " ^ summary);
153
+ OS.Process.exit status
154
+ end
155
+ end
156
+ end
157
+
158
+ fun describe description tests = Test.TestGroup (description, tests)
159
+ fun test description thunk = Test.Test (description, thunk)
@@ -0,0 +1,66 @@
1
+ # Prime Factors
2
+
3
+ Compute the prime factors of a given natural number.
4
+
5
+ A prime number is only evenly divisible by itself and 1.
6
+
7
+ Note that 1 is not a prime number.
8
+
9
+ ## Example
10
+
11
+ What are the prime factors of 60?
12
+
13
+ - Our first divisor is 2. 2 goes into 60, leaving 30.
14
+ - 2 goes into 30, leaving 15.
15
+ - 2 doesn't go cleanly into 15. So let's move on to our next divisor, 3.
16
+ - 3 goes cleanly into 15, leaving 5.
17
+ - 3 does not go cleanly into 5. The next possible factor is 4.
18
+ - 4 does not go cleanly into 5. The next possible factor is 5.
19
+ - 5 does go cleanly into 5.
20
+ - We're left only with 1, so now, we're done.
21
+
22
+ Our successful divisors in that computation represent the list of prime
23
+ factors of 60: 2, 2, 3, and 5.
24
+
25
+ You can check this yourself:
26
+
27
+ - 2 * 2 * 3 * 5
28
+ - = 4 * 15
29
+ - = 60
30
+ - Success!
31
+
32
+ ## Loading your exercise implementation in PolyML
33
+
34
+ ```
35
+ $ poly --use {exercise}.sml
36
+ ```
37
+
38
+ Or:
39
+
40
+ ```
41
+ $ poly
42
+ > use "{exercise}.sml";
43
+ ```
44
+
45
+ **Note:** You have to replace {exercise}.
46
+
47
+ ## Running the tests
48
+
49
+ ```
50
+ $ poly -q --use test.sml
51
+ ```
52
+
53
+ ## Feedback, Issues, Pull Requests
54
+
55
+ The [exercism/sml](https://github.com/exercism/sml) repository on
56
+ GitHub is the home for all of the Standard ML exercises.
57
+
58
+ If you have feedback about an exercise, or want to help implementing a new
59
+ one, head over there and create an issue. We'll do our best to help you!
60
+
61
+ ## Source
62
+
63
+ The Prime Factors Kata by Uncle Bob [http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata](http://butunclebob.com/ArticleS.UncleBob.ThePrimeFactorsKata)
64
+
65
+ ## Submitting Incomplete Solutions
66
+ It's possible to submit an incomplete solution so you can see how others have completed the exercise.
@@ -0,0 +1,15 @@
1
+ fun factors n =
2
+ let
3
+ fun aux prime n =
4
+ if prime * prime > n
5
+ then [n]
6
+ else if n mod prime = 0
7
+ then prime :: aux prime (n div prime)
8
+ else if prime = 2
9
+ then aux (prime + 1) n
10
+ else aux (prime + 2) n
11
+ in
12
+ if n < 2
13
+ then []
14
+ else aux 2 n
15
+ end
@@ -0,0 +1,2 @@
1
+ fun factors (input: int): int list =
2
+ raise Fail "'factors' is not implemented"
@@ -0,0 +1,35 @@
1
+ (* version 1.0.0 *)
2
+
3
+ use "prime-factors.sml";
4
+ use "testlib.sml";
5
+
6
+ infixr |>
7
+ fun x |> f = f x
8
+
9
+ val testsuite =
10
+ describe "prime-factors" [
11
+ describe "returns prime factors for the given input number" [
12
+ test "no factors"
13
+ (fn _ => factors (1) |> Expect.equalTo []),
14
+
15
+ test "prime number"
16
+ (fn _ => factors (2) |> Expect.equalTo [2]),
17
+
18
+ test "square of a prime"
19
+ (fn _ => factors (9) |> Expect.equalTo [3, 3]),
20
+
21
+ test "cube of a prime"
22
+ (fn _ => factors (8) |> Expect.equalTo [2, 2, 2]),
23
+
24
+ test "product of primes and non-primes"
25
+ (fn _ => factors (12) |> Expect.equalTo [2, 2, 3]),
26
+
27
+ test "product of primes"
28
+ (fn _ => factors (901255) |> Expect.equalTo [5, 17, 23, 461]),
29
+
30
+ test "factors include a large prime"
31
+ (fn _ => factors (93819012551) |> Expect.equalTo [11, 9539, 894119])
32
+ ]
33
+ ]
34
+
35
+ val _ = Test.run testsuite