Create a gist now

Instantly share code, notes, and snippets.

@Jeffrey04 /spiral.php Secret
Last active Aug 29, 2015

What would you like to do?
#!/usr/bin/env php
<?php
function node_is_valid($count_row, $count_column, Array $node_path, $node_next) {
return FALSE === (node_is_used($node_next, $node_path)
OR node_exceeds_range($node_next, $count_row, $count_column));
}
function node_is_used($node_next, $node_path) {
return in_array($node_next, $node_path);
}
function node_exceeds_range($node_next, $count_row, $count_column) {
return $node_next[0] >= $count_row
OR $node_next[0] < 0
OR $node_next[1] >= $count_column
OR $node_next[1] < 0;
}
function node_candidates(Array $node_path) {
$node_last = end(array_values($node_path));
$node_vector = node_get_vector($node_path, $node_last);
return array(
node_go_to($node_last, $node_vector),
node_go_to($node_last, node_rotate_vector($node_vector)));
}
function node_get_vector($node_path, $node_last) {
$node_count = count($node_path);
return $node_count > 1 ?
array($node_last[0] - $node_path[$node_count - 2][0],
$node_last[1] - $node_path[$node_count - 2][1])
: array(0, 1);
}
function node_rotate_vector($node_vector) {
// maths theorem by @angch
// http://en.wikipedia.org/wiki/Rotation_matrix#Common_rotations
return array($node_vector[1], -1 * $node_vector[0]);
}
function node_go_to($node_last, $node_vector) {
return array($node_last[0] + $node_vector[0],
$node_last[1] + $node_vector[1]);
}
function node_get_next($row, $column, Array $node_path) {
return array_shift(array_filter(
node_candidates($node_path),
function($node_next) use($row, $column, $node_path) {
return node_is_valid($row, $column, $node_path, $node_next);
}));
}
function node_construct_path($row, $column, $node_path=array(array(0, 0))) {
return count($node_path) == ($row * $column) ?
$node_path
: node_construct_path(
$row,
$column,
array_merge(
$node_path,
array(node_get_next($row, $column, $node_path))));
}
function print_result($row_count, $column_count, Array $result) {
$format = sprintf('%%%dd ', strlen($row_count * $column_count));
$column_range = range(0, $column_count - 1);
array_walk(range(0, $row_count - 1), function($row) use($column_range, $format, $result) {
array_walk($column_range, function($column) use($row, $format, $result) {
printf($format, 1 + array_search(array($row, $column), $result));
});
echo PHP_EOL;
});
}
function spiral($row, $column) {
return print_result($row, $column, node_construct_path($row, $column));
}
spiral(5,5);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment