A few weeks ago I wanted to start learning Erlang. A co-worker pointed out the Ruby Programming Challenge for Newbies that they were completing in Ruby. I decided to try the RPCFN #4, but write it in Erlang. This probably isn’t the most concise or best implementation, but it was a good exercise to encourage me to look at Erlang.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | %% This was inspired from the ruby programming challenge for newbies.
%% http://rubylearning.com/blog/2009/11/26/rpcfn-rubyfun-4/
-module (polynomials).
%% -compile(export_all).
-export([poly_epr/1]).
-import(string, [concat/2]).
-import(lists, [append/1]).
%% include the test module
-include_lib("eunit/include/eunit.hrl").
%% Create a polynomial expression from an array of numbers
poly_epr(List) when is_list(List), length(List) >= 2 ->
P = gen_epr([], List),
case R=join_epr(P) of
"" ->
"0";
_ ->
R
end;
poly_epr(_) ->
{error, "Need at least 2 coefficients"}.
%% generate the polyonmial expression
gen_epr(Poly, []) ->
case Poly of
[] ->
"0";
_ ->
Poly
end;
gen_epr(Poly, [H|T]) ->
Poly ++ gen_epr([term(H, length(T))], T).
%% join the expressions term together
join_epr([]) ->
"0";
join_epr([H|T]) ->
H ++ append([check_neg(X) || X <- T]).
%% add appropreiate sign in front of expression term
check_neg([]) ->
"";
check_neg(Val="-" ++ _T) ->
Val;
check_neg(Val) ->
concat("+",Val).
%% create an expression term
term(1, Expo) ->
expo(Expo);
term(-1, Expo) ->
"-" ++ expo(Expo);
term(0, _Expo) ->
"";
term(Val, 0) ->
integer_to_list(Val);
term(Val, Expo) when is_number(Val), is_number(Expo) ->
concat(integer_to_list(Val), expo(Expo));
term(_Val, _Expo) ->
"".
%% create the exponent expression
expo(1) ->
"x";
expo(E) ->
concat("x^", integer_to_list(E)).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% TESTS
%% term tests
term1_test() ->
"x^2" = term(1,2).
term_negative_value_test() ->
"-x^2" = term(-1,2).
term0_test() ->
"" = term(0,5).
term_zero_exponent_test() ->
"5" = term(5,0).
term_bad_values_test() ->
"" = term("str","more").
%% poly tests from the rpcfn
poly_epr1_test() ->
?assert("3x^3+4x^2-3" =:= poly_epr([3,4,0,-3])).
poly_first_negative_test() ->
?assert("-3x^4-4x^3+x^2+6" =:= poly_epr([-3,-4,1,0,6])).
poly_simple_test() ->
?assert("x^2+2" =:= poly_epr([1,0,2])).
poly_first_minus_one_test() ->
?assert("-x^3-2x^2+3x" =:= poly_epr([-1,-2,3,0])).
poly_all_zera_test() ->
?assert("0" =:= poly_epr([0,0,0])).
poly_test_error_test() ->
{error,Msg} = poly_epr([1]),
?assert("Need at least 2 coefficients" =:= Msg).
|
You need to have eunit setup in your code path. Then you can start the Erlang shell and run the tests. Really, they pass!
1 2 3 4 5 6 7 8 9 10 | $ erl
Erlang R13B03 (erts-5.7.4) [source] [smp:2:2] [rq:2] [async-threads:0] [kernel-poll:false]
Eshell V5.7.4 (abort with ^G)
1> c(polynomials).
{ok,polynomials}
2> polynomials:test().
All 11 tests passed.
ok
3>
|