Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
cb37572
Add configlet binaries
kytrinyx Jun 2, 2014
6ba96ca
Update configlet binaries
kytrinyx Jun 2, 2014
76dd7cf
Update configlet binaries
kytrinyx Jun 9, 2014
d110dcb
Update configlet binaries
kytrinyx Jun 9, 2014
d2c94d1
Correct dict:dict() type annotation
Jun 12, 2014
8d9dc50
Streamlined naming of test files and examples files
Jun 12, 2014
8e73629
Updated readme and config.json
Jun 12, 2014
24595b2
Activate all trinary tests
Jun 12, 2014
690ee93
Add example and proper test for point-mutations
Jun 12, 2014
a2ef294
Add binary and bank-account
Jun 16, 2014
d440e44
Run tests with escript
Jun 17, 2014
6bd4d56
Add exit value to test script
Jun 17, 2014
f1307f9
Correct exit status
Jun 17, 2014
210eef4
Merge pull request #2 from ebengt/check-exercises-escript
lehoff Jun 24, 2014
546ff1e
Add difference-of-squares exercise
Jun 27, 2014
781adda
Add grains exercise
Jun 27, 2014
bc737fc
Renamned point-mutations to hamming
Jun 28, 2014
eccb6aa
Renamed rna-transcription module to rna_transcription
Jun 28, 2014
cde323c
Renamed module (and tests) after exercise
Jun 28, 2014
e6534a7
Cleanup trinary
Jun 28, 2014
5ebc852
Add largest-series-product exercise
Jul 1, 2014
5439ed5
Merge pull request #6 from ebengt/difference-of-squares
lehoff Jul 1, 2014
6b04722
Merge pull request #7 from ebengt/grains
lehoff Jul 1, 2014
0626db2
Merge pull request #8 from ebengt/hamming
lehoff Jul 1, 2014
15bacdb
Merge pull request #9 from ebengt/rna-transcription
lehoff Jul 1, 2014
d4ef3f0
Merge pull request #10 from ebengt/nucleotide-count
lehoff Jul 1, 2014
7b43da1
Merge pull request #11 from ebengt/trinary
lehoff Jul 1, 2014
4c1194a
Merge pull request #13 from ebengt/largest-series-product
lehoff Jul 1, 2014
7f87583
Add robot-name exercise
Jul 12, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
*.swp
.DS_Store
tmp
*~
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# xErlang

Exercism exercises in Erlang
Exercism exercises in Erlang.

For each test there is a directory, which contains two files, e.g., in the `bob` dir
there is `bob_test.erl` and `example.erl`. The example file define a module with the
name `bob`, so that we can use it to check that the tests are running as they should.
The users of exercism will create their own `bob.erl` file and `bob_test` will test it.

## Contributing Guide

Expand Down
34 changes: 34 additions & 0 deletions _test/check-exercises.escript
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#! /usr/bin/env escript

main( [] ) ->
Examples = filelib:wildcard( "*/example.erl" ),
Modules = [{X, compile(X)} || X <- Examples],
[compile_tests(X) || X <- Modules],
Results = [run_tests(X) || X <- Modules],
erlang:halt( erlang:length([X || X <- Results, X =:= ok]) );
main( _ ) -> usage().



compile( File ) ->
Compile = compile:file( File, [binary, return_errors] ),
{compile, File, {ok, Module, Binary}} = {compile, File, Compile},
Load = code:load_binary( Module, File, Binary ),
{load, Module, Load} = {load, Module, Load},
{Module, Binary}.


compile_tests( {Example, {Example_module, _Binary}} ) ->
Filename = erlang:atom_to_list(Example_module) ++ "_tests.erl",
Filepath = filename:join( [filename:dirname(Example), Filename] ),
compile( Filepath ).


run_tests( {_Example, {Module, _Binary}} ) ->
io:fwrite( "~p: ", [Module] ),
eunit:test( Module ).


usage() ->
io:fwrite( "Usage: ~s~n", [escript:script_name()] ),
io:fwrite( "~s will compile and run Erlang examples and test cases in sub directories of where it is started.~n", [escript:script_name()] ).
25 changes: 25 additions & 0 deletions accumulate/accumulate_tests.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-module( accumulate_tests ).

-include_lib("eunit/include/eunit.hrl").

accumulate_squares_test() ->
Fn = fun(Number) -> Number * Number end,
Ls = [1, 2, 3],
?assertEqual([1, 4, 9], accumulate:accumulate(Fn, Ls)).

accumulate_upcases_test() ->
Fn = fun(Word) -> string:to_upper(Word) end,
Ls = string:tokens("hello world", " "),
?assertEqual(["HELLO", "WORLD"], accumulate:accumulate(Fn, Ls)).

accumulate_reversed_strings_test() ->
Fn = fun(Word) -> lists:reverse(Word) end,
Ls = string:tokens("the quick brown fox etc", " "),
?assertEqual(["eht", "kciuq", "nworb", "xof", "cte"], accumulate:accumulate(Fn, Ls)).

accumulate_recursively_test() ->
Chars = string:tokens("a b c", " "),
Nums = string:tokens("1 2 3", " "),
Fn = fun(Char) -> [Char ++ Num || Num <- Nums] end,
?assertEqual([["a1", "a2", "a3"], ["b1", "b2", "b3"], ["c1", "c2", "c3"]], accumulate:accumulate(Fn, Chars)).

49 changes: 49 additions & 0 deletions allergies/allergies_test.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
% To run tests:
% elc *.erl
% erl -noshell -eval "eunit:test(allergies, [verbose])" -s init stop
%

-module(allergies_test).

-include_lib("eunit/include/eunit.hrl").

no_allergies_at_all_test() ->
?assertEqual(allergies:allergies(0), []).

allergic_to_just_eggs_test() ->
?assertEqual(allergies:allergies(1), ['eggs']).

allergic_to_just_peanuts_test() ->
?assertEqual(allergies:allergies(2), ['peanuts']).

allergic_to_just_strawberries_test() ->
?assertEqual(allergies:allergies(8), ['strawberries']).

allergic_to_eggs_and_peanuts_test() ->
?assertEqual(allergies:allergies(3), ['eggs', 'peanuts']).

allergic_to_more_than_eggs_but_not_peanuts_test() ->
?assertEqual(allergies:allergies(5), ['eggs', 'shellfish']).

allergic_to_lots_of_stuff_test() ->
?assertEqual(allergies:allergies(248), ['strawberries', 'tomatoes', 'chocolate',
'pollen', 'cats']).

allergic_to_everything_test() ->
?assertEqual(allergies:allergies(255),['eggs', 'peanuts', 'shellfish', 'strawberries',
'tomatoes', 'chocolate', 'pollen', 'cats']).

no_allergies_means_not_allergic_test() ->
?assertNot(allergies:isAllergicTo('peanuts', 0)),
?assertNot(allergies:isAllergicTo('cats', 0)),
?assertNot(allergies:isAllergicTo('strawberries', 0)).

is_allergic_to_eggs_test() ->
?assert(allergies:isAllergicTo('eggs', 1)).

allergic_to_eggs_and_other_stuff_test() ->
?assert(allergies:isAllergicTo('eggs', 5)).

ignore_non_allergen_score_parts_test() ->
?assertEqual(allergies:allergies(509), ['eggs', 'shellfish', 'strawberries',
'tomatoes', 'chocolate', 'pollen', 'cats']).
2 changes: 1 addition & 1 deletion allergies/allergies_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
% erl -noshell -eval "eunit:test(allergies, [verbose])" -s init stop
%

-module(allergies_tests).
-module( allergies_tests ).

-include_lib("eunit/include/eunit.hrl").

Expand Down
48 changes: 48 additions & 0 deletions anagram/anagram_tests.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
-module( anagram_tests ).
-include_lib("eunit/include/eunit.hrl").

no_matches_test() ->
?assertEqual(
anagram:find("diaper", ["hello", "world", "zombies", "pants"]),
[]).

detect_simple_anagram_test() ->
?assertEqual(
anagram:find("ant", ["tan", "stand", "at"]),
["tan"]).

does_not_confuse_different_duplicates_test() ->
?assertEqual(
anagram:find("galea", ["eagle"]),
[]).

eliminate_anagram_subsets_test() ->
?assertEqual(
anagram:find("good", ["dog", "goody"]),
[]).

detect_anagram_test() ->
?assertEqual(
anagram:find("listen", ["enlists", "google", "inlets", "banana"]),
["inlets"]).

multiple_anagrams_test() ->
?assertEqual(
anagram:find("allergy", ["gallery", "ballerina", "regally", "clergy",
"largely", "leading"]),
["gallery", "regally", "largely"]).

case_insensitive_subject_test() ->
?assertEqual(
anagram:find("Orchestra", ["cashregister", "carthorse", "radishes"]),
["carthorse"]).

case_insensitive_candidate_test() ->
?assertEqual(
anagram:find("orchestra", ["cashregister", "Carthorse", "radishes"]),
["Carthorse"]).

does_not_detect_a_word_as_its_own_anagram_test() ->
?assertEqual(
anagram:find("corn", ["corn", "dark", "Corn", "rank", "CORN", "cron", "park"]),
["cron"]).
95 changes: 95 additions & 0 deletions bank-account/bank_account_tests.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
-module(bank_account_tests).
-include_lib("eunit/include/eunit.hrl").


create_test() ->
Bank_account = bank_account:create(),
?assert(bank_account:balance( Bank_account ) =:= 0).

close_account_test() ->
Bank_account = bank_account:create(),
bank_account:deposit( Bank_account, 1 ),
Amount = bank_account:close( Bank_account ),
?assert(Amount =:= 1),
?assertError(function_clause, bank_account:balance( Bank_account )).

deposit_test() ->
Bank_account = bank_account:create(),
bank_account:deposit( Bank_account, 1 ),
?assert(bank_account:balance( Bank_account ) =:= 1).

deposit_fail_test() ->
Bank_account = bank_account:create(),
bank_account:deposit( Bank_account, -1 ),
?assert(bank_account:balance( Bank_account ) =:= 0).

deposit_many_test() ->
Bank_account = bank_account:create(),
[erlang:spawn( fun () -> bank_account:deposit(Bank_account, X) end ) || X <- lists:seq(1, 10)],
First = bank_account:balance( Bank_account ),
timer:sleep( 100 ),
Last = bank_account:balance( Bank_account ),
?assert(First < 55),
?assert(Last =:= 55).

withdraw_test() ->
Bank_account = bank_account:create(),
bank_account:deposit( Bank_account, 10 ),
Amount = bank_account:withdraw( Bank_account, 1 ),
?assert(Amount =:= 1),
?assert(bank_account:balance( Bank_account ) =:= 9).

withdraw_fail_test() ->
Bank_account = bank_account:create(),
bank_account:deposit( Bank_account, 10 ),
Amount = bank_account:withdraw( Bank_account, -1 ),
?assert(Amount =:= 0),
?assert(bank_account:balance( Bank_account ) =:= 10).

withdraw_excessive_test() ->
Bank_account = bank_account:create(),
bank_account:deposit( Bank_account, 10 ),
Amount = bank_account:withdraw( Bank_account, 20 ),
?assert(Amount =:= 10),
?assert(bank_account:balance( Bank_account ) =:= 0).

withdraw_many_test() ->
Bank_account = bank_account:create(),
bank_account:deposit(Bank_account, 55 ),
[erlang:spawn( fun () -> bank_account:withdraw(Bank_account, X) end ) || X <- lists:seq(1, 10)],
First = bank_account:balance( Bank_account ),
timer:sleep( 100 ),
Last = bank_account:balance( Bank_account ),
?assert(First > 0),
?assert(Last =:= 0).

charge_test() ->
Bank_account = bank_account:create(),
bank_account:deposit( Bank_account, 10 ),
Amount = bank_account:charge( Bank_account, 2 ),
?assert(Amount =:= 2),
?assert(bank_account:balance( Bank_account ) =:= 8).

charge_fail_test() ->
Bank_account = bank_account:create(),
bank_account:deposit( Bank_account, 10 ),
Amount = bank_account:charge( Bank_account, -2 ),
?assert(Amount =:= 0),
?assert(bank_account:balance( Bank_account ) =:= 10).

charge_excessive_test() ->
Bank_account = bank_account:create(),
bank_account:deposit( Bank_account, 10 ),
Amount = bank_account:charge( Bank_account, 20 ),
?assert(Amount =:= 0),
?assert(bank_account:balance( Bank_account ) =:= 10).

charge_many_test() ->
Bank_account = bank_account:create(),
bank_account:deposit(Bank_account, 55 ),
[erlang:spawn( fun () -> bank_account:charge(Bank_account, 10) end ) || _X <- lists:seq(1, 10)],
First = bank_account:balance( Bank_account ),
timer:sleep( 100 ),
Last = bank_account:balance( Bank_account ),
?assert(First > 0),
?assert(Last =:= 5).
48 changes: 48 additions & 0 deletions bank-account/example.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
-module(bank_account).

-export( [balance/1, charge/2, close/1, create/0, deposit/2, withdraw/2] ).

balance( Pid ) -> call( erlang:is_process_alive(Pid), Pid, balance, 0 ).

charge( Pid, Amount ) when Amount > 0 -> call( erlang:is_process_alive(Pid), Pid, charge, Amount );
charge( _Pid, _Amount ) -> 0.

close( Pid ) -> call( erlang:is_process_alive(Pid), Pid, close, 0 ).

create() -> erlang:spawn( fun () -> loop(0) end ).

deposit( Pid, Amount ) when Amount > 0 -> Pid ! {deposit, Amount};
deposit( _Pid, _Amount ) -> ok.

withdraw( Pid, Amount ) when Amount > 0 -> call( erlang:is_process_alive(Pid), Pid, withdraw, Amount );
withdraw( _Pid, _Amount ) -> 0.



call( true, Pid, Request, Argument ) ->
Pid ! {Request, Argument, erlang:self()},
receive
{Request, Answer} -> Answer
end.

loop( Balance ) ->
receive
{balance, _Argument, Pid} ->
Pid ! {balance, Balance},
loop( Balance );
{charge, Amount, Pid} ->
Charge = loop_charge( Balance, Amount ),
Pid ! {charge, Charge},
loop( Balance - Charge );
{close, _Argument, Pid} ->
Pid ! {close, Balance};
{deposit, Amount} ->
loop( Balance + Amount );
{withdraw, Amount, Pid} ->
Withdraw = erlang:min( Balance, Amount ),
Pid ! {withdraw, Withdraw},
loop( Balance - Withdraw )
end.

loop_charge( Balance, Amount ) when Balance >= Amount -> Amount;
loop_charge( _Balance, _Amount ) -> 0.
50 changes: 50 additions & 0 deletions beer-song/beer_song_tests.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
-module( beer_song_tests ).
-include_lib("eunit/include/eunit.hrl").

verse_test() ->
compareNestedLists(beer_song:verse(8),
"8 bottles of beer on the wall, 8 bottles of beer.\n"
"Take it down and pass it around, 7 bottles of beer on the wall.\n").

verse_0_test() ->
compareNestedLists(beer_song:verse(0),
"No more bottles of beer on the wall, no more bottles of beer.\n"
"Go to the store and buy some more, 99 bottles of beer on the wall.\n").

verse_1_test() ->
compareNestedLists(beer_song:verse(1),
"1 bottle of beer on the wall, 1 bottle of beer.\n"
"Take it down and pass it around, no more bottles of beer on the wall.\n").

verse_2_test() ->
compareNestedLists(beer_song:verse(2),
"2 bottles of beer on the wall, 2 bottles of beer.\n"
"Take it down and pass it around, 1 bottle of beer on the wall.\n").

singing_several_verses_test() ->
compareNestedLists(beer_song:sing(8, 6),
"8 bottles of beer on the wall, 8 bottles of beer.\n"
"Take it down and pass it around, 7 bottles of beer on the wall.\n\n"

"7 bottles of beer on the wall, 7 bottles of beer.\n"
"Take it down and pass it around, 6 bottles of beer on the wall.\n\n"

"6 bottles of beer on the wall, 6 bottles of beer.\n"
"Take it down and pass it around, 5 bottles of beer on the wall.\n\n").

sing_all_the_rest_of_the_verses_test() ->
compareNestedLists(beer_song:sing(3),
"3 bottles of beer on the wall, 3 bottles of beer.\n"
"Take it down and pass it around, 2 bottles of beer on the wall.\n\n"

"2 bottles of beer on the wall, 2 bottles of beer.\n"
"Take it down and pass it around, 1 bottle of beer on the wall.\n\n"

"1 bottle of beer on the wall, 1 bottle of beer.\n"
"Take it down and pass it around, no more bottles of beer on the wall.\n\n"

"No more bottles of beer on the wall, no more bottles of beer.\n"
"Go to the store and buy some more, 99 bottles of beer on the wall.\n\n").

compareNestedLists(Response, Expected) ->
?assertEqual(lists:flatten(Response), lists:flatten(Expected)).
Binary file added bin/configlet-darwin-386
Binary file not shown.
Binary file added bin/configlet-darwin-amd64
Binary file not shown.
Binary file added bin/configlet-linux-386
Binary file not shown.
Binary file added bin/configlet-linux-amd64
Binary file not shown.
Binary file added bin/configlet-windows-386.exe
Binary file not shown.
Binary file added bin/configlet-windows-amd64.exe
Binary file not shown.
Loading