%% 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
polyepr(List) when is_list(List), length(List) >= 2 ->
P = gen_epr([], List),
case R=join_epr(P) of
"" ->
"0";
->
R
end;
polyepr() ->
{error, "Need at least 2 coefficients"}.
%% generate the polyonmial expression
genepr(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
checkneg([]) ->
"";
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).