ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

BenNG's solution

to Pascal's Triangle in the Elixir Track

Published at Jul 13 2018 · 0 comments
Instructions
Test suite
Solution

Note:

This solution was written on an old version of Exercism. The tests below might not correspond to the solution code, and the exercise may have changed since this code was written.

Compute Pascal's triangle up to a given number of rows.

In Pascal's Triangle each number is computed by adding the numbers to the right and left of the current position in the previous row.

``````    1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
# ... etc
``````

Running tests

Execute the tests with:

``````\$ elixir pascals_triangle_test.exs
``````

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
``````

For more detailed information about the Elixir track, please see the help page.

Source

Pascal's Triangle at Wolfram Math World http://mathworld.wolfram.com/PascalsTriangle.html

Submitting Incomplete Solutions

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

pascals_triangle_test.exs

``````if !System.get_env("EXERCISM_TEST_EXAMPLES") do
end

ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)

defmodule PascalsTriangleTest do
use ExUnit.Case

# @tag pending
test "one row" do
assert PascalsTriangle.rows(1) == [[1]]
end

@tag :pending
test "two rows" do
assert PascalsTriangle.rows(2) == [[1], [1, 1]]
end

@tag :pending
test "three rows" do
assert PascalsTriangle.rows(3) == [[1], [1, 1], [1, 2, 1]]
end

@tag :pending
test "fourth row" do
assert List.last(PascalsTriangle.rows(4)) == [1, 3, 3, 1]
end

@tag :pending
test "fifth row" do
assert List.last(PascalsTriangle.rows(5)) == [1, 4, 6, 4, 1]
end

@tag :pending
test "twentieth row" do
expected = [
1,
19,
171,
969,
3876,
11_628,
27_132,
50_388,
75_582,
92_378,
92_378,
75_582,
50_388,
27_132,
11_628,
3876,
969,
171,
19,
1
]

assert List.last(PascalsTriangle.rows(20)) == expected
end
end``````
``````defmodule PascalsTriangle do
@doc """
Calculates the rows of a pascal triangle
with the given height
"""
@spec rows(integer) :: [[integer]]

def rows(num) do
0..num - 1
|> Enum.reduce([], &([compute_row(&1, &2)|&2]))
|> Enum.reverse
end

defp compute_row(0,_), do: [1]
defp compute_row(1,_), do: [1,1]
defp compute_row(n, acc) do
previous = Enum.at(Enum.reverse(acc), n - 1)
Enum.map(0..n, &(compute_element(&1, previous)))
end

defp compute_element(0, previous), do: Enum.at(previous, 0)
# last element in a row
defp compute_element(n, previous) when length(previous) === n, do: Enum.at(previous, n - 1)
defp compute_element(n, previous) do
Enum.at(previous, n - 1) + Enum.at(previous, n)
end
end``````