61 lines
1.7 KiB
Elixir
61 lines
1.7 KiB
Elixir
defmodule Matrix do
|
|
defstruct ~w(rows columns)a
|
|
|
|
defp at(list, index), do: Enum.at(list, index - 1)
|
|
|
|
defp transpose(list), do: Enum.zip_with(list, &Function.identity/1)
|
|
|
|
defp parse_columns(string), do: String.split(string, "\n")
|
|
|
|
defp parse_row(row) do
|
|
row
|
|
|> String.split(" ")
|
|
|> Enum.map(&String.to_integer/1)
|
|
end
|
|
|
|
@doc """
|
|
Convert an `input` string, with rows separated by newlines and values
|
|
separated by single spaces, into a `Matrix` struct.
|
|
"""
|
|
@spec from_string(input :: String.t()) :: %Matrix{}
|
|
def from_string(input) do
|
|
matrix =
|
|
input
|
|
|> parse_columns()
|
|
|> Enum.map(&parse_row/1)
|
|
|
|
struct(__MODULE__, rows: matrix, columns: transpose(matrix))
|
|
end
|
|
|
|
@doc """
|
|
Write the `matrix` out as a string, with rows separated by newlines and
|
|
values separated by single spaces.
|
|
"""
|
|
@spec to_string(matrix :: %Matrix{}) :: String.t()
|
|
def to_string(matrix), do: Enum.map_join(matrix.rows, "\n", &Enum.join(&1, " "))
|
|
|
|
@doc """
|
|
Given a `matrix`, return its rows as a list of lists of integers.
|
|
"""
|
|
@spec rows(matrix :: %Matrix{}) :: list(list(integer))
|
|
def rows(matrix), do: matrix.rows
|
|
|
|
@doc """
|
|
Given a `matrix` and `index`, return the row at `index`.
|
|
"""
|
|
@spec row(matrix :: %Matrix{}, index :: integer) :: list(integer)
|
|
def row(matrix, index), do: at(matrix.rows, index)
|
|
|
|
@doc """
|
|
Given a `matrix`, return its columns as a list of lists of integers.
|
|
"""
|
|
@spec columns(matrix :: %Matrix{}) :: list(list(integer))
|
|
def columns(matrix), do: matrix.columns
|
|
|
|
@doc """
|
|
Given a `matrix` and `index`, return the column at `index`.
|
|
"""
|
|
@spec column(matrix :: %Matrix{}, index :: integer) :: list(integer)
|
|
def column(matrix, index), do: at(matrix.columns, index)
|
|
end
|