Created
October 1, 2019 19:38
-
-
Save Jwsonic/15d2a8ddc9ebb39f703ac979de325b44 to your computer and use it in GitHub Desktop.
Revisions
-
Jwsonic created this gist
Oct 1, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,80 @@ defmodule Spiral do def order(matrix) do bounds = %{ xmin: 0, xmax: matrix |> hd() |> length(), ymin: 0, ymax: length(matrix) } matrix |> next({0, 0}, {1, 0}, bounds, []) |> Enum.reverse() end # Guard clause that checks if we've reached the center of the matrix defguardp is_center?(x, y, matrix) when matrix |> hd() |> length() |> div(2) |> floor() == x and matrix |> length() |> div(2) |> floor() == y # We've reached the center, add it to the result and we're done defp next(matrix, {x, y}, _direction, _bounds, result) when is_center?(x, y, matrix) do [get(matrix, x, y) | result] end # When we get to the right edge, start moving downwards defp next(matrix, {x, y}, _direction, %{xmax: xmax, ymin: ymin} = bounds, result) when x >= xmax do next(matrix, {x - 1, y + 1}, {0, 1}, %{bounds | ymin: ymin + 1}, result) end # When we get to the bottom edge, start moving left defp next(matrix, {x, y}, _direction, %{ymax: ymax, xmax: xmax} = bounds, result) when y >= ymax do next(matrix, {x - 1, y - 1}, {-1, 0}, %{bounds | xmax: xmax - 1}, result) end # When we get to the left edge, start moving up defp next(matrix, {x, y}, _direction, %{xmin: xmin, ymax: ymax} = bounds, result) when x < xmin do next(matrix, {x + 1, y - 1}, {0, -1}, %{bounds | ymax: ymax - 1}, result) end # When we get to the top edge, start moving right defp next(matrix, {x, y}, _direction, %{ymin: ymin, xmin: xmin} = bounds, result) when y < ymin do next(matrix, {x + 1, y + 1}, {1, 0}, %{bounds | xmin: xmin + 1}, result) end # Process other cells normally defp next(matrix, {x, y}, {dx, dy} = direction, bounds, result) do next(matrix, {x + dx, y + dy}, direction, bounds, [get(matrix, x, y) | result]) end # Returns the matrix element at (x, y) defp get(matrix, x, y), do: matrix |> Enum.at(y) |> Enum.at(x) end l = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] IO.puts("Input: [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]") IO.puts("Output: #{l |> Spiral.order() |> inspect()}") l = [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12] ] IO.puts("Input: [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12] ]") IO.puts("Output: #{l |> Spiral.order() |> inspect()}")