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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/lib/trackler/version.rb +1 -1
  3. data/problem-specifications/exercises/pov/description.md +0 -2
  4. data/problem-specifications/exercises/protein-translation/canonical-data.json +3 -3
  5. data/problem-specifications/exercises/simple-cipher/description.md +4 -6
  6. data/tracks/csharp/exercises/all-your-base/AllYourBaseTest.cs +7 -7
  7. data/tracks/csharp/exercises/dominoes/README.md +2 -11
  8. data/tracks/csharp/exercises/reverse-string/ReverseStringTest.cs +2 -2
  9. data/tracks/dart/CONTRIBUTING.md +7 -4
  10. data/tracks/delphi/config.json +23 -20
  11. data/tracks/ecmascript/CONTRIBUTING.md +3 -0
  12. data/tracks/ecmascript/README.md +2 -5
  13. data/tracks/fsharp/config.json +11 -0
  14. data/tracks/fsharp/exercises/Exercises.sln +6 -0
  15. data/tracks/fsharp/exercises/all-your-base/AllYourBaseTest.fs +7 -7
  16. data/tracks/fsharp/exercises/diamond/Diamond.fsproj +1 -0
  17. data/tracks/fsharp/exercises/diamond/DiamondTest.fs +111 -114
  18. data/tracks/fsharp/exercises/diamond/README.md +2 -1
  19. data/tracks/fsharp/exercises/dominoes/README.md +2 -5
  20. data/tracks/fsharp/exercises/palindrome-products/Example.fs +27 -19
  21. data/tracks/fsharp/exercises/palindrome-products/PalindromeProducts.fs +3 -3
  22. data/tracks/fsharp/exercises/palindrome-products/PalindromeProductsTest.fs +52 -49
  23. data/tracks/fsharp/exercises/reverse-string/ReverseStringTest.fs +2 -2
  24. data/tracks/fsharp/exercises/spiral-matrix/Example.fs +35 -0
  25. data/tracks/fsharp/exercises/spiral-matrix/Program.fs +1 -0
  26. data/tracks/fsharp/exercises/spiral-matrix/README.md +25 -0
  27. data/tracks/fsharp/exercises/spiral-matrix/SpiralMatrix.fs +3 -0
  28. data/tracks/fsharp/exercises/spiral-matrix/SpiralMatrix.fsproj +23 -0
  29. data/tracks/fsharp/exercises/spiral-matrix/SpiralMatrixTest.fs +47 -0
  30. data/tracks/fsharp/generators/Generators.fs +42 -5
  31. data/tracks/fsharp/generators/Properties/launchSettings.json +1 -2
  32. data/tracks/java/config.json +7 -2
  33. data/tracks/java/exercises/binary-search-tree/src/test/java/BinarySearchTreeTest.java +0 -1
  34. data/tracks/javascript/.eslintignore +1 -2
  35. data/tracks/javascript/exercises/wordy/example.js +2 -2
  36. data/tracks/perl6/exercises/atbash-cipher/AtbashCipher.pm6 +6 -0
  37. data/tracks/perl6/exercises/atbash-cipher/atbash-cipher.t +2 -9
  38. data/tracks/perl6/exercises/atbash-cipher/example.yaml +8 -9
  39. data/tracks/perl6/exercises/grade-school/Example.pm6 +1 -1
  40. data/tracks/perl6/exercises/grade-school/GradeSchool.pm6 +1 -1
  41. data/tracks/perl6/exercises/grade-school/example.yaml +19 -12
  42. data/tracks/perl6/exercises/grade-school/grade-school.t +19 -12
  43. data/tracks/python/.github/stale.yml +6 -3
  44. data/tracks/python/config.json +17 -0
  45. data/tracks/python/exercises/dot-dsl/.meta/hints.md +14 -0
  46. data/tracks/python/exercises/dot-dsl/README.md +52 -0
  47. data/tracks/python/exercises/dot-dsl/dot_dsl.py +27 -0
  48. data/tracks/python/exercises/dot-dsl/dot_dsl_test.py +117 -0
  49. data/tracks/python/exercises/dot-dsl/example.py +52 -0
  50. data/tracks/python/exercises/proverb/README.md +5 -2
  51. data/tracks/python/exercises/proverb/example.py +5 -5
  52. data/tracks/python/exercises/proverb/proverb.py +1 -1
  53. data/tracks/python/exercises/proverb/proverb_test.py +42 -52
  54. data/tracks/python/exercises/say/example.py +2 -2
  55. data/tracks/python/exercises/say/say_test.py +2 -2
  56. data/tracks/rust/README.md +2 -0
  57. data/tracks/rust/_test/count-ignores.sh +15 -8
  58. data/tracks/rust/bin/test-exercise +4 -1
  59. data/tracks/rust/exercises/perfect-numbers/.meta/ignore-count-ignores +6 -0
  60. data/tracks/rust/exercises/perfect-numbers/tests/perfect-numbers.rs +32 -22
  61. data/tracks/typescript/config.json +16 -0
  62. data/tracks/typescript/exercises/two-bucket/README.md +66 -0
  63. data/tracks/typescript/exercises/two-bucket/package.json +36 -0
  64. data/tracks/typescript/exercises/two-bucket/tsconfig.json +22 -0
  65. data/tracks/typescript/exercises/two-bucket/tslint.json +127 -0
  66. data/tracks/typescript/exercises/two-bucket/two-bucket.example.ts +97 -0
  67. data/tracks/typescript/exercises/two-bucket/two-bucket.test.ts +47 -0
  68. data/tracks/typescript/exercises/two-bucket/two-bucket.ts +0 -0
  69. data/tracks/typescript/exercises/two-bucket/yarn.lock +2624 -0
  70. 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
- type DiamondTest() =
9
- let split (x: string) = x.Split([| '\n' |], StringSplitOptions.None)
10
+ let split (x: string) = x.Split([| '\n' |], StringSplitOptions.None)
10
11
 
11
- let trim (x:string) = x.Trim()
12
+ let trim (x:string) = x.Trim()
12
13
 
13
- let leadingSpaces (x:string) = x.Substring(0, x.IndexOfAny [|'A'..'Z'|])
14
+ let leadingSpaces (x:string) = x.Substring(0, x.IndexOfAny [|'A'..'Z'|])
14
15
 
15
- let trailingSpaces (x:string) = x.Substring(x.LastIndexOfAny [|'A'..'Z'|] + 1)
16
-
17
- [<Theory>]
18
- [<MemberData("Letters")>]
19
- member this.``First row contains 'A'`` (letter:char) =
20
- let actual = make letter
21
- let rows = actual |> split
22
- let firstRowCharacters = rows |> Seq.head |> trim
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
- firstRowCharacters |> should equal "A"
25
-
26
- [<Theory(Skip = "Remove to run test")>]
27
- [<MemberData("Letters")>]
28
- member this.``All rows must have symmetric contour`` (letter:char) =
29
- let actual = make letter
30
- let rows = actual |> split
31
- let symmetric (row:string) = leadingSpaces row = trailingSpaces row
32
-
33
- rows |> Array.iter (fun x -> symmetric x |> should equal true)
34
-
35
- [<Theory(Skip = "Remove to run test")>]
36
- [<MemberData("Letters")>]
37
- member this.``Top of figure has letters in correct order`` (letter:char) =
38
- let actual = make letter
39
-
40
- let expected = ['A'..letter]
41
- let rows = actual |> split
42
- let firstNonSpaceLetters =
43
- rows
44
- |> Seq.take expected.Length
45
- |> Seq.map (trim >> Seq.head)
46
- |> Seq.toList
47
-
48
- expected |> should equal firstNonSpaceLetters
49
-
50
- [<Theory(Skip = "Remove to run test")>]
51
- [<MemberData("Letters")>]
52
- member this.``Figure is symmetric around the horizontal axis`` (letter:char) =
53
- let actual = make letter
54
-
55
- let rows = actual |> split
56
- let top =
57
- rows
58
- |> Seq.takeWhile (fun x -> not (x.Contains(string letter)))
59
- |> List.ofSeq
60
-
61
- let bottom =
62
- rows
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
- [<Theory(Skip = "Remove to run test")>]
70
- [<MemberData("Letters")>]
71
- member this.``Diamond has square shape`` (letter:char) =
72
- let actual = make letter
73
-
74
- let rows = actual |> split
75
- let expected = rows.Length
76
- let correctWidth (x:string) = x.Length = expected
77
-
78
- rows |> Array.iter (fun x -> correctWidth x |> should equal true)
79
-
80
- [<Theory(Skip = "Remove to run test")>]
81
- [<MemberData("Letters")>]
82
- member this.``All rows except top and bottom have two identical letters`` (letter:char) =
83
- let actual = make letter
84
-
85
- let rows =
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
- Make a chain of dominoes.
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 compute something
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 Palindrome
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
- let allPalindromes =
14
- [for y in minFactor..maxFactor do
15
- for x in minFactor ..y do
16
- if isPalindrome (x * y) then
17
- yield x * y, (x, y)]
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
- let value =
20
- allPalindromes
21
- |> List.map fst
22
- |> predicate
23
-
24
- let factors =
25
- allPalindromes
26
- |> List.filter (fun x -> fst x = value)
27
- |> List.map snd
28
- |> List.sort
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
- (value, factors)
37
+ Some (value, factors)
31
38
 
32
- let largestPalindrome minFactor maxFactor = palindrome List.max minFactor maxFactor
33
- let smallestPalindrome minFactor maxFactor = palindrome List.min minFactor maxFactor
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 Palindrome
1
+ module PalindromeProducts
2
2
 
3
- let largestPalindrome minFactor maxFactor = failwith "You need to implement this function."
3
+ let largest minFactor maxFactor = failwith "You need to implement this function."
4
4
 
5
- let smallestPalindrome minFactor maxFactor = failwith "You need to implement this function."
5
+ let smallest minFactor maxFactor = failwith "You need to implement this function."
@@ -1,54 +1,57 @@
1
- module PalindromeTest
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 Palindrome
8
+ open PalindromeProducts
7
9
 
8
10
  [<Fact>]
9
- let ``Largest palindrome from single digit factors`` () =
10
- let (largest, factors) = largestPalindrome 1 9
11
- largest |> should equal 9
12
- factors |> should equal [(1, 9); (3, 3)]
13
-
14
- [<Fact(Skip = "Remove to run test")>]
15
- let ``Smallest palindrome from single digit factors`` () =
16
- let (smallest, factors) = smallestPalindrome 1 9
17
- smallest |> should equal 1
18
- factors |> should equal [(1, 1)]
19
-
20
- [<Fact(Skip = "Remove to run test")>]
21
- let ``Largest palindrome from double digit actors`` () =
22
- let (largest, factors) = largestPalindrome 10 99
23
- largest |> should equal 9009
24
- factors |> should equal [(91, 99)]
25
-
26
- [<Fact(Skip = "Remove to run test")>]
27
- let ``Smallest palindrome from double digit factors`` () =
28
- let (smallest, factors) = smallestPalindrome 10 99
29
- smallest |> should equal 121
30
- factors |> should equal [(11, 11)]
31
-
32
- [<Fact(Skip = "Remove to run test")>]
33
- let ``Largest palindrome from triple digit factors`` () =
34
- let (largest, factors) = largestPalindrome 100 999
35
- largest |> should equal 906609
36
- factors |> should equal [(913, 993)]
37
-
38
- [<Fact(Skip = "Remove to run test")>]
39
- let ``Smallest palindrome from triple digit factors`` () =
40
- let (smallest, factors) = smallestPalindrome 100 999
41
- smallest |> should equal 10201
42
- factors |> should equal [(101, 101)]
43
-
44
- [<Fact(Skip = "Remove to run test")>]
45
- let ``Largest palindrome from four digit factors`` () =
46
- let (largest, factors) = largestPalindrome 1000 9999
47
- largest |> should equal 99000099
48
- factors |> should equal [(9901, 9999)]
49
-
50
- [<Fact(Skip = "Remove to run test")>]
51
- let ``Smallest palindrome from four digit factors`` () =
52
- let (smallest, factors) = smallestPalindrome 1000 9999
53
- smallest |> should equal 1002001
54
- factors |> should equal [(1001, 1001)]
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.0 of the canonical data.
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 ``Empty string`` () =
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,3 @@
1
+ module SpiralMatrix
2
+
3
+ let spiralMatrix size = failwith "You need to implement this function."
@@ -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
+