From 2b9223fa6e11b6b15d54168786fe836f67538382 Mon Sep 17 00:00:00 2001 From: Tomas Norre Mikkelsen Date: Wed, 21 Feb 2024 23:00:48 +0100 Subject: [PATCH] Add Spiral Matrix Exercise (#625) --- config.json | 8 ++ .../spiral-matrix/.docs/instructions.md | 24 ++++ .../practice/spiral-matrix/.meta/config.json | 19 +++ .../practice/spiral-matrix/.meta/example.php | 80 ++++++++++++ .../practice/spiral-matrix/.meta/tests.toml | 28 ++++ .../practice/spiral-matrix/SpiralMatrix.php | 33 +++++ .../spiral-matrix/SpiralMatrixTest.php | 120 ++++++++++++++++++ 7 files changed, 312 insertions(+) create mode 100644 exercises/practice/spiral-matrix/.docs/instructions.md create mode 100644 exercises/practice/spiral-matrix/.meta/config.json create mode 100644 exercises/practice/spiral-matrix/.meta/example.php create mode 100644 exercises/practice/spiral-matrix/.meta/tests.toml create mode 100644 exercises/practice/spiral-matrix/SpiralMatrix.php create mode 100644 exercises/practice/spiral-matrix/SpiralMatrixTest.php diff --git a/config.json b/config.json index 4fb6d54d..178fd1b8 100644 --- a/config.json +++ b/config.json @@ -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", diff --git a/exercises/practice/spiral-matrix/.docs/instructions.md b/exercises/practice/spiral-matrix/.docs/instructions.md new file mode 100644 index 00000000..ba99e12c --- /dev/null +++ b/exercises/practice/spiral-matrix/.docs/instructions.md @@ -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 +``` diff --git a/exercises/practice/spiral-matrix/.meta/config.json b/exercises/practice/spiral-matrix/.meta/config.json new file mode 100644 index 00000000..4d48ccaa --- /dev/null +++ b/exercises/practice/spiral-matrix/.meta/config.json @@ -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/" +} diff --git a/exercises/practice/spiral-matrix/.meta/example.php b/exercises/practice/spiral-matrix/.meta/example.php new file mode 100644 index 00000000..dd025d05 --- /dev/null +++ b/exercises/practice/spiral-matrix/.meta/example.php @@ -0,0 +1,80 @@ +. + * + * 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; + } +} diff --git a/exercises/practice/spiral-matrix/.meta/tests.toml b/exercises/practice/spiral-matrix/.meta/tests.toml new file mode 100644 index 00000000..9ac5baca --- /dev/null +++ b/exercises/practice/spiral-matrix/.meta/tests.toml @@ -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" diff --git a/exercises/practice/spiral-matrix/SpiralMatrix.php b/exercises/practice/spiral-matrix/SpiralMatrix.php new file mode 100644 index 00000000..e78c4706 --- /dev/null +++ b/exercises/practice/spiral-matrix/SpiralMatrix.php @@ -0,0 +1,33 @@ +. + * + * 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__)); + } +} diff --git a/exercises/practice/spiral-matrix/SpiralMatrixTest.php b/exercises/practice/spiral-matrix/SpiralMatrixTest.php new file mode 100644 index 00000000..85b1c605 --- /dev/null +++ b/exercises/practice/spiral-matrix/SpiralMatrixTest.php @@ -0,0 +1,120 @@ +. + * + * 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); + } +}