Skip to content

Commit

Permalink
Add Spiral Matrix Exercise (exercism#625)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasnorre authored Feb 21, 2024
1 parent 76b48b6 commit 2b9223f
Show file tree
Hide file tree
Showing 7 changed files with 312 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -1156,6 +1156,14 @@
"prerequisites": [],
"difficulty": 6
},
{
"slug": "spiral-matrix",
"name": "Spiral Matrix",
"uuid": "a8d52588-a7af-4543-867b-17f9728df77e",
"practices": [],
"prerequisites": [],
"difficulty": 4
},
{
"slug": "zebra-puzzle",
"name": "Zebra Puzzle",
Expand Down
24 changes: 24 additions & 0 deletions exercises/practice/spiral-matrix/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Instructions

Given the size, return a square matrix of numbers in spiral order.

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:

## Examples

### Spiral matrix of size 3

```text
1 2 3
8 9 4
7 6 5
```

### Spiral matrix of size 4

```text
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
```
19 changes: 19 additions & 0 deletions exercises/practice/spiral-matrix/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"tomasnorre"
],
"files": {
"solution": [
"SpiralMatrix.php"
],
"test": [
"SpiralMatrixTest.php"
],
"example": [
".meta/example.php"
]
},
"blurb": "Given the size, return a square matrix of numbers in spiral order.",
"source": "Reddit r/dailyprogrammer challenge #320 [Easy] Spiral Ascension.",
"source_url": "https://web.archive.org/web/20230607064729/https://old.reddit.com/r/dailyprogrammer/comments/6i60lr/20170619_challenge_320_easy_spiral_ascension/"
}
80 changes: 80 additions & 0 deletions exercises/practice/spiral-matrix/.meta/example.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

class SpiralMatrix
{
public function draw(int $n): array
{
// Initialize the matrix with zeros
$matrix = array_fill(0, $n, array_fill(0, $n, 0));

// Define boundaries
$top = 0;
$bottom = $n - 1;
$left = 0;
$right = $n - 1;

// Define direction (right, down, left, up)
$direction = 0;

// Initialize counter
$counter = 1;

// Generate the spiral matrix
while ($top <= $bottom && $left <= $right) {
if ($direction === 0) {
// Move from left to right
for ($i = $left; $i <= $right; ++$i) {
$matrix[$top][$i] = $counter++;
}
++$top;
} elseif ($direction === 1) {
// Move from top to bottom
for ($i = $top; $i <= $bottom; ++$i) {
$matrix[$i][$right] = $counter++;
}
--$right;
} elseif ($direction === 2) {
// Move from right to left
for ($i = $right; $i >= $left; --$i) {
$matrix[$bottom][$i] = $counter++;
}
--$bottom;
} elseif ($direction === 3) {
// Move from bottom to top
for ($i = $bottom; $i >= $top; --$i) {
$matrix[$i][$left] = $counter++;
}
++$left;
}

// Update direction
$direction = ($direction + 1) % 4;
}

return $matrix;
}
}
28 changes: 28 additions & 0 deletions exercises/practice/spiral-matrix/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[8f584201-b446-4bc9-b132-811c8edd9040]
description = "empty spiral"

[e40ae5f3-e2c9-4639-8116-8a119d632ab2]
description = "trivial spiral"

[cf05e42d-eb78-4098-a36e-cdaf0991bc48]
description = "spiral of size 2"

[1c475667-c896-4c23-82e2-e033929de939]
description = "spiral of size 3"

[05ccbc48-d891-44f5-9137-f4ce462a759d]
description = "spiral of size 4"

[f4d2165b-1738-4e0c-bed0-c459045ae50d]
description = "spiral of size 5"
33 changes: 33 additions & 0 deletions exercises/practice/spiral-matrix/SpiralMatrix.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

class SpiralMatrix
{
public function draw(int $n): array
{
throw new \BadMethodCallException(sprintf('Implement the %s method', __FUNCTION__));
}
}
120 changes: 120 additions & 0 deletions exercises/practice/spiral-matrix/SpiralMatrixTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

use PHPUnit\Framework\TestCase;

class SpiralMatrixTest extends TestCase
{
private SpiralMatrix $spiralMatrix;

public static function setUpBeforeClass(): void
{
require_once 'SpiralMatrix.php';
}

public function setUp(): void
{
$this->spiralMatrix = new SpiralMatrix();
}

/**
* uuid: 8f584201-b446-4bc9-b132-811c8edd9040
*/
public function testEmptySpiral(): void
{
$expected = [];
$actual = $this->spiralMatrix->draw(0);
$this->assertEquals($expected, $actual);
}

/**
* uuid: e40ae5f3-e2c9-4639-8116-8a119d632ab2
*/
public function testTrivialSpiral(): void
{
$expected = [[1]];
$actual = $this->spiralMatrix->draw(1);
$this->assertEquals($expected, $actual);
}

/**
* uuid: cf05e42d-eb78-4098-a36e-cdaf0991bc48
*/
public function testSpiralOfSize2(): void
{
$expected = [
[1, 2],
[4, 3],
];
$actual = $this->spiralMatrix->draw(2);
$this->assertEquals($expected, $actual);
}

/**
* uuid: 1c475667-c896-4c23-82e2-e033929de939
*/
public function testSpiralOfSize3(): void
{
$expected = [
[1, 2, 3],
[8, 9, 4],
[7, 6, 5],
];
$actual = $this->spiralMatrix->draw(3);
$this->assertEquals($expected, $actual);
}

/**
* uuid: 05ccbc48-d891-44f5-9137-f4ce462a759d
*/
public function testSpiralOfSize4(): void
{
$expected = [
[1, 2, 3, 4],
[12, 13, 14, 5],
[11, 16, 15, 6],
[10, 9, 8, 7],
];
$actual = $this->spiralMatrix->draw(4);
$this->assertEquals($expected, $actual);
}

/**
* uuid: f4d2165b-1738-4e0c-bed0-c459045ae50d
*/
public function testSpiralOfSize5(): void
{
$expected = [
[1, 2, 3, 4, 5],
[16, 17, 18, 19, 6],
[15, 24, 25, 20, 7],
[14, 23, 22, 21, 8],
[13, 12, 11, 10, 9],
];
$actual = $this->spiralMatrix->draw(5);
$this->assertEquals($expected, $actual);
}
}

0 comments on commit 2b9223f

Please sign in to comment.