用Erlang写了个优惠计算器« Tony Huang & Tech

今天在为公司买东西的时候,发现了qq的一个网站:

后来又发现了新蛋网的qq返利的比率很有意思,最近又在学习erlang,所以就写个程序,看看对于这种算法类的程序,erlang写起来是否麻烦,一下是代码:

-module(bne).
-export([solve/1, print_solution/1]).

% Calculate the cashback of a bill
get_cashback(N) when N =< 100 -> 0.76;
get_cashback(N) when N =< 300 -> 2.29;
get_cashback(N) when N =< 500 -> 5.35;
get_cashback(N) when N =< 800 -> 7.65;
get_cashback(N) when N =< 1000 -> 11.47;
get_cashback(N) when N =< 2000 -> 13.0;
get_cashback(N) when N =< 3000 -> 16.83;
get_cashback(N) when N =< 5000 -> 20.65;
get_cashback(N) when N =< 8000 -> 24.48;
get_cashback(N) when N =< 10000 -> 34.42;
get_cashback(_N) -> 42.07.

% Calculate the real cost of a bill
get_bill_cost({Total, _}) when Total < 99 -> Total + 10.0 - get_cashback(Total);
get_bill_cost({Total, _}) -> Total - get_cashback(Total).

% Calculate the total cost of a solution
get_solution_cost(Solution) -> lists:foldl(fun(X, Sum) -> get_bill_cost(X) + Sum end, 0, Solution).

% make combinations with a series of combination and a new element
reduce_comb(HeadList, [], Element) -> [HeadList ++ [[Element]]];
reduce_comb(HeadList, [Head | Rest], Element) -> [HeadList ++ [[Element | Head]] ++ Rest | reduce_comb(HeadList ++ [Head], Rest, Element)].

% call Function on each combination of the 3rd argument, and the Default, the return value will overwrite the Default value
combination(_Function, Default, []) -> Default;
combination(Function, Default, [Head]) -> Function([[Head]], Default);
combination(Function, Default, [Head | List]) ->
	combination(fun(Combination, OldSolution) ->
		ReducedCombination = reduce_comb([], Combination, Head),
		lists:foldl(Function, OldSolution, ReducedCombination)
	end, Default, List).

% choose a solution from a set of solution
choose_solution(Solutions) -> lists:foldl(
	fun(NewSolution, ExistSolution) ->
		case NewSolution of
			{Cost, Solution} ->
				case ExistSolution of
					no_solution -> NewSolution;
					{OldCost, _} when OldCost > Cost -> {Cost, Solution};
					_ -> ExistSolution
				end;
			no_solution -> ExistSolution
		end
	end, no_solution, Solutions).

% solve problem
solve([]) -> {ok, 0, []};
solve([Price]) -> {ok, get_bill_cost({Price, [Price]}), [[Price]]};
solve(PriceList) -> combination(
	fun(Combination, Origional) ->
		Solution = lists:map(fun(Bill) -> {lists:sum(Bill), Bill} end, Combination),
		choose_solution([{get_solution_cost(Solution), Solution} , Origional])
	end, no_solution, PriceList).

% print a bill
print_bill({Total, Items}) ->
	io:fwrite("    Bill Total: ~p, Cashback: ~p, Real: ~p~n", [Total, get_cashback(Total), get_bill_cost({Total, Items})]),
	lists:foreach(fun(Item) -> io:fwrite("        ~p~n", [Item]) end, Items),
	io:fwrite("~n").

% print the solution
print_solution({Cost, Solution}) ->
	io:fwrite("Solution Total: ~p, Bill Count: ~p~n", [Cost, length(Solution)]),
	lists:foreach(fun(Bill) -> print_bill(Bill) end, Solution),
	io:fwrite("~n").

用法:

bne:print_solution(bne:solve([64, 44, 100, 10, 29])).

Erlang确实是个很优秀的语言,特别是解决这种问题的时候。

我几乎就只是在描述问题,而不是在解决问题,虽然这还需要我花一点时间去适应

在下一篇文章里,我会着重讲排列组合的实现方式

郑重声明:资讯 【用Erlang写了个优惠计算器« Tony Huang & Tech】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——