# Spiral printing elements of a matrix

As I’m learning elixir, I wrote some code for printing elements in the spiral of a matrix(2D array). I was wondering if there is any room for improvements with regards to its performance or refactoring of any kind.

For example, I was wondering if there could be a neater way to get rid-off of the long arguments list for each print function.

``````defmodule MatrixSpiralPrint do
@moduledoc """
Solution to Spiral print of elements of a matrix(2D array)
"""

@doc """
prints elements of matrix(2D array) in a spiral
## Examples
iex> matrix = [[1,   2,  3, 4], [12, 13, 14, 5], [11, 16, 15, 6], [10,  9,  8, 7]]
iex> MatrixSpiralPrint.spriral_print_matrix(matrix)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
"""
def spriral_print_matrix(matrix) do
case List.improper?(matrix) do
true -> "Not a valid matrix"
false -> has_rows(matrix)
end
end

def has_rows(matrix) do
row = Enum.at(matrix, 0)
case List.improper?(row) do
true -> "Does not contain a row"
false -> spiral_print(matrix)
end
end

def spiral_print(matrix) do
row_min = 0
row_max = length(matrix) - 1
column_min = 0
column_max = length(Enum.at(matrix, 0, 0)) - 1

matrix
|> spiral_print(row_min, row_max, column_min, column_max)
end

def spiral_print(matrix, row_min, row_max, column_min, column_max) do
print_matrix(row_min < row_max and column_min < column_max, matrix, row_min, row_max, column_min, column_max)
end

def print_matrix(true, matrix, row_min, row_max, column_min, column_max) do
# IO.puts(:stdio, "row_min: #{row_min}, row_max: #{row_max} column_min: #{column_min}, column_max: #{column_max}")
print_left_to_right(column_min <= column_max, matrix, row_min, column_min, column_max)
row_min = row_min + 1

# IO.puts(:stdio, "row_min: #{row_min}, row_max: #{row_max} column_min: #{column_min}, column_max: #{column_max}")
print_top_to_bottom(row_min <= row_max, matrix, row_min, column_max, row_max)
column_max = column_max - 1

# IO.puts(:stdio, "row_min: #{row_min}, row_max: #{row_max} column_min: #{column_min}, column_max: #{column_max}")
print_right_to_left(column_min <= column_max, matrix, row_max, column_max, column_min)
row_max = row_max - 1

# IO.puts(:stdio, "row_min: #{row_min}, row_max: #{row_max} column_min: #{column_min}, column_max: #{column_max}")
print_bottom_to_top(row_min <= row_max, matrix, row_max, column_min, row_min)
column_min = column_min + 1

# IO.puts(:stdio, "==============================================================")
# IO.puts(:stdio, "row_min: #{row_min}, row_max: #{row_max} column_min: #{column_min}, column_max: #{column_max}")
print_matrix(row_min < row_max and column_min < column_max, matrix, row_min, row_max, column_min, column_max)
end

def print_matrix(false, _matrix, _row_min, _row_max, _column_min, _column_max) do
:ok # IO.puts(:stdio, "End of the matrix")
end

def print_left_to_right(true, matrix, row, column, limit) do
# IO.puts(:stdio, "row: #{row}, column: #{column}, limit: #{limit}")
IO.puts(:stdio, Enum.at(Enum.at(matrix, row), column))
print_left_to_right(column < limit, matrix, row, column+1, limit)
end

def print_left_to_right(false, _matrix, _row, _column, _limit) do
:ok # do nothing
end

def print_top_to_bottom(true, matrix, row, column, limit) do
# IO.puts(:stdio, "row: #{row}, column: #{column}, limit: #{limit}")
IO.puts(:stdio, Enum.at(Enum.at(matrix, row), column))
print_top_to_bottom(row < limit, matrix, row+1, column, limit)
end

def print_top_to_bottom(false, _matrix, _row, _column, _limit) do
:ok # do nothing
end

def print_right_to_left(true, matrix, row, column, limit) do
# IO.puts(:stdio, "row: #{row}, column: #{column}, limit: #{limit}")
IO.puts(:stdio, Enum.at(Enum.at(matrix, row), column))
print_right_to_left(limit < column, matrix, row, column-1, limit)
end

def print_right_to_left(false, _matrix, _row, _column, _limit) do
:ok # do nothing
end

def print_bottom_to_top(true, matrix, row, column, limit) do
# IO.puts(:stdio, "row: #{row}, column: #{column}, limit: #{limit}")
IO.puts(:stdio, Enum.at(Enum.at(matrix, row), column))
print_bottom_to_top(limit < row, matrix, row-1, column, limit)
end

def print_bottom_to_top(false, _matrix, _row, _column, _limit) do
:ok # do nothing
end
end
``````
1 Like