trackler 2.2.1.24 → 2.2.1.25
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/TOPICS.txt +73 -73
- data/tracks/bash/config.json +82 -73
- data/tracks/bash/config/maintainers.json +9 -9
- data/tracks/bash/exercises/nucleotide-count/README.md +38 -0
- data/tracks/bash/exercises/nucleotide-count/example.sh +38 -0
- data/tracks/bash/exercises/nucleotide-count/nucleotide_count_test.sh +29 -0
- data/tracks/csharp/.travis.yml +9 -2
- data/tracks/csharp/build.cake +7 -34
- data/tracks/csharp/build.ps1 +2 -2
- data/tracks/csharp/build.sh +2 -2
- data/tracks/csharp/docs/GENERATORS.md +102 -0
- data/tracks/csharp/exercises/Exercises.sln +669 -0
- data/tracks/csharp/exercises/queen-attack/Example.cs +14 -1
- data/tracks/csharp/exercises/queen-attack/QueenAttack.cs +6 -1
- data/tracks/csharp/exercises/queen-attack/QueenAttackTest.cs +57 -19
- data/tracks/csharp/generators/Exercises/QueenAttack.cs +85 -0
- data/tracks/d/README.md +3 -2
- data/tracks/d/docs/SNIPPET.txt +7 -0
- data/tracks/d/exercises/crypto-square/.dub/dub.json +6 -0
- data/tracks/d/exercises/crypto-square/example/crypto_square.d +4 -2
- data/tracks/dart/exercises/bob/pubspec.lock +28 -16
- data/tracks/dart/exercises/bob/pubspec.yaml +1 -1
- data/tracks/dart/exercises/bob/test/bob_test.dart +2 -0
- data/tracks/dart/exercises/difference-of-squares/pubspec.lock +28 -16
- data/tracks/dart/exercises/difference-of-squares/pubspec.yaml +1 -1
- data/tracks/dart/exercises/gigasecond/pubspec.lock +28 -16
- data/tracks/dart/exercises/gigasecond/pubspec.yaml +1 -1
- data/tracks/dart/exercises/hamming/pubspec.lock +28 -16
- data/tracks/dart/exercises/hamming/pubspec.yaml +1 -1
- data/tracks/dart/exercises/hello-world/pubspec.lock +28 -16
- data/tracks/dart/exercises/hello-world/pubspec.yaml +1 -1
- data/tracks/dart/exercises/hello-world/test/hello_world_test.dart +13 -15
- data/tracks/dart/exercises/leap/pubspec.lock +28 -16
- data/tracks/dart/exercises/leap/pubspec.yaml +1 -1
- data/tracks/dart/exercises/rna-transcription/pubspec.lock +28 -16
- data/tracks/dart/exercises/rna-transcription/pubspec.yaml +1 -1
- data/tracks/elixir/exercises/pig-latin/example.exs +17 -18
- data/tracks/elixir/exercises/pig-latin/pig_latin_test.exs +16 -1
- data/tracks/fsharp/build.cake +0 -2
- data/tracks/go/exercises/error-handling/.meta/description.md +39 -0
- data/tracks/go/exercises/error-handling/.meta/hints.md +5 -0
- data/tracks/go/exercises/error-handling/.meta/metadata.yml +2 -0
- data/tracks/go/exercises/error-handling/README.md +43 -5
- data/tracks/go/exercises/error-handling/common.go +4 -3
- data/tracks/go/exercises/error-handling/error_handling_test.go +1 -38
- data/tracks/go/exercises/secret-handshake/secret_handshake_test.go +3 -1
- data/tracks/haxe/docs/LEARNING.md +8 -0
- data/tracks/java/.gitignore +2 -1
- data/tracks/java/config.json +337 -491
- data/tracks/java/config/maintainers.json +26 -26
- data/tracks/java/exercises/bob/src/test/java/BobTest.java +7 -1
- data/tracks/java/exercises/rna-transcription/src/example/java/RnaTranscription.java +4 -2
- data/tracks/java/exercises/rna-transcription/src/main/java/RnaTranscription.java +5 -3
- data/tracks/java/exercises/rna-transcription/src/test/java/RnaTranscriptionTest.java +21 -26
- data/tracks/javascript/config.json +662 -664
- data/tracks/javascript/config/maintainers.json +35 -35
- data/tracks/javascript/exercises/simple-cipher/simple-cipher.spec.js +7 -3
- data/tracks/plsql/config.json +52 -66
- data/tracks/plsql/docs/SNIPPET.txt +6 -0
- data/tracks/plsql/exercises/hello-world/example.plsql +20 -0
- data/tracks/plsql/exercises/hello-world/hello_world#.plsql +20 -0
- data/tracks/plsql/exercises/hello-world/ut_hello_world#.plsql +60 -0
- data/tracks/sml/Makefile +5 -0
- data/tracks/sml/bin/generate +3 -4
- data/tracks/sml/config.json +55 -5
- data/tracks/sml/exercises/collatz-conjecture/README.md +63 -0
- data/tracks/sml/exercises/collatz-conjecture/collatz-conjecture.sml +4 -0
- data/tracks/sml/exercises/collatz-conjecture/example.sml +17 -0
- data/tracks/sml/exercises/collatz-conjecture/test.sml +30 -0
- data/tracks/sml/exercises/collatz-conjecture/testlib.sml +159 -0
- data/tracks/sml/exercises/leap/README.md +63 -0
- data/tracks/sml/exercises/leap/example.sml +2 -0
- data/tracks/sml/exercises/leap/leap.sml +2 -0
- data/tracks/sml/exercises/leap/test.sml +24 -0
- data/tracks/sml/exercises/leap/testlib.sml +159 -0
- data/tracks/sml/exercises/rna-transcription/README.md +55 -0
- data/tracks/sml/exercises/rna-transcription/example.sml +20 -0
- data/tracks/sml/exercises/rna-transcription/rna-transcription.sml +2 -0
- data/tracks/sml/exercises/rna-transcription/test.sml +36 -0
- data/tracks/sml/exercises/rna-transcription/testlib.sml +159 -0
- data/tracks/sml/exercises/sum-of-multiples/README.md +48 -0
- data/tracks/sml/exercises/sum-of-multiples/example.sml +8 -0
- data/tracks/sml/exercises/sum-of-multiples/sum-of-multiples.sml +2 -0
- data/tracks/sml/exercises/sum-of-multiples/test.sml +48 -0
- data/tracks/sml/exercises/sum-of-multiples/testlib.sml +159 -0
- data/tracks/sml/exercises/two-fer/README.md +78 -0
- data/tracks/sml/exercises/two-fer/example.sml +1 -0
- data/tracks/sml/exercises/two-fer/test.sml +21 -0
- data/tracks/sml/exercises/two-fer/testlib.sml +159 -0
- data/tracks/sml/exercises/two-fer/two-fer.sml +2 -0
- metadata +43 -5
- data/tracks/csharp/exercises/Exercises.All.sln +0 -1545
- data/tracks/csharp/exercises/Exercises.Default.sln +0 -1503
- data/tracks/csharp/exercises/Exercises.Refactoring.sln +0 -61
@@ -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,55 @@
|
|
1
|
+
# Rna Transcription
|
2
|
+
|
3
|
+
Given a DNA strand, return its RNA complement (per RNA transcription).
|
4
|
+
|
5
|
+
Both DNA and RNA strands are a sequence of nucleotides.
|
6
|
+
|
7
|
+
The four nucleotides found in DNA are adenine (**A**), cytosine (**C**),
|
8
|
+
guanine (**G**) and thymine (**T**).
|
9
|
+
|
10
|
+
The four nucleotides found in RNA are adenine (**A**), cytosine (**C**),
|
11
|
+
guanine (**G**) and uracil (**U**).
|
12
|
+
|
13
|
+
Given a DNA strand, its transcribed RNA strand is formed by replacing
|
14
|
+
each nucleotide with its complement:
|
15
|
+
|
16
|
+
* `G` -> `C`
|
17
|
+
* `C` -> `G`
|
18
|
+
* `T` -> `A`
|
19
|
+
* `A` -> `U`
|
20
|
+
|
21
|
+
## Loading your exercise implementation in PolyML
|
22
|
+
|
23
|
+
```
|
24
|
+
$ poly --use {exercise}.sml
|
25
|
+
```
|
26
|
+
|
27
|
+
Or:
|
28
|
+
|
29
|
+
```
|
30
|
+
$ poly
|
31
|
+
> use "{exercise}.sml";
|
32
|
+
```
|
33
|
+
|
34
|
+
**Note:** You have to replace {exercise}.
|
35
|
+
|
36
|
+
## Running the tests
|
37
|
+
|
38
|
+
```
|
39
|
+
$ poly -q --use test.sml
|
40
|
+
```
|
41
|
+
|
42
|
+
## Feedback, Issues, Pull Requests
|
43
|
+
|
44
|
+
The [exercism/sml](https://github.com/exercism/sml) repository on
|
45
|
+
GitHub is the home for all of the Standard ML exercises.
|
46
|
+
|
47
|
+
If you have feedback about an exercise, or want to help implementing a new
|
48
|
+
one, head over there and create an issue. We'll do our best to help you!
|
49
|
+
|
50
|
+
## Source
|
51
|
+
|
52
|
+
Rosalind [http://rosalind.info/problems/rna](http://rosalind.info/problems/rna)
|
53
|
+
|
54
|
+
## Submitting Incomplete Solutions
|
55
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
fun toRna dna =
|
2
|
+
let
|
3
|
+
fun translate #"G" = SOME #"C"
|
4
|
+
| translate #"C" = SOME #"G"
|
5
|
+
| translate #"T" = SOME #"A"
|
6
|
+
| translate #"A" = SOME #"U"
|
7
|
+
| translate _ = NONE
|
8
|
+
|
9
|
+
fun reducer (_, NONE) = NONE
|
10
|
+
| reducer (x, SOME acc) =
|
11
|
+
let
|
12
|
+
val t = translate x
|
13
|
+
in
|
14
|
+
case t of
|
15
|
+
NONE => NONE
|
16
|
+
| SOME c => SOME (c :: acc)
|
17
|
+
end
|
18
|
+
in
|
19
|
+
Option.map implode (foldr reducer (SOME []) (explode dna))
|
20
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
(* version 1.0.1 *)
|
2
|
+
|
3
|
+
use "testlib.sml";
|
4
|
+
use "rna-transcription.sml";
|
5
|
+
|
6
|
+
infixr |>
|
7
|
+
fun x |> f = f x
|
8
|
+
|
9
|
+
val testsuite =
|
10
|
+
describe "rna-transcription" [
|
11
|
+
test "RNA complement of cytosine is guanine"
|
12
|
+
(fn _ => toRna ("C") |> Expect.equalTo (SOME "G")),
|
13
|
+
|
14
|
+
test "RNA complement of guanine is cytosine"
|
15
|
+
(fn _ => toRna ("G") |> Expect.equalTo (SOME "C")),
|
16
|
+
|
17
|
+
test "RNA complement of thymine is adenine"
|
18
|
+
(fn _ => toRna ("T") |> Expect.equalTo (SOME "A")),
|
19
|
+
|
20
|
+
test "RNA complement of adenine is uracil"
|
21
|
+
(fn _ => toRna ("A") |> Expect.equalTo (SOME "U")),
|
22
|
+
|
23
|
+
test "RNA complement"
|
24
|
+
(fn _ => toRna ("ACGTGGTCTTAA") |> Expect.equalTo (SOME "UGCACCAGAAUU")),
|
25
|
+
|
26
|
+
test "correctly handles invalid input (RNA instead of DNA)"
|
27
|
+
(fn _ => toRna ("U") |> Expect.equalTo NONE),
|
28
|
+
|
29
|
+
test "correctly handles completely invalid DNA input"
|
30
|
+
(fn _ => toRna ("XXX") |> Expect.equalTo NONE),
|
31
|
+
|
32
|
+
test "correctly handles partially invalid DNA input"
|
33
|
+
(fn _ => toRna ("ACGTXXXCTTAA") |> Expect.equalTo NONE)
|
34
|
+
]
|
35
|
+
|
36
|
+
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,48 @@
|
|
1
|
+
# Sum Of Multiples
|
2
|
+
|
3
|
+
Given a number, find the sum of all the multiples of particular numbers up to
|
4
|
+
but not including that number.
|
5
|
+
|
6
|
+
If we list all the natural numbers up to but not including 20 that are
|
7
|
+
multiples of either 3 or 5, we get 3, 5, 6 and 9, 10, 12, 15, and 18.
|
8
|
+
|
9
|
+
The sum of these multiples is 78.
|
10
|
+
|
11
|
+
Given a number, find the sum of the multiples of a given set of numbers,
|
12
|
+
up to but not including that number.
|
13
|
+
|
14
|
+
## Loading your exercise implementation in PolyML
|
15
|
+
|
16
|
+
```
|
17
|
+
$ poly --use {exercise}.sml
|
18
|
+
```
|
19
|
+
|
20
|
+
Or:
|
21
|
+
|
22
|
+
```
|
23
|
+
$ poly
|
24
|
+
> use "{exercise}.sml";
|
25
|
+
```
|
26
|
+
|
27
|
+
**Note:** You have to replace {exercise}.
|
28
|
+
|
29
|
+
## Running the tests
|
30
|
+
|
31
|
+
```
|
32
|
+
$ poly -q --use test.sml
|
33
|
+
```
|
34
|
+
|
35
|
+
## Feedback, Issues, Pull Requests
|
36
|
+
|
37
|
+
The [exercism/sml](https://github.com/exercism/sml) repository on
|
38
|
+
GitHub is the home for all of the Standard ML exercises.
|
39
|
+
|
40
|
+
If you have feedback about an exercise, or want to help implementing a new
|
41
|
+
one, head over there and create an issue. We'll do our best to help you!
|
42
|
+
|
43
|
+
## Source
|
44
|
+
|
45
|
+
A variation on Problem 1 at Project Euler [http://projecteuler.net/problem=1](http://projecteuler.net/problem=1)
|
46
|
+
|
47
|
+
## Submitting Incomplete Solutions
|
48
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|