Skip to content

Commit 2b9223f

Browse files
authored
Add Spiral Matrix Exercise (#625)
1 parent 76b48b6 commit 2b9223f

File tree

7 files changed

+312
-0
lines changed

7 files changed

+312
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,14 @@
11561156
"prerequisites": [],
11571157
"difficulty": 6
11581158
},
1159+
{
1160+
"slug": "spiral-matrix",
1161+
"name": "Spiral Matrix",
1162+
"uuid": "a8d52588-a7af-4543-867b-17f9728df77e",
1163+
"practices": [],
1164+
"prerequisites": [],
1165+
"difficulty": 4
1166+
},
11591167
{
11601168
"slug": "zebra-puzzle",
11611169
"name": "Zebra Puzzle",
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Instructions
2+
3+
Given the size, return a square matrix of numbers in spiral order.
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: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"tomasnorre"
4+
],
5+
"files": {
6+
"solution": [
7+
"SpiralMatrix.php"
8+
],
9+
"test": [
10+
"SpiralMatrixTest.php"
11+
],
12+
"example": [
13+
".meta/example.php"
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: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
/*
4+
* By adding type hints and enabling strict type checking, code can become
5+
* easier to read, self-documenting and reduce the number of potential bugs.
6+
* By default, type declarations are non-strict, which means they will attempt
7+
* to change the original type to match the type specified by the
8+
* type-declaration.
9+
*
10+
* In other words, if you pass a string to a function requiring a float,
11+
* it will attempt to convert the string value to a float.
12+
*
13+
* To enable strict mode, a single declare directive must be placed at the top
14+
* of the file.
15+
* This means that the strictness of typing is configured on a per-file basis.
16+
* This directive not only affects the type declarations of parameters, but also
17+
* a function's return type.
18+
*
19+
* For more info review the Concept on strict type checking in the PHP track
20+
* <link>.
21+
*
22+
* To disable strict typing, comment out the directive below.
23+
*/
24+
25+
declare(strict_types=1);
26+
27+
class SpiralMatrix
28+
{
29+
public function draw(int $n): array
30+
{
31+
// Initialize the matrix with zeros
32+
$matrix = array_fill(0, $n, array_fill(0, $n, 0));
33+
34+
// Define boundaries
35+
$top = 0;
36+
$bottom = $n - 1;
37+
$left = 0;
38+
$right = $n - 1;
39+
40+
// Define direction (right, down, left, up)
41+
$direction = 0;
42+
43+
// Initialize counter
44+
$counter = 1;
45+
46+
// Generate the spiral matrix
47+
while ($top <= $bottom && $left <= $right) {
48+
if ($direction === 0) {
49+
// Move from left to right
50+
for ($i = $left; $i <= $right; ++$i) {
51+
$matrix[$top][$i] = $counter++;
52+
}
53+
++$top;
54+
} elseif ($direction === 1) {
55+
// Move from top to bottom
56+
for ($i = $top; $i <= $bottom; ++$i) {
57+
$matrix[$i][$right] = $counter++;
58+
}
59+
--$right;
60+
} elseif ($direction === 2) {
61+
// Move from right to left
62+
for ($i = $right; $i >= $left; --$i) {
63+
$matrix[$bottom][$i] = $counter++;
64+
}
65+
--$bottom;
66+
} elseif ($direction === 3) {
67+
// Move from bottom to top
68+
for ($i = $bottom; $i >= $top; --$i) {
69+
$matrix[$i][$left] = $counter++;
70+
}
71+
++$left;
72+
}
73+
74+
// Update direction
75+
$direction = ($direction + 1) % 4;
76+
}
77+
78+
return $matrix;
79+
}
80+
}
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: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* By adding type hints and enabling strict type checking, code can become
5+
* easier to read, self-documenting and reduce the number of potential bugs.
6+
* By default, type declarations are non-strict, which means they will attempt
7+
* to change the original type to match the type specified by the
8+
* type-declaration.
9+
*
10+
* In other words, if you pass a string to a function requiring a float,
11+
* it will attempt to convert the string value to a float.
12+
*
13+
* To enable strict mode, a single declare directive must be placed at the top
14+
* of the file.
15+
* This means that the strictness of typing is configured on a per-file basis.
16+
* This directive not only affects the type declarations of parameters, but also
17+
* a function's return type.
18+
*
19+
* For more info review the Concept on strict type checking in the PHP track
20+
* <link>.
21+
*
22+
* To disable strict typing, comment out the directive below.
23+
*/
24+
25+
declare(strict_types=1);
26+
27+
class SpiralMatrix
28+
{
29+
public function draw(int $n): array
30+
{
31+
throw new \BadMethodCallException(sprintf('Implement the %s method', __FUNCTION__));
32+
}
33+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<?php
2+
3+
/*
4+
* By adding type hints and enabling strict type checking, code can become
5+
* easier to read, self-documenting and reduce the number of potential bugs.
6+
* By default, type declarations are non-strict, which means they will attempt
7+
* to change the original type to match the type specified by the
8+
* type-declaration.
9+
*
10+
* In other words, if you pass a string to a function requiring a float,
11+
* it will attempt to convert the string value to a float.
12+
*
13+
* To enable strict mode, a single declare directive must be placed at the top
14+
* of the file.
15+
* This means that the strictness of typing is configured on a per-file basis.
16+
* This directive not only affects the type declarations of parameters, but also
17+
* a function's return type.
18+
*
19+
* For more info review the Concept on strict type checking in the PHP track
20+
* <link>.
21+
*
22+
* To disable strict typing, comment out the directive below.
23+
*/
24+
25+
declare(strict_types=1);
26+
27+
use PHPUnit\Framework\TestCase;
28+
29+
class SpiralMatrixTest extends TestCase
30+
{
31+
private SpiralMatrix $spiralMatrix;
32+
33+
public static function setUpBeforeClass(): void
34+
{
35+
require_once 'SpiralMatrix.php';
36+
}
37+
38+
public function setUp(): void
39+
{
40+
$this->spiralMatrix = new SpiralMatrix();
41+
}
42+
43+
/**
44+
* uuid: 8f584201-b446-4bc9-b132-811c8edd9040
45+
*/
46+
public function testEmptySpiral(): void
47+
{
48+
$expected = [];
49+
$actual = $this->spiralMatrix->draw(0);
50+
$this->assertEquals($expected, $actual);
51+
}
52+
53+
/**
54+
* uuid: e40ae5f3-e2c9-4639-8116-8a119d632ab2
55+
*/
56+
public function testTrivialSpiral(): void
57+
{
58+
$expected = [[1]];
59+
$actual = $this->spiralMatrix->draw(1);
60+
$this->assertEquals($expected, $actual);
61+
}
62+
63+
/**
64+
* uuid: cf05e42d-eb78-4098-a36e-cdaf0991bc48
65+
*/
66+
public function testSpiralOfSize2(): void
67+
{
68+
$expected = [
69+
[1, 2],
70+
[4, 3],
71+
];
72+
$actual = $this->spiralMatrix->draw(2);
73+
$this->assertEquals($expected, $actual);
74+
}
75+
76+
/**
77+
* uuid: 1c475667-c896-4c23-82e2-e033929de939
78+
*/
79+
public function testSpiralOfSize3(): void
80+
{
81+
$expected = [
82+
[1, 2, 3],
83+
[8, 9, 4],
84+
[7, 6, 5],
85+
];
86+
$actual = $this->spiralMatrix->draw(3);
87+
$this->assertEquals($expected, $actual);
88+
}
89+
90+
/**
91+
* uuid: 05ccbc48-d891-44f5-9137-f4ce462a759d
92+
*/
93+
public function testSpiralOfSize4(): void
94+
{
95+
$expected = [
96+
[1, 2, 3, 4],
97+
[12, 13, 14, 5],
98+
[11, 16, 15, 6],
99+
[10, 9, 8, 7],
100+
];
101+
$actual = $this->spiralMatrix->draw(4);
102+
$this->assertEquals($expected, $actual);
103+
}
104+
105+
/**
106+
* uuid: f4d2165b-1738-4e0c-bed0-c459045ae50d
107+
*/
108+
public function testSpiralOfSize5(): void
109+
{
110+
$expected = [
111+
[1, 2, 3, 4, 5],
112+
[16, 17, 18, 19, 6],
113+
[15, 24, 25, 20, 7],
114+
[14, 23, 22, 21, 8],
115+
[13, 12, 11, 10, 9],
116+
];
117+
$actual = $this->spiralMatrix->draw(5);
118+
$this->assertEquals($expected, $actual);
119+
}
120+
}

0 commit comments

Comments
 (0)