trackler 2.2.1.68 → 2.2.1.69
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/trackler/version.rb +1 -1
- data/problem-specifications/exercises/pov/description.md +0 -2
- data/problem-specifications/exercises/protein-translation/canonical-data.json +3 -3
- data/problem-specifications/exercises/simple-cipher/description.md +4 -6
- data/tracks/csharp/exercises/all-your-base/AllYourBaseTest.cs +7 -7
- data/tracks/csharp/exercises/dominoes/README.md +2 -11
- data/tracks/csharp/exercises/reverse-string/ReverseStringTest.cs +2 -2
- data/tracks/dart/CONTRIBUTING.md +7 -4
- data/tracks/delphi/config.json +23 -20
- data/tracks/ecmascript/CONTRIBUTING.md +3 -0
- data/tracks/ecmascript/README.md +2 -5
- data/tracks/fsharp/config.json +11 -0
- data/tracks/fsharp/exercises/Exercises.sln +6 -0
- data/tracks/fsharp/exercises/all-your-base/AllYourBaseTest.fs +7 -7
- data/tracks/fsharp/exercises/diamond/Diamond.fsproj +1 -0
- data/tracks/fsharp/exercises/diamond/DiamondTest.fs +111 -114
- data/tracks/fsharp/exercises/diamond/README.md +2 -1
- data/tracks/fsharp/exercises/dominoes/README.md +2 -5
- data/tracks/fsharp/exercises/palindrome-products/Example.fs +27 -19
- data/tracks/fsharp/exercises/palindrome-products/PalindromeProducts.fs +3 -3
- data/tracks/fsharp/exercises/palindrome-products/PalindromeProductsTest.fs +52 -49
- data/tracks/fsharp/exercises/reverse-string/ReverseStringTest.fs +2 -2
- data/tracks/fsharp/exercises/spiral-matrix/Example.fs +35 -0
- data/tracks/fsharp/exercises/spiral-matrix/Program.fs +1 -0
- data/tracks/fsharp/exercises/spiral-matrix/README.md +25 -0
- data/tracks/fsharp/exercises/spiral-matrix/SpiralMatrix.fs +3 -0
- data/tracks/fsharp/exercises/spiral-matrix/SpiralMatrix.fsproj +23 -0
- data/tracks/fsharp/exercises/spiral-matrix/SpiralMatrixTest.fs +47 -0
- data/tracks/fsharp/generators/Generators.fs +42 -5
- data/tracks/fsharp/generators/Properties/launchSettings.json +1 -2
- data/tracks/java/config.json +7 -2
- data/tracks/java/exercises/binary-search-tree/src/test/java/BinarySearchTreeTest.java +0 -1
- data/tracks/javascript/.eslintignore +1 -2
- data/tracks/javascript/exercises/wordy/example.js +2 -2
- data/tracks/perl6/exercises/atbash-cipher/AtbashCipher.pm6 +6 -0
- data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +2 -9
- data/tracks/perl6/exercises/atbash-cipher/example.yaml +8 -9
- data/tracks/perl6/exercises/grade-school/Example.pm6 +1 -1
- data/tracks/perl6/exercises/grade-school/GradeSchool.pm6 +1 -1
- data/tracks/perl6/exercises/grade-school/example.yaml +19 -12
- data/tracks/perl6/exercises/grade-school/grade-school.t +19 -12
- data/tracks/python/.github/stale.yml +6 -3
- data/tracks/python/config.json +17 -0
- data/tracks/python/exercises/dot-dsl/.meta/hints.md +14 -0
- data/tracks/python/exercises/dot-dsl/README.md +52 -0
- data/tracks/python/exercises/dot-dsl/dot_dsl.py +27 -0
- data/tracks/python/exercises/dot-dsl/dot_dsl_test.py +117 -0
- data/tracks/python/exercises/dot-dsl/example.py +52 -0
- data/tracks/python/exercises/proverb/README.md +5 -2
- data/tracks/python/exercises/proverb/example.py +5 -5
- data/tracks/python/exercises/proverb/proverb.py +1 -1
- data/tracks/python/exercises/proverb/proverb_test.py +42 -52
- data/tracks/python/exercises/say/example.py +2 -2
- data/tracks/python/exercises/say/say_test.py +2 -2
- data/tracks/rust/README.md +2 -0
- data/tracks/rust/_test/count-ignores.sh +15 -8
- data/tracks/rust/bin/test-exercise +4 -1
- data/tracks/rust/exercises/perfect-numbers/.meta/ignore-count-ignores +6 -0
- data/tracks/rust/exercises/perfect-numbers/tests/perfect-numbers.rs +32 -22
- data/tracks/typescript/config.json +16 -0
- data/tracks/typescript/exercises/two-bucket/README.md +66 -0
- data/tracks/typescript/exercises/two-bucket/package.json +36 -0
- data/tracks/typescript/exercises/two-bucket/tsconfig.json +22 -0
- data/tracks/typescript/exercises/two-bucket/tslint.json +127 -0
- data/tracks/typescript/exercises/two-bucket/two-bucket.example.ts +97 -0
- data/tracks/typescript/exercises/two-bucket/two-bucket.test.ts +47 -0
- data/tracks/typescript/exercises/two-bucket/two-bucket.ts +0 -0
- data/tracks/typescript/exercises/two-bucket/yarn.lock +2624 -0
- metadata +23 -2
@@ -2,124 +2,121 @@ module DiamondTest
|
|
2
2
|
|
3
3
|
open Diamond
|
4
4
|
open System
|
5
|
-
open Xunit
|
6
5
|
open FsUnit.Xunit
|
6
|
+
open Xunit
|
7
|
+
open FsCheck
|
8
|
+
open FsCheck.Xunit
|
7
9
|
|
8
|
-
|
9
|
-
let split (x: string) = x.Split([| '\n' |], StringSplitOptions.None)
|
10
|
+
let split (x: string) = x.Split([| '\n' |], StringSplitOptions.None)
|
10
11
|
|
11
|
-
|
12
|
+
let trim (x:string) = x.Trim()
|
12
13
|
|
13
|
-
|
14
|
+
let leadingSpaces (x:string) = x.Substring(0, x.IndexOfAny [|'A'..'Z'|])
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
let trailingSpaces (x:string) = x.Substring(x.LastIndexOfAny [|'A'..'Z'|] + 1)
|
17
|
+
|
18
|
+
type Letters =
|
19
|
+
static member Chars () =
|
20
|
+
Arb.Default.Char()
|
21
|
+
|> Arb.filter (fun c -> 'A' <= c && c <= 'Z')
|
22
|
+
|
23
|
+
type DiamondPropertyAttribute () =
|
24
|
+
inherit PropertyAttribute(Arbitrary = [| typeof<Letters> |])
|
25
|
+
|
26
|
+
[<DiamondProperty>]
|
27
|
+
let ``First row contains 'A'`` (letter:char) =
|
28
|
+
let actual = make letter
|
29
|
+
let rows = actual |> split
|
30
|
+
let firstRowCharacters = rows |> Seq.head |> trim
|
31
|
+
|
32
|
+
firstRowCharacters |> should equal "A"
|
33
|
+
|
34
|
+
[<DiamondProperty(Skip = "Remove to run test")>]
|
35
|
+
let ``All rows must have symmetric contour`` (letter:char) =
|
36
|
+
let actual = make letter
|
37
|
+
let rows = actual |> split
|
38
|
+
let symmetric (row:string) = leadingSpaces row = trailingSpaces row
|
39
|
+
|
40
|
+
rows |> Array.iter (fun x -> symmetric x |> should equal true)
|
41
|
+
|
42
|
+
[<DiamondProperty(Skip = "Remove to run test")>]
|
43
|
+
let ``Top of figure has letters in correct order`` (letter:char) =
|
44
|
+
let actual = make letter
|
45
|
+
|
46
|
+
let expected = ['A'..letter]
|
47
|
+
let rows = actual |> split
|
48
|
+
let firstNonSpaceLetters =
|
49
|
+
rows
|
50
|
+
|> Seq.take expected.Length
|
51
|
+
|> Seq.map (trim >> Seq.head)
|
52
|
+
|> Seq.toList
|
53
|
+
|
54
|
+
expected |> should equal firstNonSpaceLetters
|
55
|
+
|
56
|
+
[<DiamondProperty(Skip = "Remove to run test")>]
|
57
|
+
let ``Figure is symmetric around the horizontal axis`` (letter:char) =
|
58
|
+
let actual = make letter
|
59
|
+
|
60
|
+
let rows = actual |> split
|
61
|
+
let top =
|
62
|
+
rows
|
63
|
+
|> Seq.takeWhile (fun x -> not (x.Contains(string letter)))
|
64
|
+
|> List.ofSeq
|
23
65
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
let
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|> Array.rev
|
64
|
-
|> Seq.takeWhile (fun x -> not (x.Contains(string letter)))
|
65
|
-
|> List.ofSeq
|
66
|
-
|
67
|
-
top |> should equal bottom
|
66
|
+
let bottom =
|
67
|
+
rows
|
68
|
+
|> Array.rev
|
69
|
+
|> Seq.takeWhile (fun x -> not (x.Contains(string letter)))
|
70
|
+
|> List.ofSeq
|
71
|
+
|
72
|
+
top |> should equal bottom
|
73
|
+
|
74
|
+
[<DiamondProperty(Skip = "Remove to run test")>]
|
75
|
+
let ``Diamond has square shape`` (letter:char) =
|
76
|
+
let actual = make letter
|
77
|
+
|
78
|
+
let rows = actual |> split
|
79
|
+
let expected = rows.Length
|
80
|
+
let correctWidth (x:string) = x.Length = expected
|
81
|
+
|
82
|
+
rows |> Array.iter (fun x -> correctWidth x |> should equal true)
|
83
|
+
|
84
|
+
[<DiamondProperty(Skip = "Remove to run test")>]
|
85
|
+
let ``All rows except top and bottom have two identical letters`` (letter:char) =
|
86
|
+
let actual = make letter
|
87
|
+
|
88
|
+
let rows =
|
89
|
+
actual
|
90
|
+
|> split
|
91
|
+
|> Array.filter (fun x -> not (x.Contains("A")))
|
92
|
+
|
93
|
+
let twoIdenticalLetters (row:string) =
|
94
|
+
let twoCharacters = row.Replace(" ", "").Length = 2
|
95
|
+
let identicalCharacters = row.Replace(" ", "") |> Seq.distinct |> Seq.length = 1
|
96
|
+
twoCharacters && identicalCharacters
|
97
|
+
|
98
|
+
rows |> Array.iter (fun x -> twoIdenticalLetters x |> should equal true)
|
99
|
+
|
100
|
+
[<DiamondProperty(Skip = "Remove to run test")>]
|
101
|
+
let ``Bottom left corner spaces are triangle`` (letter:char) =
|
102
|
+
let actual = make letter
|
103
|
+
|
104
|
+
let rows = actual |> split
|
68
105
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
actual
|
87
|
-
|> split
|
88
|
-
|> Array.filter (fun x -> not (x.Contains("A")))
|
89
|
-
|
90
|
-
let twoIdenticalLetters (row:string) =
|
91
|
-
let twoCharacters = row.Replace(" ", "").Length = 2
|
92
|
-
let identicalCharacters = row.Replace(" ", "") |> Seq.distinct |> Seq.length = 1
|
93
|
-
twoCharacters && identicalCharacters
|
94
|
-
|
95
|
-
rows |> Array.iter (fun x -> twoIdenticalLetters x |> should equal true)
|
96
|
-
|
97
|
-
[<Theory(Skip = "Remove to run test")>]
|
98
|
-
[<MemberData("Letters")>]
|
99
|
-
member this.``Bottom left corner spaces are triangle`` (letter:char) =
|
100
|
-
let actual = make letter
|
101
|
-
|
102
|
-
let rows = actual |> split
|
103
|
-
|
104
|
-
let cornerSpaces =
|
105
|
-
rows
|
106
|
-
|> Array.rev
|
107
|
-
|> Seq.skipWhile (fun x -> not (x.Contains(string letter)))
|
108
|
-
|> Seq.map leadingSpaces
|
109
|
-
|> Seq.toList
|
110
|
-
|
111
|
-
let spaceCounts =
|
112
|
-
cornerSpaces
|
113
|
-
|> List.map (fun x -> x.Length)
|
114
|
-
|
115
|
-
let expected =
|
116
|
-
Seq.initInfinite id
|
117
|
-
|> Seq.take spaceCounts.Length
|
118
|
-
|> Seq.toList
|
119
|
-
|
120
|
-
spaceCounts |> should equal expected
|
121
|
-
|
122
|
-
static member Letters =
|
123
|
-
let theoryData = new TheoryData<char>()
|
124
|
-
[ 'A' .. 'Z' ] |> List.iter (fun c -> theoryData.Add(c))
|
125
|
-
theoryData
|
106
|
+
let cornerSpaces =
|
107
|
+
rows
|
108
|
+
|> Array.rev
|
109
|
+
|> Seq.skipWhile (fun x -> not (x.Contains(string letter)))
|
110
|
+
|> Seq.map leadingSpaces
|
111
|
+
|> Seq.toList
|
112
|
+
|
113
|
+
let spaceCounts =
|
114
|
+
cornerSpaces
|
115
|
+
|> List.map (fun x -> x.Length)
|
116
|
+
|
117
|
+
let expected =
|
118
|
+
Seq.initInfinite id
|
119
|
+
|> Seq.take spaceCounts.Length
|
120
|
+
|> Seq.toList
|
121
|
+
|
122
|
+
spaceCounts |> should equal expected
|
@@ -53,7 +53,8 @@ E·······E
|
|
53
53
|
```
|
54
54
|
|
55
55
|
## Hints
|
56
|
-
- Testing this one can be tricky without simply hardcoding a bunch of inputs and outputs. [Property based testing](https://fsharpforfunandprofit.com/posts/property-based-testing/) is another way to think about testing that allows you to more easily test this type of algorithm.
|
56
|
+
- Testing this one can be tricky without simply hardcoding a bunch of inputs and outputs. [Property based testing](https://fsharpforfunandprofit.com/posts/property-based-testing/) is another way to think about testing that allows you to more easily test this type of algorithm. The test suite uses the [FsCheck](https://fscheck.github.io/FsCheck/) property-based testing framework to define the tests.
|
57
|
+
|
57
58
|
## Source
|
58
59
|
|
59
60
|
Seb Rose [http://claysnow.co.uk/recycling-tests-in-tdd/](http://claysnow.co.uk/recycling-tests-in-tdd/)
|
@@ -1,14 +1,11 @@
|
|
1
1
|
# Dominoes
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
Compute a way to order a given set of dominoes in such a way that they form a
|
3
|
+
Compute whether there exists a way to order a given set of dominoes in such a way that they form a
|
6
4
|
correct domino chain (the dots on one half of a stone match the dots on the
|
7
5
|
neighbouring half of an adjacent stone) and that dots on the halfs of the stones
|
8
6
|
which don't have a neighbour (the first and last stone) match each other.
|
9
7
|
|
10
|
-
For example given the stones `21`, `23` and `13` you should
|
11
|
-
like `12 23 31` or `32 21 13` or `13 32 21` etc, where the first and last numbers are the same.
|
8
|
+
For example given the stones `21`, `23` and `13` you should declare that there exists a possible chain (for example, `12`, `23` and `31` is a possible chain).
|
12
9
|
|
13
10
|
For stones 12, 41 and 23 the resulting chain is not valid: 41 12 23's first and last numbers are not the same. 4 != 3
|
14
11
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module PalindromeProducts
|
2
2
|
|
3
3
|
let isPalindrome n =
|
4
4
|
let mutable current = n
|
@@ -10,24 +10,32 @@ let isPalindrome n =
|
|
10
10
|
result = n
|
11
11
|
|
12
12
|
let palindrome predicate minFactor maxFactor =
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
if minFactor > maxFactor then
|
14
|
+
None
|
15
|
+
else
|
16
|
+
let allPalindromes =
|
17
|
+
[for y in minFactor..maxFactor do
|
18
|
+
for x in minFactor ..y do
|
19
|
+
if isPalindrome (x * y) then
|
20
|
+
yield x * y, (x, y)]
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
match List.isEmpty allPalindromes with
|
23
|
+
| true ->
|
24
|
+
None
|
25
|
+
| false ->
|
26
|
+
let value =
|
27
|
+
allPalindromes
|
28
|
+
|> List.map fst
|
29
|
+
|> predicate
|
30
|
+
|
31
|
+
let factors =
|
32
|
+
allPalindromes
|
33
|
+
|> List.filter (fun x -> fst x = value)
|
34
|
+
|> List.map snd
|
35
|
+
|> List.sort
|
29
36
|
|
30
|
-
|
37
|
+
Some (value, factors)
|
31
38
|
|
32
|
-
let
|
33
|
-
|
39
|
+
let largest minFactor maxFactor = palindrome List.max minFactor maxFactor
|
40
|
+
|
41
|
+
let smallest minFactor maxFactor = palindrome List.min minFactor maxFactor
|
@@ -1,5 +1,5 @@
|
|
1
|
-
module
|
1
|
+
module PalindromeProducts
|
2
2
|
|
3
|
-
let
|
3
|
+
let largest minFactor maxFactor = failwith "You need to implement this function."
|
4
4
|
|
5
|
-
let
|
5
|
+
let smallest minFactor maxFactor = failwith "You need to implement this function."
|
@@ -1,54 +1,57 @@
|
|
1
|
-
|
1
|
+
// This file was auto-generated based on version 1.0.0 of the canonical data.
|
2
|
+
|
3
|
+
module PalindromeProductsTest
|
2
4
|
|
3
|
-
open Xunit
|
4
5
|
open FsUnit.Xunit
|
6
|
+
open Xunit
|
5
7
|
|
6
|
-
open
|
8
|
+
open PalindromeProducts
|
7
9
|
|
8
10
|
[<Fact>]
|
9
|
-
let ``
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
[<Fact(Skip = "Remove to run test")>]
|
21
|
-
let ``
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
[<Fact(Skip = "Remove to run test")>]
|
33
|
-
let ``
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
[<Fact(Skip = "Remove to run test")>]
|
45
|
-
let ``
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
11
|
+
let ``Finds the smallest palindrome from single digit factors`` () =
|
12
|
+
smallest 1 9 |> should equal (Some (1, [(1, 1)]))
|
13
|
+
|
14
|
+
[<Fact(Skip = "Remove to run test")>]
|
15
|
+
let ``Finds the largest palindrome from single digit factors`` () =
|
16
|
+
largest 1 9 |> should equal (Some (9, [(1, 9); (3, 3)]))
|
17
|
+
|
18
|
+
[<Fact(Skip = "Remove to run test")>]
|
19
|
+
let ``Find the smallest palindrome from double digit factors`` () =
|
20
|
+
smallest 10 99 |> should equal (Some (121, [(11, 11)]))
|
21
|
+
|
22
|
+
[<Fact(Skip = "Remove to run test")>]
|
23
|
+
let ``Find the largest palindrome from double digit factors`` () =
|
24
|
+
largest 10 99 |> should equal (Some (9009, [(91, 99)]))
|
25
|
+
|
26
|
+
[<Fact(Skip = "Remove to run test")>]
|
27
|
+
let ``Find smallest palindrome from triple digit factors`` () =
|
28
|
+
smallest 100 999 |> should equal (Some (10201, [(101, 101)]))
|
29
|
+
|
30
|
+
[<Fact(Skip = "Remove to run test")>]
|
31
|
+
let ``Find the largest palindrome from triple digit factors`` () =
|
32
|
+
largest 100 999 |> should equal (Some (906609, [(913, 993)]))
|
33
|
+
|
34
|
+
[<Fact(Skip = "Remove to run test")>]
|
35
|
+
let ``Find smallest palindrome from four digit factors`` () =
|
36
|
+
smallest 1000 9999 |> should equal (Some (1002001, [(1001, 1001)]))
|
37
|
+
|
38
|
+
[<Fact(Skip = "Remove to run test")>]
|
39
|
+
let ``Find the largest palindrome from four digit factors`` () =
|
40
|
+
largest 1000 9999 |> should equal (Some (99000099, [(9901, 9999)]))
|
41
|
+
|
42
|
+
[<Fact(Skip = "Remove to run test")>]
|
43
|
+
let ``Empty result for smallest if no palindrome in the range`` () =
|
44
|
+
smallest 1002 1003 |> should equal None
|
45
|
+
|
46
|
+
[<Fact(Skip = "Remove to run test")>]
|
47
|
+
let ``Empty result for largest if no palindrome in the range`` () =
|
48
|
+
largest 15 15 |> should equal None
|
49
|
+
|
50
|
+
[<Fact(Skip = "Remove to run test")>]
|
51
|
+
let ``Error result for smallest if min is more than max`` () =
|
52
|
+
smallest 10000 1 |> should equal None
|
53
|
+
|
54
|
+
[<Fact(Skip = "Remove to run test")>]
|
55
|
+
let ``Error result for largest if min is more than max`` () =
|
56
|
+
largest 2 1 |> should equal None
|
57
|
+
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// This file was auto-generated based on version 1.0.
|
1
|
+
// This file was auto-generated based on version 1.0.1 of the canonical data.
|
2
2
|
|
3
3
|
module ReverseStringTest
|
4
4
|
|
@@ -8,7 +8,7 @@ open Xunit
|
|
8
8
|
open ReverseString
|
9
9
|
|
10
10
|
[<Fact>]
|
11
|
-
let ``
|
11
|
+
let ``An empty string`` () =
|
12
12
|
reverse "" |> should equal ""
|
13
13
|
|
14
14
|
[<Fact(Skip = "Remove to run test")>]
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module SpiralMatrix
|
2
|
+
|
3
|
+
let array2DToList array =
|
4
|
+
[ for x in Array2D.base1 array .. Array2D.length1 array - 1 ->
|
5
|
+
[ for y in Array2D.base2 array .. Array2D.length2 array - 1 -> array.[x, y] ] ]
|
6
|
+
|
7
|
+
let spiralMatrix size =
|
8
|
+
let numbersToPlace = size * size
|
9
|
+
|
10
|
+
let mutable spiral = Array2D.create size size 0
|
11
|
+
let mutable currentSpiralValue = 1
|
12
|
+
let mutable firstPivot = 0
|
13
|
+
let mutable secondPivot = size - 1
|
14
|
+
|
15
|
+
let setValue x y =
|
16
|
+
spiral.[x, y] <- currentSpiralValue
|
17
|
+
currentSpiralValue <- currentSpiralValue + 1
|
18
|
+
|
19
|
+
while currentSpiralValue <= numbersToPlace do
|
20
|
+
[firstPivot .. secondPivot]
|
21
|
+
|> List.iter (fun i -> setValue firstPivot i)
|
22
|
+
|
23
|
+
[firstPivot + 1.. secondPivot]
|
24
|
+
|> List.iter (fun i -> setValue i secondPivot)
|
25
|
+
|
26
|
+
[secondPivot - 1 .. -1 .. firstPivot]
|
27
|
+
|> List.iter (fun i -> setValue secondPivot i)
|
28
|
+
|
29
|
+
[secondPivot - 1 .. -1 .. firstPivot + 1]
|
30
|
+
|> List.iter (fun i -> setValue i firstPivot)
|
31
|
+
|
32
|
+
firstPivot <- firstPivot + 1
|
33
|
+
secondPivot <- secondPivot - 1
|
34
|
+
|
35
|
+
array2DToList spiral
|
@@ -0,0 +1 @@
|
|
1
|
+
module Program = let [<EntryPoint>] main _ = 0
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Given the size, return a square matrix of numbers in spiral order.
|
2
|
+
|
3
|
+
The matrix should be filled with natural numbers, starting from 1
|
4
|
+
in the top-left corner, increasing in an inward, clockwise spiral order,
|
5
|
+
like these examples:
|
6
|
+
|
7
|
+
###### Spiral matrix of size 3
|
8
|
+
|
9
|
+
```text
|
10
|
+
1 2 3
|
11
|
+
8 9 4
|
12
|
+
7 6 5
|
13
|
+
```
|
14
|
+
|
15
|
+
###### Spiral matrix of size 4
|
16
|
+
|
17
|
+
```text
|
18
|
+
1 2 3 4
|
19
|
+
12 13 14 5
|
20
|
+
11 16 15 6
|
21
|
+
10 9 8 7
|
22
|
+
```
|
23
|
+
|
24
|
+
## Submitting Incomplete Solutions
|
25
|
+
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<Project Sdk="Microsoft.NET.Sdk">
|
2
|
+
|
3
|
+
<PropertyGroup>
|
4
|
+
<TargetFramework>netcoreapp2.0</TargetFramework>
|
5
|
+
|
6
|
+
<IsPackable>false</IsPackable>
|
7
|
+
</PropertyGroup>
|
8
|
+
|
9
|
+
<ItemGroup>
|
10
|
+
<Compile Include="SpiralMatrix.fs" />
|
11
|
+
<Compile Include="SpiralMatrixTest.fs" />
|
12
|
+
<Compile Include="Program.fs" />
|
13
|
+
</ItemGroup>
|
14
|
+
|
15
|
+
<ItemGroup>
|
16
|
+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
|
17
|
+
<PackageReference Include="xunit" Version="2.3.1" />
|
18
|
+
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
19
|
+
<PackageReference Include="FsUnit.xUnit" Version="3.0.0" />
|
20
|
+
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
21
|
+
</ItemGroup>
|
22
|
+
|
23
|
+
</Project>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
// This file was auto-generated based on version 1.0.0 of the canonical data.
|
2
|
+
|
3
|
+
module SpiralMatrixTest
|
4
|
+
|
5
|
+
open FsUnit.Xunit
|
6
|
+
open Xunit
|
7
|
+
|
8
|
+
open SpiralMatrix
|
9
|
+
|
10
|
+
[<Fact>]
|
11
|
+
let ``Empty spiral`` () =
|
12
|
+
spiralMatrix 0 |> should be Empty
|
13
|
+
|
14
|
+
[<Fact(Skip = "Remove to run test")>]
|
15
|
+
let ``Trivial spiral`` () =
|
16
|
+
spiralMatrix 1 |> should equal [[1]]
|
17
|
+
|
18
|
+
[<Fact(Skip = "Remove to run test")>]
|
19
|
+
let ``Spiral of size 2`` () =
|
20
|
+
spiralMatrix 2 |> should equal
|
21
|
+
[ [1; 2];
|
22
|
+
[4; 3] ]
|
23
|
+
|
24
|
+
[<Fact(Skip = "Remove to run test")>]
|
25
|
+
let ``Spiral of size 3`` () =
|
26
|
+
spiralMatrix 3 |> should equal
|
27
|
+
[ [1; 2; 3];
|
28
|
+
[8; 9; 4];
|
29
|
+
[7; 6; 5] ]
|
30
|
+
|
31
|
+
[<Fact(Skip = "Remove to run test")>]
|
32
|
+
let ``Spiral of size 4`` () =
|
33
|
+
spiralMatrix 4 |> should equal
|
34
|
+
[ [1; 2; 3; 4];
|
35
|
+
[12; 13; 14; 5];
|
36
|
+
[11; 16; 15; 6];
|
37
|
+
[10; 9; 8; 7] ]
|
38
|
+
|
39
|
+
[<Fact(Skip = "Remove to run test")>]
|
40
|
+
let ``Spiral of size 5`` () =
|
41
|
+
spiralMatrix 5 |> should equal
|
42
|
+
[ [1; 2; 3; 4; 5];
|
43
|
+
[16; 17; 18; 19; 6];
|
44
|
+
[15; 24; 25; 20; 7];
|
45
|
+
[14; 23; 22; 21; 8];
|
46
|
+
[13; 12; 11; 10; 9] ]
|
47
|
+
|