diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2024-02-23 07:08:18 +0100 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2024-02-23 07:08:18 +0100 |
commit | 5a9cdd3cc89507d4d74f8bded56ce5e037b3b56e (patch) | |
tree | 982ca2e7f9ac4e8c350dfb5c4f60bcfdfff5afaf /learn-you-some-erlang/calc.erl | |
parent | 05ae56e5e89abf2993f84e6d52b250131f247c35 (diff) | |
download | erlang-workshop-5a9cdd3cc89507d4d74f8bded56ce5e037b3b56e.tar.gz erlang-workshop-5a9cdd3cc89507d4d74f8bded56ce5e037b3b56e.tar.bz2 erlang-workshop-5a9cdd3cc89507d4d74f8bded56ce5e037b3b56e.tar.xz erlang-workshop-5a9cdd3cc89507d4d74f8bded56ce5e037b3b56e.zip |
wip
Diffstat (limited to 'learn-you-some-erlang/calc.erl')
-rw-r--r-- | learn-you-some-erlang/calc.erl | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/learn-you-some-erlang/calc.erl b/learn-you-some-erlang/calc.erl new file mode 100644 index 0000000..c41ffb6 --- /dev/null +++ b/learn-you-some-erlang/calc.erl @@ -0,0 +1,51 @@ +-module(calc). +-export([rpn/1, rpn_test/0]). + +%% rpn(List()) -> Int() | Float() +%% parses an RPN string and outputs the results. +rpn(L) when is_list(L) -> + [Res] = lists:foldl(fun rpn/2, [], string:tokens(L, " ")), + Res. + +%% rpn(Str(), List()) -> List() +%% Returns the new stack after an operation has been done. +%% If no operator is found, we assume a number. +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("sum", Stack) -> [lists:sum(Stack)]; +rpn("prod", Stack) -> [lists:foldl(fun erlang:'*'/2, 1, Stack)]; +rpn(X, Stack) -> [read(X)|Stack]. + +%% read(String()) -> Int() | Float() +read(N) -> + case string:to_float(N) of + {error,no_float} -> list_to_integer(N); + {F,_} -> F + end. + +%% returns 'ok' iff successful +rpn_test() -> + 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"), + 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"), + ok. + |