今天在为公司买东西的时候,发现了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确实是个很优秀的语言,特别是解决这种问题的时候。
我几乎就只是在描述问题,而不是在解决问题,虽然这还需要我花一点时间去适应
在下一篇文章里,我会着重讲排列组合的实现方式