trackler 2.2.1.68 → 2.2.1.69

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 (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
+