Skip to content

Instantly share code, notes, and snippets.

@oskwazir
Created May 10, 2016 21:58
Show Gist options
  • Select an option

  • Save oskwazir/918ddc8064ae2b7b4bcbf1c626043dba to your computer and use it in GitHub Desktop.

Select an option

Save oskwazir/918ddc8064ae2b7b4bcbf1c626043dba to your computer and use it in GitHub Desktop.
Reverse Polish notation calculator
% -*- coding: utf8 -*-
% From LearnYouSomeErlang Functionally Solving Problems
-module(main).
-export([main/0]).
main() ->
5 = rpn("2 3 +"),
87 = rpn("90 3 -"),
-4 = rpn("10 4 3 + 2 * -"),
-2.0 = rpn("10 4 3 + 2 * - 2 /"),
ok = try
rpn("90 34 12 33 55 66 + * - +")
catch
error:{badmatch,[_|_]} -> ok
end,
4037 = rpn("90 34 12 33 55 66 + * - + -"),
8.0 = rpn("2 3 ^"),
true = math:sqrt(2) == rpn("2 0.5 ^"),
true = math:log(2.7) == rpn("2.7 ln"),
true = math:log10(2.7) == rpn("2.7 log10").
%% TODO--
%% 50 = rpn("10 10 10 20 sum"),
%% 10.0 = rpn("10 10 10 20 sum 5 /"),
%% 1000.0 = rpn("10 10 20 0.5 prod").
rpn(L) when is_list(L) ->
[Res] = lists:foldl(fun rpn/2, [], string:tokens(L," ")),
Res.
rpn("+", [N1, N2|S]) -> [N2+N1|S];
rpn("-", [N1, N2|S]) -> [N2-N1|S];
rpn("*", [N1, N2|S]) -> [N2*N1|S];
rpn("/", [N1, N2|S]) -> [N2/N1|S];
rpn("^", [N1, N2|S]) -> [math:pow(N2,N1)|S];
rpn("ln", [N|S]) -> [math:log(N)|S];
rpn("log10", [N|S]) -> [math:log10(N)|S];
rpn(X,Stack) -> [read(X) | Stack].
read(N) ->
case string:to_float(N) of
{error,no_float} -> list_to_integer(N);
{F,_} -> F
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment