Skip to content

Instantly share code, notes, and snippets.

@f3ath
Last active August 26, 2016 21:20
Show Gist options
  • Save f3ath/10e8f0456fd72929cc6ace8084cccb2e to your computer and use it in GitHub Desktop.
Save f3ath/10e8f0456fd72929cc6ace8084cccb2e to your computer and use it in GitHub Desktop.
<?php
class Spiral
{
const RIGHT = 'RIGHT';
const DOWN = 'DOWN';
const LEFT = 'LEFT';
const UP = 'UP';
private $xMin = 0;
private $xMax = 0;
private $yMin = 0;
private $yMax = 0;
private $x = 0;
private $y = 0;
private $dirSequence = [self::RIGHT, self::DOWN, self::LEFT, self::UP];
private $dir = 0;
private $matrix;
public function __construct(array $matrix)
{
$this->matrix = $matrix;
$this->xMax = count($matrix[0]) - 1;
$this->yMax = count($matrix) - 1;
}
public function walk()
{
while ($this->xMin <= $this->xMax && $this->yMin <= $this->yMax)
{
yield $this->currentItem();
switch ($this->getDirection()) {
case self::RIGHT:
if ($this->x == $this->xMax) {
$this->yMin++;
$this->dir++;
$this->y++;
continue;
}
$this->x++;
break;
case self::LEFT:
if ($this->x == $this->xMin) {
$this->yMax--;
$this->dir++;
$this->y--;
continue;
}
$this->x--;
break;
case self::UP:
if ($this->y == $this->yMin) {
$this->xMin++;
$this->dir++;
$this->x++;
continue;
}
$this->y--;
break;
case self::DOWN:
if ($this->y == $this->yMax) {
$this->xMax--;
$this->dir++;
$this->x--;
continue;
}
$this->y++;
break;
}
}
return;
}
private function getDirection()
{
return $this->dirSequence[$this->dir % 4];
}
private function currentItem()
{
return $this->matrix[$this->y][$this->x];
}
}
$m = [
[1, 2, 3],
[8, 9, 4],
[7, 6, 5],
];
$s = new Spiral($m);
foreach ($s->walk() as $value) {
echo "$value\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment