Current section

Files

Jump to
calc lib Stack.ex
Raw

lib/Stack.ex

defmodule Stack do
@moduledoc """
A Stack data structure.
"""
defstruct elements: []
@doc """
Return a new Stack with empty elements
## Examples
iex> Stack.new
%Stack{elements: []}
"""
def new, do: %Stack{}
@doc """
Push an element into given stack.\n
Given : a stack, and an element\n
RETURNS : push the element in the stack's elements
## Examples
iex> Stack.push(Stack.new, 2)
%Stack{elements: [2]}
"""
def push(stack, element) do
%Stack{stack | elements: [element | stack.elements]}
end
@doc """
Pop the top element of given stack.\n
GIVEN : a stack\n
RETURNS : the stack with the original top one removed
## Examples
iex> Stack.pop(%Stack{elements: [2, 1]})
%Stack{elements: [1]}
iex> Stack.pop(%Stack{elements: []})
** (RuntimeError) Stack is empty!
"""
def pop(%Stack{elements: []}), do: raise("Stack is empty!")
def pop(%Stack{elements: [_top | rest]}) do
%Stack{elements: rest}
end
@doc """
Pop the top k elements of given stack.\n
GIVEN : a stack and a number k\n
RETURNS : the stack with the original top k elements removed
## Examples
iex> Stack.popFirstK(%Stack{elements: [2, 1, 4, 7, 8]}, 3)
%Stack{elements: [7, 8]}
"""
def popFirstK(%Stack{elements: elements}, k) do
{_, tail} = Enum.split(elements, k)
%Stack{elements: tail}
end
@doc """
Get the top element of given stack.\n
GIVEN : a stack\n
RETURNS : the top element of the stack
## Examples
iex> Stack.peek(%Stack{elements: [2, 1, 4, 7, 8]})
2
"""
def peek(%Stack{elements: elements}) do
if length(elements) == 0 do
:nil
else
[top | _rest] = elements
top
end
end
@doc """
Get the index of given target in the stack.\n
GIVEN : a stack, and the target to find\n
RETURNS : the index of the first target(0 index-based)
## Examples
iex> Stack.find_index(%Stack{elements: [2, 1, 4, 7, 8]}, 4)
2
"""
def find_index(%Stack{elements: elements}, target) do
Enum.find_index(elements, fn x -> x == target end)
end
@doc """
Get the sum of the elements in stack from index a to index b.\n
GIVEN : a stack and a range start a, a range end b\n
RETURNS : the sum of elements between a and b
## Examples
iex> Stack.getSum(%Stack{elements: [2, 1, 4, 7, 8]}, 1,3)
12
"""
def getSum(%Stack{elements: elements}, a, b) do
Enum.slice(elements, a, b)
|> Enum.sum
end
@doc """
Judge if the stack is empty or not.\n
GIVEN : a stack\n
RETURNS : true iff the stack is empty
## Examples
iex> Stack.isEmpty?(%Stack{elements: [2, 1, 4, 7, 8]})
false
iex> Stack.isEmpty?(%Stack{elements: []})
true
"""
def isEmpty?(%Stack{elements: elements}) do
if length(elements) == 0 do
:true
else
:false
end
end
@doc """
Get the size of given stack.\n
GIVEN : a stack\n
RETURNS : the size of the stack
## Examples
iex> Stack.size(%Stack{elements: [2, 1, 4, 7, 8]})
5
"""
def size(%Stack{elements: elements}), do: length(elements)
end