Skip to content

Instantly share code, notes, and snippets.

@pazworld
Last active December 19, 2015 08:38
Show Gist options
  • Save pazworld/5926625 to your computer and use it in GitHub Desktop.
Save pazworld/5926625 to your computer and use it in GitHub Desktop.
第9回オフラインリアルタイムどう書く Erlang による実装 ref: http://qiita.com/pazworld/items/e641fd71af82a99f92e2
-module(bus).
-compile(export_all).
solve(Data) -> adult_fee(Data) + child_fee(Data) + infant_fee(Data).
adult_fee(Data) -> lists:sum(fees($A, Data)).
child_fee(Data) -> lists:sum(fees($C, Data)).
infant_fee(Data) -> lists:sum(dropn(num_adult(Data) * 2, rev_sort(fees($I, Data)))).
num_adult(Data) -> length(fees($A, Data)).
fees(Mark, Data) -> [mark_to_fee(X, base_fee(Data)) || X <- only(Mark, Data)].
mark_to_fee(Mark, BaseFee) -> roundup10(marks_to_ratio(Mark) * BaseFee).
roundup10(X) -> trunc(X / 10 + 0.99) * 10.
marks_to_ratio(Marks) -> lists:foldl(fun(X, S) -> mark_to_ratio(X) * S end, 1, Marks).
mark_to_ratio(Mark) -> element(2, find_mark(Mark)).
find_mark(Mark) -> hd(lists:dropwhile(fun({M, _}) -> M =/= Mark end, ratio_data())).
ratio_data() -> [{$A, 1}, {$C, 0.5}, {$I, 0.5}, {$n, 1}, {$p, 0}, {$w, 0.5}].
base_fee(Data) -> list_to_integer(hd(string:tokens(Data, ":"))).
only(Mark, Data) -> lists:filter(fun(X) -> hd(X) =:= Mark end, marks(Data)).
marks(Data) -> string:tokens(lists:nth(2, string:tokens(Data, ":")), ",").
dropn(N, L) -> case length(L) >= N of true -> lists:nthtail(N, L); false -> [] end.
rev_sort(L) -> lists:reverse(lists:sort(L)).
tests() ->
test("210:Cn,In,Iw,Ap,Iw", 170), %0
test("220:Cp,In", 110), %1
test("440:In,Ip,Cp,Aw,Iw,In,An", 660), %39
test("1270:Ap,In,An,Ip,In,Ip,Ip", 1270). %40
test(Data, Expected) ->
Result = solve(Data),
OkNg = case Result =:= Expected of true -> ok; false -> ng end,
io:fwrite("~s: ~s -> ~w~n", [OkNg, Data, Result]).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment