Download:
child 14:ea71408f41b3
parent 12:23a27ec9f362
13:30f6287441d2
Anton Shestakov <engored@ya.ru>, Wed, 26 Feb 2014 15:06:12 +0900
Separate winner/1 and winning_hand/1, as their logic is different.

2 файлов изменено, 58 вставок(+), 16 удалений(-) [+]
rps.erl file | annotate | diff | comparison | revisions
rps3.erl file | annotate | diff | comparison | revisions
--- a/rps.erl Wed Feb 26 02:28:07 2014 +0900
+++ b/rps.erl Wed Feb 26 15:06:12 2014 +0900
@@ -1,5 +1,5 @@
-module(rps).
--import(rps3, [get_rules/0, beats/1]).
+-import(rps3, [get_rules/0, winning_hand/1]).
-export([
go/0,
winner/1,
@@ -15,18 +15,17 @@
% rock, rock, paper -> {paper, Who}
winner(Choices) when length(Choices) > 1 ->
- HSet = sets:from_list([Hand || {Hand, _} <- Choices]),
- RSet = sets:from_list(get_rules()),
- Absents = sets:subtract(RSet, HSet),
- case sets:size(Absents) of
- 1 ->
- Absent = hd(sets:to_list(Absents)),
- Unbeaten = beats(Absent),
- Winners = [{Hand, Who} || {Hand, Who} <- Choices, Hand =:= Unbeaten],
- case length(Winners) of
- 1 -> hd(Winners);
- _ -> undefined
- end;
+ PlayersByHand = lists:foldl(
+ fun({Hand, Who}, Acc) ->
+ dict:append(Hand, Who, Acc)
+ end, dict:new(), Choices),
+ WHand = winning_hand([Hand || {Hand, _} <- Choices]),
+ Players = if
+ WHand =:= undefined -> [];
+ WHand =/= undefined -> dict:fetch(WHand, PlayersByHand)
+ end,
+ case length(Players) of
+ 1 -> {WHand, hd(Players)};
_ -> undefined
end.
--- a/rps3.erl Wed Feb 26 02:28:07 2014 +0900
+++ b/rps3.erl Wed Feb 26 15:06:12 2014 +0900
@@ -1,5 +1,5 @@
-module(rps3).
--export([get_rules/0, beats/1, test_beats/0]).
+-export([get_rules/0, beats/1, test_beats/0, test_loses/0, winning_hand/1, test_winning_hand/0]).
get_rules() -> [rock, paper, scissors].
@@ -15,9 +15,52 @@
beats(H, [_|T]) ->
beats(H, T).
+loses(H) ->
+ beats(H, lists:reverse(get_rules())).
+
test_beats() ->
lists:foreach(
- fun(C) ->
- io:format("~w beats ~w.~n", [C, beats(C)])
+ fun(H) ->
+ io:format("~w beats ~w.~n", [H, beats(H)])
+ end,
+ get_rules()).
+
+test_loses() ->
+ lists:foreach(
+ fun(H) ->
+ io:format("~w loses to ~w.~n", [H, loses(H)])
end,
get_rules()).
+
+% winner for 3 hands is:
+% rock, rock, rock -> rock
+% rock, paper, scissors -> undefined
+% rock, paper, paper -> paper
+% rock, rock, paper -> paper
+
+winning_hand(Hands) ->
+ HSet = sets:from_list(Hands),
+ sets:fold(
+ fun(Hand, Acc) ->
+ case sets:is_element(loses(Hand), HSet) of
+ true -> Acc;
+ false -> Hand
+ end
+ end, undefined, HSet).
+
+test_winning_hand() ->
+ Cases = [
+ [rock, rock, rock],
+ [rock, paper, scissors],
+ [rock, paper, paper],
+ [rock, rock, paper],
+ [rock, paper],
+ [paper, scissors],
+ [scissors, rock]
+ ],
+ lists:foreach(
+ fun(Hands) ->
+ Winner = winning_hand(Hands),
+ io:format("~w wins in ~w.~n", [Winner, Hands])
+ end,
+ Cases).