Created
September 27, 2016 14:25
-
-
Save gvaughn/0d2c44740f89cb0de192bda76ab21452 to your computer and use it in GitHub Desktop.
homework assignment to implement a stack and evaluate a postfix expression
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Stack do | |
@moduledoc """ | |
Implement a stack using a linked list to back it. The stack should support | |
peek, push, pop, count | |
do it in whatever language you want | |
""" | |
defstruct llist: [] | |
def peek(%Stack{llist: [head | _]}), do: head | |
def peek(%Stack{}), do: nil | |
def push(%Stack{llist: list}, new_item) do | |
%Stack{llist: [new_item | list]} | |
end | |
def push(initial_item), do: %Stack{llist: [initial_item]} | |
def pop(%Stack{llist: [head | tail]}) do | |
{head, %Stack{llist: tail}} | |
end | |
def pop(%Stack{} = stack), do: {nil, stack} | |
def count(%Stack{llist: list}) do | |
Enum.reduce(list, 0, fn(_e, sum) -> sum + 1 end) | |
end | |
def is_empty?(%Stack{llist: []}), do: true | |
def is_empty?(%Stack{}), do: false | |
def eval(str) do | |
String.split(str) |> Enum.reduce(%Stack{}, &eval/2) |> peek | |
end | |
defp eval("+", stack), do: operate(&Kernel.+/2, stack) | |
defp eval("x", stack), do: operate(&Kernel.*/2, stack) | |
defp eval("%", stack), do: operate(&Kernel.rem/2, stack) | |
defp eval(token, stack), do: push(stack, String.to_integer(token)) | |
defp operate(f, stack) do | |
{a, stack} = pop(stack) | |
{b, stack} = pop(stack) | |
push(stack, f.(b,a)) | |
end | |
end | |
ExUnit.start | |
defmodule StackTest do | |
use ExUnit.Case | |
import Stack | |
setup do: {:ok, stack: push("hello") |> push("world")} | |
test "push and pop", %{stack: stack} do | |
assert {"world", stack} = pop(stack) | |
assert {"hello", stack} = pop(stack) | |
assert {nil , _stack} = pop(stack) | |
end | |
test "peek", %{stack: stack} do | |
assert "world" = peek(stack) | |
assert "world" = peek(stack) | |
end | |
test "count", %{stack: stack} do | |
assert 2 = count(stack) | |
end | |
test "is_empty?", %{stack: stack} do | |
assert false == is_empty?(stack) | |
assert true == is_empty?(%Stack{}) | |
end | |
test "eval" do | |
"500 122 29 + 14 x + 30 %" |> eval |> IO.puts | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment