Skip to content

Commit e22110c

Browse files
authored
Add Spiral Matrix Exercise (exercism#864)
1 parent ade61ec commit e22110c

File tree

10 files changed

+228
-0
lines changed

10 files changed

+228
-0
lines changed

config.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,6 +1181,19 @@
11811181
"transforming"
11821182
]
11831183
},
1184+
{
1185+
"slug": "spiral-matrix",
1186+
"name": "Spiral Matrix",
1187+
"uuid": "a08ec5a6-80dd-4c03-a125-d28a857836c4",
1188+
"practices": [],
1189+
"prerequisites": [],
1190+
"difficulty": 5,
1191+
"topics": [
1192+
"algorithms",
1193+
"matrices",
1194+
"loops"
1195+
]
1196+
},
11841197
{
11851198
"slug": "bowling",
11861199
"name": "Bowling",
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Instructions
2+
3+
Your task is to return a square matrix of a given size.
4+
5+
The matrix should be filled with natural numbers, starting from 1 in the top-left corner, increasing in an inward, clockwise spiral order, like these examples:
6+
7+
## Examples
8+
9+
### Spiral matrix of size 3
10+
11+
```text
12+
1 2 3
13+
8 9 4
14+
7 6 5
15+
```
16+
17+
### Spiral matrix of size 4
18+
19+
```text
20+
1 2 3 4
21+
12 13 14 5
22+
11 16 15 6
23+
10 9 8 7
24+
```
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Introduction
2+
3+
In a small village near an ancient forest, there was a legend of a hidden treasure buried deep within the woods.
4+
Despite numerous attempts, no one had ever succeeded in finding it.
5+
This was about to change, however, thanks to a young explorer named Elara.
6+
She had discovered an old document containing instructions on how to locate the treasure.
7+
Using these instructions, Elara was able to draw a map that revealed the path to the treasure.
8+
9+
To her surprise, the path followed a peculiar clockwise spiral.
10+
It was no wonder no one had been able to find the treasure before!
11+
With the map in hand, Elara embarks on her journey to uncover the hidden treasure.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
2+
func spiralMatrix(size: Int) -> [[Int]] {
3+
if size <= 0 { return [] }
4+
else if size == 1 { return [[1]] }
5+
6+
var matrix = Array(repeating: Array(repeating: 0, count: size), count: size)
7+
var rowStart = 0
8+
var rowEnd = size - 1
9+
var columnStart = 0
10+
var columnEnd = size - 1
11+
var counter = 1
12+
13+
while (rowStart <= rowEnd && columnStart <= columnEnd) {
14+
if columnStart <= columnEnd {
15+
for i in columnStart...columnEnd {
16+
matrix[rowStart][i] = counter
17+
counter += 1
18+
}
19+
}
20+
rowStart += 1
21+
22+
if rowStart <= rowEnd {
23+
for i in rowStart...rowEnd {
24+
matrix[i][columnEnd] = counter
25+
counter += 1
26+
}
27+
}
28+
columnEnd -= 1
29+
30+
if columnStart <= columnEnd {
31+
for i in stride(from: columnEnd, through: columnStart, by: -1) {
32+
matrix[rowEnd][i] = counter
33+
counter += 1
34+
}
35+
}
36+
rowEnd -= 1
37+
38+
if rowStart <= rowEnd {
39+
for i in stride(from: rowEnd, through: rowStart, by: -1) {
40+
matrix[i][columnStart] = counter
41+
counter += 1
42+
}
43+
44+
}
45+
columnStart += 1
46+
}
47+
return matrix
48+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"Sencudra"
4+
],
5+
"files": {
6+
"solution": [
7+
"Sources/SpiralMatrix/SpiralMatrix.swift"
8+
],
9+
"test": [
10+
"Tests/SpiralMatrixTests/SpiralMatrixTests.swift"
11+
],
12+
"example": [
13+
".meta/Sources/SpiralMatrix/SpiralMatrixExample.swift"
14+
]
15+
},
16+
"blurb": "Given the size, return a square matrix of numbers in spiral order.",
17+
"source": "Reddit r/dailyprogrammer challenge #320 [Easy] Spiral Ascension.",
18+
"source_url": "https://web.archive.org/web/20230607064729/https://old.reddit.com/r/dailyprogrammer/comments/6i60lr/20170619_challenge_320_easy_spiral_ascension/"
19+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import Testing
2+
import Foundation
3+
@testable import {{exercise|camelCase}}
4+
5+
let RUNALL = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false
6+
7+
@Suite struct {{exercise|camelCase}}Tests {
8+
{% for case in cases %}
9+
{% if forloop.first -%}
10+
@Test("{{case.description}}")
11+
{% else -%}
12+
@Test("{{case.description}}", .enabled(if: RUNALL))
13+
{% endif -%}
14+
func test{{case.description | camelCase }}() {
15+
#expect({{ case.property }}(size: {{case.input.size}}) == {{case.expected }})
16+
}
17+
{% endfor -%}
18+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[8f584201-b446-4bc9-b132-811c8edd9040]
13+
description = "empty spiral"
14+
15+
[e40ae5f3-e2c9-4639-8116-8a119d632ab2]
16+
description = "trivial spiral"
17+
18+
[cf05e42d-eb78-4098-a36e-cdaf0991bc48]
19+
description = "spiral of size 2"
20+
21+
[1c475667-c896-4c23-82e2-e033929de939]
22+
description = "spiral of size 3"
23+
24+
[05ccbc48-d891-44f5-9137-f4ce462a759d]
25+
description = "spiral of size 4"
26+
27+
[f4d2165b-1738-4e0c-bed0-c459045ae50d]
28+
description = "spiral of size 5"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// swift-tools-version:6.0
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "SpiralMatrix",
7+
products: [
8+
.library(
9+
name: "SpiralMatrix",
10+
targets: ["SpiralMatrix"])
11+
],
12+
dependencies: [],
13+
targets: [
14+
.target(
15+
name: "SpiralMatrix",
16+
dependencies: []),
17+
.testTarget(
18+
name: "SpiralMatrixTests",
19+
dependencies: ["SpiralMatrix"]),
20+
]
21+
)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
2+
// Write your code for the 'SpiralMatrix' exercise in this file.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import Foundation
2+
import Testing
3+
4+
@testable import SpiralMatrix
5+
6+
let RUNALL = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false
7+
8+
@Suite struct SpiralMatrixTests {
9+
10+
@Test("empty spiral")
11+
func testEmptySpiral() {
12+
#expect(spiralMatrix(size: 0) == [])
13+
}
14+
15+
@Test("trivial spiral", .enabled(if: RUNALL))
16+
func testTrivialSpiral() {
17+
#expect(spiralMatrix(size: 1) == [[1]])
18+
}
19+
20+
@Test("spiral of size 2", .enabled(if: RUNALL))
21+
func testSpiralOfSize2() {
22+
#expect(spiralMatrix(size: 2) == [[1, 2], [4, 3]])
23+
}
24+
25+
@Test("spiral of size 3", .enabled(if: RUNALL))
26+
func testSpiralOfSize3() {
27+
#expect(spiralMatrix(size: 3) == [[1, 2, 3], [8, 9, 4], [7, 6, 5]])
28+
}
29+
30+
@Test("spiral of size 4", .enabled(if: RUNALL))
31+
func testSpiralOfSize4() {
32+
#expect(
33+
spiralMatrix(size: 4) == [[1, 2, 3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10, 9, 8, 7]])
34+
}
35+
36+
@Test("spiral of size 5", .enabled(if: RUNALL))
37+
func testSpiralOfSize5() {
38+
#expect(
39+
spiralMatrix(size: 5) == [
40+
[1, 2, 3, 4, 5], [16, 17, 18, 19, 6], [15, 24, 25, 20, 7], [14, 23, 22, 21, 8],
41+
[13, 12, 11, 10, 9],
42+
])
43+
}
44+
}

0 commit comments

Comments
 (0)