Last active
August 29, 2015 14:21
-
-
Save huseyinyilmaz/fe1c3be4f8fd69628a6d to your computer and use it in GitHub Desktop.
Functional_programming_with_erlang week 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(funs). | |
-export([compose/1]). | |
-export([twice/1]). | |
-export([iteration/1]). | |
-export([make_list/2]). | |
-include_lib("eunit/include/eunit.hrl"). | |
compose(Funs)-> | |
fun(Arg) -> | |
lists:foldl( | |
fun(Fun,Result) -> Fun(Result) end, | |
Arg, | |
Funs) | |
end. | |
twice(Fun) -> compose([Fun,Fun]). | |
% takes an Item and a number N and returns a list | |
% that contains that Item N times. | |
make_list(0, _) -> []; | |
make_list(N, Item) when N>0 -> [Item|make_list(N-1, Item)]. | |
% repeates given function n times. | |
iteration(N) -> | |
fun(Fun) -> compose(make_list(N, Fun)) end. | |
%%%%%%%%%%% | |
%% TESTS %% | |
%%%%%%%%%%% | |
test_double(X) -> X * 2. | |
test_increment(X) -> X + 1. | |
compose_1_test() -> ?assertEqual(5, (compose([fun test_double/1, fun test_increment/1]))(2)). | |
compose_2_test() -> ?assertEqual(6, (compose([fun test_increment/1, fun test_double/1]))(2)). | |
twice_1_test() -> ?assertEqual(8, (twice(fun test_double/1))(2)). | |
twice_2_test() -> ?assertEqual(4, (twice(fun test_increment/1))(2)). | |
twice_3_test() -> ?assertEqual(32, ((twice(fun twice/1))(fun test_double/1))(2)). | |
twice_4_test() -> ?assertEqual(6, ((twice(fun twice/1))(fun test_increment/1))(2)). | |
iteration_1_test() -> ?assertEqual(5, ((iteration(0))(fun test_increment/1))(5)). | |
iteration_2_test() -> ?assertEqual(10, ((iteration(5))(fun test_increment/1))(5)). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(one_five). | |
-export([doubleAll/1]). | |
-export([evens/1]). | |
-export([product/1]). | |
-export([zip/2]). | |
-export([zip_with/3]). | |
-export([zip_with2/3]). | |
-include_lib("eunit/include/eunit.hrl"). | |
-spec doubleAll([integer()]) -> [integer()]. | |
doubleAll(Xs) -> lists:map(fun(X)-> X*2 end,Xs). | |
-spec evens([integer()]) -> [integer()]. | |
evens(Xs) -> lists:filter(fun(X)->(X rem 2) == 0 end, Xs). | |
-spec product([integer()]) -> integer(). | |
product(Xs) -> lists:foldr(fun(X, Acc) -> Acc*X end,1,Xs). | |
-spec zip_with(_,[any()],[any()]) -> [any()]. | |
zip_with(_, [], _) -> []; | |
zip_with(_, _, []) -> []; | |
zip_with(F, [X|Xs], [Y|Ys]) -> [F(X,Y)|zip_with(F,Xs,Ys)]. | |
-spec zip_with2(_,[any()],[any()]) -> [any()]. | |
zip_with2(F, Xs, Ys) -> lists:map(fun({X,Y})->F(X,Y)end,zip(Xs,Ys)). | |
-spec zip([T], [V]) -> [{T,V}]. | |
zip(Xs, Ys) -> zip_with(fun(X,Y)-> {X,Y} end, Xs, Ys). | |
%%%%%%%%%%% | |
%% TESTS %% | |
%%%%%%%%%%% | |
double_all_1_test() -> ?assertEqual([], doubleAll([])). | |
double_all_2_test() -> ?assertEqual([0,2,4,6], doubleAll([0,1,2,3])). | |
evens_1_test() -> ?assertEqual([], evens([])). | |
evens_2_test() -> ?assertEqual([2,4], evens([1,2,3,4])). | |
product_1_test() -> ?assertEqual(1, product([])). | |
product_2_test() -> ?assertEqual(24, product([1,2,3,4])). | |
zip_with_1_test() -> ?assertEqual([],zip_with(fun(X,Y) -> X+Y end, [1,3], [])). | |
zip_with_2_test() -> ?assertEqual([ 3, 7 ], | |
zip_with(fun(X,Y) -> X+Y end, [1,3,5,7], [2,4])). | |
zip_with2_1_test() -> ?assertEqual([],zip_with2(fun(X,Y) -> X+Y end, [1,3], [])). | |
zip_with2_2_test() -> ?assertEqual([ 3, 7 ], | |
zip_with2(fun(X,Y) -> X+Y end, [1,3,5,7], [2,4])). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(rock_paper_scissors). | |
-export([beat/1]). | |
-export([lose/1]). | |
-export([result/2]). | |
-include_lib("eunit/include/eunit.hrl"). | |
beat(rock) -> paper; | |
beat(paper) -> scissors; | |
beat(scissors) -> rock. | |
lose(rock) -> scissors; | |
lose(scissors) -> paper; | |
lose(paper) -> rock. | |
% return 1 for win | |
% 0 for draw | |
% -1 for loose | |
result(First, Second) -> | |
case {beat(First),lose(First)} of | |
{Second,_} -> -1; | |
{_, Second} -> 1; | |
{_, _} -> 0 | |
end. | |
tournament(Xs, Ys) -> lists:foldr(fun({L,R},Sum)-> Sum + result(L,R) end, | |
0, lists:zip(Xs,Ys)). | |
%%%%%%%%%%% | |
%% TESTS %% | |
%%%%%%%%%%% | |
beat_1_test() -> ?assertEqual(paper, beat(rock)). | |
lose_1_test() -> ?assertEqual(scissors, lose(rock)). | |
result_1_test() -> ?assertEqual(0, result(rock,rock)). | |
result_2_test() -> ?assertEqual(0, result(paper,paper)). | |
result_3_test() -> ?assertEqual(0, result(scissors,scissors)). | |
result_4_test() -> ?assertEqual(-1, result(rock,paper)). | |
result_5_test() -> ?assertEqual(-1, result(paper,scissors)). | |
result_6_test() -> ?assertEqual(-1, result(scissors,rock)). | |
result_7_test() -> ?assertEqual(1, result(paper, rock)). | |
result_8_test() -> ?assertEqual(1, result(scissors, paper)). | |
result_9_test() -> ?assertEqual(1, result(rock, scissors)). | |
tournament_1_test() -> ?assertEqual(0, tournament([], [])). | |
tournament_2_test() -> ?assertEqual(-1, tournament([rock,rock,paper,paper], | |
[rock,paper,scissors,rock])). | |
tournament_3_test() -> ?assertEqual(-3, tournament([rock,rock,rock], | |
[paper,paper,paper])). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(rps). | |
-export([play/1,echo/1,play_two/3,rock/1,no_repeat/1,const/1,enum/1,cycle/1,rand/1,val/1,tournament/2]). | |
-include_lib("eunit/include/eunit.hrl"). | |
%% Source: | |
%% http://erlang.org/doc/reference_manual/typespec.html | |
-type choice()::rock|paper|scissors. | |
-type strategy()::fun(([choice()])->choice()). | |
-type result()::win|lose|result. | |
% | |
% play one strategy against another, for N moves. | |
% | |
-spec play_two(strategy(), strategy(), integer())-> integer(). | |
play_two(StrategyL,StrategyR,N) -> | |
play_two(StrategyL,StrategyR,[],[],N). | |
% tail recursive loop for play_two/3 | |
% 0 case computes the result of the tournament | |
% FOR YOU TO DEFINE | |
% REPLACE THE dummy DEFINITIONS | |
-spec play_two(strategy(),strategy(),[choice()],[choice()],integer())->integer(). | |
play_two(_,_,PlaysL,PlaysR,0) -> | |
Result = tournament(PlaysL, PlaysR), | |
io:format("Finished Left Player = ~p , Right Player = ~p~n Result is ~p~n", [PlaysL, PlaysR, Result]), | |
Result; | |
play_two(StrategyL,StrategyR,PlaysL,PlaysR,N) -> | |
{PlayL,PlayR} = {StrategyL(PlaysR), StrategyR(PlaysL)}, | |
play_two(StrategyL, StrategyR, [PlayL|PlaysL],[PlayR|PlaysR], N-1). | |
% | |
% interactively play against a strategy, provided as argument. | |
% | |
-spec play(strategy())-> ok. | |
play(Strategy) -> | |
io:format("Rock - paper - scissors~n"), | |
io:format("Play one of rock, paper, scissors, ...~n"), | |
io:format("... r, p, s, stop, followed by '.'~n"), | |
play(Strategy,[]). | |
% tail recursive loop for play/1 | |
-spec play(strategy(), [choice()])-> ok. | |
play(Strategy,Moves) -> | |
{ok,P} = io:read("Play: "), | |
Play = expand(P), | |
case Play of | |
stop -> | |
io:format("Stopped~n"); | |
_ -> | |
Result = result(Play,Strategy(Moves)), | |
io:format("Result: ~p~n",[Result]), | |
play(Strategy,[Play|Moves]) | |
end. | |
% | |
% auxiliary functions | |
% | |
% transform shorthand atoms to expanded form | |
-spec expand(atom()) -> atom(). | |
expand(r) -> rock; | |
expand(p) -> paper; | |
expand(s) -> scissors; | |
expand(X) -> X. | |
% result of one set of plays | |
-spec result(choice(), choice())->result(). | |
result(rock,rock) -> draw; | |
result(rock,paper) -> lose; | |
result(rock,scissors) -> win; | |
result(paper,rock) -> win; | |
result(paper,paper) -> draw; | |
result(paper,scissors) -> lose; | |
result(scissors,rock) -> lose; | |
result(scissors,paper) -> win; | |
result(scissors,scissors) -> draw. | |
% result of a tournament | |
-spec tournament([choice()], [choice()]) -> integer(). | |
tournament(PlaysL,PlaysR) -> | |
lists:sum( | |
lists:map(fun outcome/1, | |
lists:zipwith(fun result/2,PlaysL,PlaysR))). | |
-spec outcome(result()) -> integer(). | |
outcome(win) -> 1; | |
outcome(lose) -> -1; | |
outcome(draw) -> 0. | |
% transform 0, 1, 2 to rock, paper, scissors and vice versa. | |
-spec enum(integer()) -> choice(). | |
enum(0) -> | |
rock; | |
enum(1) -> | |
paper; | |
enum(2) -> | |
scissors. | |
-spec val(choice()) -> integer(). | |
val(rock) -> | |
0; | |
val(paper) -> | |
1; | |
val(scissors) -> | |
2. | |
% give the play which the argument beats. | |
-spec beats(choice()) -> choice(). | |
beats(rock) -> | |
scissors; | |
beats(paper) -> | |
rock; | |
beats(scissors) -> | |
paper. | |
% | |
% strategies. | |
% | |
-spec echo([choice()])->choice(). | |
echo([]) -> | |
paper; | |
echo([Last|_]) -> | |
Last. | |
-spec rock([choice()])->choice(). | |
rock(_) -> | |
rock. | |
% FOR YOU TO DEFINE | |
% REPLACE THE dummy DEFINITIONS | |
-spec no_repeat([choice()])->choice(). | |
no_repeat([]) -> | |
paper; | |
no_repeat([X|_]) -> | |
X. | |
% Constant? | |
-spec const([choice()])->choice(). | |
const(_Play) -> | |
paper. | |
-spec cycle([choice()])->choice(). | |
cycle(Xs) -> | |
enum(erlang:length(Xs) rem 3). | |
-spec rand([choice()])->choice(). | |
rand(_) -> | |
enum(random:uniform(3)-1). | |
%%%%%%%%%% | |
%% TEST %% | |
%%%%%%%%%% | |
beats_test() -> ?assertEqual(rock, beats(paper)). | |
play_two_1_test() -> ?assertEqual(0, play_two(fun rock/1, fun rock/1,[],[],5)). | |
play_two_2_test() -> ?assertEqual(-1, play_two(fun rock/1, fun echo/1,[],[],5)). | |
play_two_3_test() -> ?assertEqual(1, play_two(fun echo/1, fun rock/1,[],[],5)). | |
play_two_4_test() -> ?assertEqual(-1, play_two(fun cycle/1, fun const/1,[],[],5)). | |
play_two_5_test() -> ?assertEqual(3, play_two(fun cycle/1, fun no_repeat/1,[],[],5)). | |
%% how to call dialyzer | |
%% 1) build plt | |
%% dialyzer --build_plt --apps erts kernel stdlib crypto mnesia sasl eunit | |
%% 2) call dialyzer rps.erl | |
%% Output: | |
%% Huseyins-MacBook-Air:week_3 huseyin$ dialyzer rps.erl | |
%% Checking whether the PLT /Users/huseyin/.dialyzer_plt is up-to-date... yes | |
%% Proceeding with analysis... | |
%% rps.erl:116: The pattern 'rock' can never match the type 'paper' | |
%% rps.erl:120: The pattern 'scissors' can never match the type 'paper' | |
%% done in 0m0.71s | |
%% done (warnings were emitted) | |
%% Huseyins-MacBook-Air:week_3 huseyin$ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment