Current section
Files
Jump to
Current section
Files
lib/pascal.ex
defmodule Pascal do
@moduledoc """
Provides a set of functions that calculate Pascal's triangles
"""
@typedoc """
Line of Pascal's triangle
"""
@type line :: nonempty_list(pos_integer)
@typedoc """
Pascal's triangle
"""
@type triangle :: nonempty_list(line)
@doc """
Generate Pascal's `t:triangle/0` of given `height`.
Returns `t:triangle/0`.
## Examples
iex> Pascal.triangle(1)
[[1]]
iex> Pascal.triangle(2)
[[1], [1, 1]]
iex> Pascal.triangle(3)
[[1], [1, 1], [1, 2, 1]]
"""
@spec triangle(pos_integer) :: triangle
def triangle(height) do
Enum.reverse triangle(height, [[1]])
end
@doc """
Generate next `t:line/0` of Pascal's `t:triangle/0` for given previous `t:line/0`.
Returns `t:line/0`.
## Examples
iex> Pascal.next_triangle_line([1])
[1, 1]
iex> Pascal.next_triangle_line([1, 1])
[1, 2, 1]
iex> Pascal.next_triangle_line([1, 2, 1])
[1, 3, 3, 1]
"""
@spec next_triangle_line(line) :: line
def next_triangle_line(line) do
Enum.zip([0 | line], line ++ [0])
|> Enum.map(fn {a, b} -> a + b end)
end
@spec triangle(pos_integer, triangle) :: triangle
defp triangle(1, triangle), do: triangle
defp triangle(n, [line | _rest] = triangle) do
next_line = next_triangle_line(line)
triangle(n - 1, [next_line | triangle])
end
end