 paulfioravanti's solution

to Matrix in the Elixir Track

Published at Aug 21 2019 · 0 comments
Instructions
Test suite
Solution

Given a string representing a matrix of numbers, return the rows and columns of that matrix.

So given a string with embedded newlines like:

9 8 7
5 3 2
6 6 7

representing this matrix:

0  1  2
|---------
0 | 9  8  7
1 | 5  3  2
2 | 6  6  7

your code should be able to spit out:

• A list of the rows, reading each row left-to-right while moving top-to-bottom across the rows,
• A list of the columns, reading each column top-to-bottom while moving from left-to-right.

The rows for our example matrix:

• 9, 8, 7
• 5, 3, 2
• 6, 6, 7

And its columns:

• 9, 5, 6
• 8, 3, 6
• 7, 2, 7

Running tests

Execute the tests with:

\$ mix test

Pending tests

In the test suites, all but the first test have been skipped.

Once you get a test passing, you can unskip the next one by commenting out the relevant @tag :pending with a # symbol.

For example:

# @tag :pending
test "shouting" do
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end

Or, you can enable all the tests by commenting out the ExUnit.configure line in the test suite.

# ExUnit.configure exclude: :pending, trace: true

If you're stuck on something, it may help to look at some of the available resources out there where answers might be found.

Source

Warmup to the saddle-points warmup. http://jumpstartlab.com

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

matrix_test.exs

defmodule MatrixTest do
use ExUnit.Case

@input "1 2 3\n4 5 6\n7 8 9"

# @tag :pending
test "reading from and writing to string" do
matrix = Matrix.from_string(@input)
assert Matrix.to_string(matrix) == @input
end

@tag :pending
test "rows should return nested lists regardless of internal structure" do
matrix = Matrix.from_string(@input)

assert Matrix.rows(matrix) == [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
end

@tag :pending
test "row should return list at index" do
matrix = Matrix.from_string(@input)

assert Matrix.row(matrix, 0) == [1, 2, 3]
assert Matrix.row(matrix, 1) == [4, 5, 6]
assert Matrix.row(matrix, 2) == [7, 8, 9]
end

@tag :pending
test "columns should return nested lists regardless of internal structure" do
matrix = Matrix.from_string(@input)

assert Matrix.columns(matrix) == [
[1, 4, 7],
[2, 5, 8],
[3, 6, 9]
]
end

@tag :pending
test "column should return list at index" do
matrix = Matrix.from_string(@input)

assert Matrix.column(matrix, 0) == [1, 4, 7]
assert Matrix.column(matrix, 1) == [2, 5, 8]
assert Matrix.column(matrix, 2) == [3, 6, 9]
end
end

test_helper.exs

ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)
defmodule Matrix do
defstruct matrix: nil

@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
|> String.split("\n")
|> Enum.map(&split_row/1)

%Matrix{matrix: 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
matrix.matrix
|> Enum.map_join("\n", &join_row/1)
end

@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.matrix
end

@doc """
Given a `matrix` and `index`, return the row at `index`.
"""
@spec row(matrix :: %Matrix{}, index :: integer) :: list(integer)
def row(matrix, index) do
matrix.matrix
|> Enum.at(index)
end

@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.matrix
|> List.zip()
|> Enum.map(&Tuple.to_list/1)
end

@doc """
Given a `matrix` and `index`, return the column at `index`.
"""
@spec column(matrix :: %Matrix{}, index :: integer) :: list(integer)
def column(matrix, index) do
matrix
|> columns()
|> Enum.at(index)
end

defp split_row(row) do
row
|> String.split(" ")
|> Enum.map(&String.to_integer/1)
end

defp join_row(row) do
row
|> Enum.map_join(" ", &Integer.to_string/1)
end
end