diff --git a/.gitignore b/.gitignore index ea0d1853..5b175045 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.swp .DS_Store tmp +*~ \ No newline at end of file diff --git a/README.md b/README.md index f18d638c..2c32c6c8 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/_test/check-exercises.escript b/_test/check-exercises.escript new file mode 100755 index 00000000..60dddf6b --- /dev/null +++ b/_test/check-exercises.escript @@ -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()] ). diff --git a/accumulate/accumulate_tests.erl b/accumulate/accumulate_tests.erl new file mode 100644 index 00000000..96564135 --- /dev/null +++ b/accumulate/accumulate_tests.erl @@ -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)). + diff --git a/allergies/allergies_test.erl b/allergies/allergies_test.erl new file mode 100644 index 00000000..23b7d579 --- /dev/null +++ b/allergies/allergies_test.erl @@ -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']). diff --git a/allergies/allergies_tests.erl b/allergies/allergies_tests.erl index 1ddcaeb9..1af49fb9 100644 --- a/allergies/allergies_tests.erl +++ b/allergies/allergies_tests.erl @@ -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"). diff --git a/anagram/anagram_tests.erl b/anagram/anagram_tests.erl new file mode 100644 index 00000000..8d0def08 --- /dev/null +++ b/anagram/anagram_tests.erl @@ -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"]). diff --git a/bank-account/bank_account_tests.erl b/bank-account/bank_account_tests.erl new file mode 100644 index 00000000..ed84ce0f --- /dev/null +++ b/bank-account/bank_account_tests.erl @@ -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). diff --git a/bank-account/example.erl b/bank-account/example.erl new file mode 100644 index 00000000..97b7e9fb --- /dev/null +++ b/bank-account/example.erl @@ -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. diff --git a/beer-song/beer_song_tests.erl b/beer-song/beer_song_tests.erl new file mode 100644 index 00000000..3ad89214 --- /dev/null +++ b/beer-song/beer_song_tests.erl @@ -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)). diff --git a/bin/configlet-darwin-386 b/bin/configlet-darwin-386 new file mode 100755 index 00000000..514ec094 Binary files /dev/null and b/bin/configlet-darwin-386 differ diff --git a/bin/configlet-darwin-amd64 b/bin/configlet-darwin-amd64 new file mode 100755 index 00000000..1142a8c7 Binary files /dev/null and b/bin/configlet-darwin-amd64 differ diff --git a/bin/configlet-linux-386 b/bin/configlet-linux-386 new file mode 100755 index 00000000..2ff44037 Binary files /dev/null and b/bin/configlet-linux-386 differ diff --git a/bin/configlet-linux-amd64 b/bin/configlet-linux-amd64 new file mode 100755 index 00000000..45ec32d5 Binary files /dev/null and b/bin/configlet-linux-amd64 differ diff --git a/bin/configlet-windows-386.exe b/bin/configlet-windows-386.exe new file mode 100755 index 00000000..64f20caf Binary files /dev/null and b/bin/configlet-windows-386.exe differ diff --git a/bin/configlet-windows-amd64.exe b/bin/configlet-windows-amd64.exe new file mode 100755 index 00000000..39fc7872 Binary files /dev/null and b/bin/configlet-windows-amd64.exe differ diff --git a/binary/binary_string_tests.erl b/binary/binary_string_tests.erl new file mode 100644 index 00000000..8648a3ac --- /dev/null +++ b/binary/binary_string_tests.erl @@ -0,0 +1,22 @@ +-module( binary_string_tests ). +-include_lib( "eunit/include/eunit.hrl" ). + + +one_test() -> check( "1" ). + +two_test() -> check( "10" ). + +three_test() -> check( "11" ). + +four_test() -> check( "100" ). + +nine_test() -> check( "1001" ). + +twenty_six_test() -> check( "11010" ). + +large_test() -> check( "10001101000" ). + +carrot_test() -> ?assert(0 =:= binary_string:to_decimal( "carrot" )). + +check( String ) -> + ?assert(binary_string:to_decimal( String ) =:= erlang:list_to_integer( String, 2 )). diff --git a/binary/example.erl b/binary/example.erl new file mode 100644 index 00000000..0c3225ec --- /dev/null +++ b/binary/example.erl @@ -0,0 +1,17 @@ +-module( binary_string ). % binary is a "sticky module" so we have to use another name. +-export( [to_decimal/1] ). + +to_decimal( String ) -> + try + {_N, Result} = lists:foldr( fun to_decimal/2, {0, 0}, String ), + Result + + catch + _:_ -> 0 + + end. + + + +to_decimal( $0, {N, Acc} ) -> {N + 1, Acc}; +to_decimal( $1, {N, Acc} ) -> {N + 1, Acc + erlang:trunc(math:pow(2, N))}. diff --git a/bob/bob_tests.erl b/bob/bob_tests.erl new file mode 100644 index 00000000..6dbb9389 --- /dev/null +++ b/bob/bob_tests.erl @@ -0,0 +1,70 @@ +-module( bob_tests ). + +-include_lib("eunit/include/eunit.hrl"). + +responds_to_something_test() -> + bob_responds("Tom-ay-to, tom-aaaah-to.", "Whatever."). + +responds_to_shouts_test() -> + bob_responds("WATCH OUT!", "Woah, chill out!"). + +responds_to_questions_test() -> + bob_responds("Does this cryogenic chamber make me look fat?", "Sure."). + +responds_to_forceful_talking_test() -> + bob_responds("Let's go make out behind the gym!", "Whatever."). + +responds_to_acronyms_test() -> + bob_responds("It's OK if you don't want to go to the DMV.", "Whatever."). + +responds_to_forceful_questions_test() -> + bob_responds("WHAT THE HELL WERE YOU THINKING?", "Woah, chill out!"). + +responds_to_shouting_with_special_characters_test() -> + bob_responds("ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!", + "Woah, chill out!"). + +responds_to_shouting_numbers_test() -> + bob_responds("1, 2, 3, GO!", "Woah, chill out!"). + +responds_to_shouting_with_no_exclamation_mark_test() -> + bob_responds("I HATE YOU", "Woah, chill out!"). + +responds_to_statement_containing_question_mark_test() -> + bob_responds("Ending with ? means a question", "Whatever."). + +responds_to_silence_test() -> + bob_responds("", "Fine. Be that way!"). + +responds_to_prolonged_silence_test() -> + bob_responds(" ", "Fine. Be that way!"). + + +responds_to_non_letters_with_question_test() -> + bob_responds(":) ?", "Sure."). + +responds_to_multiple_line_questions_test() -> + bob_responds("\nDoes this cryogenic chamber make me look fat? \nno", + "Whatever."). + +%% This one is especially challenging in Erlang, hint: use the re module. + +%%responds_to_other_whitespace_test() -> +%% bob_responds("\n\r \t\v\xA0\x{2002}", +%% "Fine. Be that way!"). + +responds_to_only_numbers_test() -> + bob_responds("1, 2, 3", "Whatever."). + +responds_to_question_with_only_numbers_test() -> + bob_responds("4?", "Sure."). + +responds_to_unicode_shout_test() -> + bob_responds("\xdcML\xc4\xdcTS!", "Woah, chill out!"). + +responds_to_unicode_non_shout_test() -> + bob_responds("\xdcML\xe4\xdcTS!", "Whatever."). + +bob_responds(Question, Answer) -> + ?assertEqual(bob:response_for(Question), + Answer). diff --git a/config.json b/config.json index b2dd685d..affa251f 100644 --- a/config.json +++ b/config.json @@ -4,7 +4,19 @@ "repository": "https://github.com/exercism/xerlang", "active": false, "problems": [ - + "bob", + "word-count", + "accumulate", + "anagram", + "beer-song", + "nucleotide-count", + "rna-transcription", + "point-mutations", + "phone-number", + "etl", + "allergies", + "trinary", + "luhn" ], "deprecated": [ diff --git a/difference-of-squares/difference_of_squares_tests.erl b/difference-of-squares/difference_of_squares_tests.erl new file mode 100644 index 00000000..4b34ce9e --- /dev/null +++ b/difference-of-squares/difference_of_squares_tests.erl @@ -0,0 +1,7 @@ +-module( difference_of_squares_tests ). +-include_lib( "eunit/include/eunit.hrl" ). + +ten_test() -> + Sum_of_squares = difference_of_squares:sum_of_squares( 10 ), + Square_of_sums = difference_of_squares:square_of_sums( 10 ), + ?assert( Square_of_sums - Sum_of_squares =:= 2640 ). diff --git a/difference-of-squares/example.erl b/difference-of-squares/example.erl new file mode 100644 index 00000000..2a89d779 --- /dev/null +++ b/difference-of-squares/example.erl @@ -0,0 +1,11 @@ +-module( difference_of_squares ). + +-export( [sum_of_squares/1, square_of_sums/1] ). + +sum_of_squares( N ) -> lists:sum( [square(X) || X <- lists:seq(1, N)] ). + +square_of_sums( N ) -> square( lists:sum(lists:seq(1, N)) ). + + + +square( N ) -> erlang:trunc( math:pow(N, 2) ). diff --git a/etl/etl_test.erl b/etl/etl_test.erl index d69c894f..40c9eb23 100644 --- a/etl/etl_test.erl +++ b/etl/etl_test.erl @@ -51,6 +51,6 @@ transform_full_dataset_test() -> erl_transform(Old, Expected). erl_transform(Old,New) -> - ?assertEqual(example:transform(Old), New). + ?assertEqual(etl:transform(Old), New). diff --git a/etl/etl_tests.erl b/etl/etl_tests.erl new file mode 100644 index 00000000..f838b22a --- /dev/null +++ b/etl/etl_tests.erl @@ -0,0 +1,56 @@ +-module( etl_tests ). + +-include_lib("eunit/include/eunit.hrl"). + +transform_one_value_test() -> + erl_transform([{"a", [1]}], [{1, "a"}]). + +transform_one_word_test() -> + erl_transform([{"hello", ["WORLD"]}], [{"world", "hello"}]). + +transform_more_values_test() -> + erl_transform([{"hello", ["WORLD","GSCHOOLERS"]}], [{"gschoolers", "hello"}, {"world", "hello"}]). + +transform_multiple_keys_from_one_value_test() -> + erl_transform([{"a", [1]}, {"b", [1]}], [{1, "ab"}]). + +transform_multiple_keys_from_multiple_values_test() -> + erl_transform([{"a", [1]}, {"b", [4]}], [{1, "a"}, {4, "b"}]). + +transform_more_keys_test() -> + Old = [ + {"a", ["APPLE", "ARTICHOKE"]} + ,{"b", ["BOAT", "BALLERINA"]} + ], + Expected = [ + {"apple", "a"}, + {"artichoke", "a"}, + {"ballerina", "b"}, + {"boat", "b"} + ], + erl_transform(Old, Expected). + +transform_full_dataset_test() -> + Old = [ + {1, ["A","E","I","O","U","L","N","R","S","T"]} + , {2, ["D","G"]} + , {3, ["B","C","M","P"]} + , {4, ["F","H","V","W","Y"]} + , {5, ["K"]} + , {8, ["J","X"]} + , {10, ["Q","Z"]} + ], + Expected = [ + {"a", 1}, {"b", 3}, {"c", 3}, {"d", 2}, {"e", 1} + , {"f", 4}, {"g", 2}, {"h", 4}, {"i", 1}, {"j", 8} + , {"k", 5}, {"l", 1}, {"m", 3}, {"n", 1}, {"o", 1} + , {"p", 3}, {"q", 10}, {"r", 1}, {"s", 1}, {"t", 1} + , {"u", 1}, {"v", 4}, {"w", 4}, {"x", 8}, {"y", 4} + , {"z", 10} + ], + erl_transform(Old, Expected). + +erl_transform(Old,New) -> + ?assertEqual(etl:transform(Old), New). + + diff --git a/etl/example.erl b/etl/example.erl index 9726652c..b8460288 100644 --- a/etl/example.erl +++ b/etl/example.erl @@ -1,4 +1,4 @@ --module(example). +-module(etl). -export([transform/1]). diff --git a/grains/example.erl b/grains/example.erl new file mode 100644 index 00000000..e0df6c50 --- /dev/null +++ b/grains/example.erl @@ -0,0 +1,12 @@ +-module( grains ). +-export( [chess/0, per_square_and_sum/1] ). + +chess() -> per_square_and_sum( 64 ). + +per_square_and_sum( N ) -> lists:mapfoldl( fun pow_2_and_sum/2, 0, lists:seq(1, N) ). + + + +pow_2_and_sum( N, Acc ) -> + Pow_2 = erlang:trunc( math:pow(2, N - 1) ), + {{N, Pow_2}, Pow_2 + Acc}. \ No newline at end of file diff --git a/grains/grains_tests.erl b/grains/grains_tests.erl new file mode 100644 index 00000000..81e17c85 --- /dev/null +++ b/grains/grains_tests.erl @@ -0,0 +1,75 @@ +-module( grains_tests ). +-include_lib( "eunit/include/eunit.hrl" ). + +general_test() -> + Solution = {[{1,1},{2,2},{3,4},{4,8},{5,16}],31}, + ?assert( Solution =:= grains:per_square_and_sum(5) ). + +chess_test() -> + Solution = +{[{1,1}, + {2,2}, + {3,4}, + {4,8}, + {5,16}, + {6,32}, + {7,64}, + {8,128}, + {9,256}, + {10,512}, + {11,1024}, + {12,2048}, + {13,4096}, + {14,8192}, + {15,16384}, + {16,32768}, + {17,65536}, + {18,131072}, + {19,262144}, + {20,524288}, + {21,1048576}, + {22,2097152}, + {23,4194304}, + {24,8388608}, + {25,16777216}, + {26,33554432}, + {27,67108864}, + {28,134217728}, + {29,268435456}, + {30,536870912}, + {31,1073741824}, + {32,2147483648}, + {33,4294967296}, + {34,8589934592}, + {35,17179869184}, + {36,34359738368}, + {37,68719476736}, + {38,137438953472}, + {39,274877906944}, + {40,549755813888}, + {41,1099511627776}, + {42,2199023255552}, + {43,4398046511104}, + {44,8796093022208}, + {45,17592186044416}, + {46,35184372088832}, + {47,70368744177664}, + {48,140737488355328}, + {49,281474976710656}, + {50,562949953421312}, + {51,1125899906842624}, + {52,2251799813685248}, + {53,4503599627370496}, + {54,9007199254740992}, + {55,18014398509481984}, + {56,36028797018963968}, + {57,72057594037927936}, + {58,144115188075855872}, + {59,288230376151711744}, + {60,576460752303423488}, + {61,1152921504606846976}, + {62,2305843009213693952}, + {63,4611686018427387904}, + {64,9223372036854775808}], + 18446744073709551615}, + ?assert( Solution =:= grains:chess() ). diff --git a/hamming/example.erl b/hamming/example.erl new file mode 100644 index 00000000..c9d7fdbc --- /dev/null +++ b/hamming/example.erl @@ -0,0 +1,8 @@ +-module( hamming ). + +-export( [distance/2] ). + +distance( [], _ ) -> 0; +distance( _, [] ) -> 0; +distance( [A|As], [A|Bs] ) -> distance( As, Bs ); +distance( [_|As], [_|Bs] ) -> 1 + distance( As, Bs ). diff --git a/hamming/hamming_tests.erl b/hamming/hamming_tests.erl new file mode 100644 index 00000000..53159ab9 --- /dev/null +++ b/hamming/hamming_tests.erl @@ -0,0 +1,24 @@ +-module( hamming_tests ). +-include_lib( "eunit/include/eunit.hrl" ). + +no_difference_between_empty_strands_test() -> + ?assertEqual( 0, hamming:distance("", "") ). + +no_difference_between_identical_strands_test() -> + ?assertEqual( 0, hamming:distance("GGACTGA", "GGACTGA") ). + +hamming_distance_in_off_by_one_strand_test() -> + ?assertEqual( 19, hamming:distance("GGACGGATTCTGACCTGGACTAATTTTGGGG", + "AGGACGGATTCTGACCTGGACTAATTTTGGGG") ). + +small_hamming_distance_in_middle_somewhere_test() -> + ?assertEqual( 1, hamming:distance("GGACG", "GGTCG") ). + +langer_distance_test() -> + ?assertEqual( 2 , hamming:distance("ACCAGGG", "ACTATGG") ). + +ignores_extra_length_on_other_strand_when_longer_test()-> + ?assertEqual( 3, hamming:distance("AAACTAGGGG", "AGGCTAGCGGTAGGAC") ). + +ignores_extra_length_on_original_strand_when_longer_test() -> + ?assertEqual( 5, hamming:distance("GACTACGGACAGGGTAGGGAAT", "GACATCGCACACC") ). diff --git a/largest-series-product/example.erl b/largest-series-product/example.erl new file mode 100644 index 00000000..d8476077 --- /dev/null +++ b/largest-series-product/example.erl @@ -0,0 +1,19 @@ +-module( largest_series_product ). + +-export( [from_string/2 ] ). + +from_string( String, N ) -> from_string( erlang:length(String), String, N ). + + + +from_string( Length, String, N ) when Length >= N -> + Sets = sets( Length, N, String ), + lists:max( [product(X) || X <- Sets] ). + +product( Set ) -> lists:foldl( fun product/2, 1, Set ). +product( C, Acc ) when C >= $0, C =< $9 -> (C - $0) * Acc. + +sets( Length, Width, [_ | T]=String ) when Length > Width -> + Set = lists:sublist( String, Width ), + [Set | sets( Length - 1, Width, T )]; +sets( _Length, _Width, String ) -> [String]. diff --git a/largest-series-product/largest_series_product_tests.erl b/largest-series-product/largest_series_product_tests.erl new file mode 100644 index 00000000..538b09d5 --- /dev/null +++ b/largest-series-product/largest_series_product_tests.erl @@ -0,0 +1,8 @@ +-module( largest_series_product_tests ). +-include_lib("eunit/include/eunit.hrl"). + +three_test() -> ?assert( 504 =:= largest_series_product:from_string("0123456789", 3) ). + +five_test() -> ?assert( 15120 =:= largest_series_product:from_string("0123456789", 5) ). + +six_test() -> ?assert( 23520 =:= largest_series_product:from_string("73167176531330624919225119674426574742355349194934", 6) ). diff --git a/luhn/luhn_tests.erl b/luhn/luhn_tests.erl new file mode 100644 index 00000000..9520b715 --- /dev/null +++ b/luhn/luhn_tests.erl @@ -0,0 +1,14 @@ +-module( luhn_tests ). +-include_lib("eunit/include/eunit.hrl"). + +invalid_test() -> + ?assertNot(luhn:valid("1111")), + ?assertNot(luhn:valid("738")). + +valid_test() -> + ?assert(luhn:valid("8739567")), + ?assert(luhn:valid("8763")), + ?assert(luhn:valid("2323 2005 7766 3554")). + +create_test() -> + ?assertEqual("2323 2005 7766 3554", luhn:create("2323 2005 7766 355")). diff --git a/nucleotide-count/dna_tests.erl b/nucleotide-count/dna_tests.erl deleted file mode 100644 index e6273ba9..00000000 --- a/nucleotide-count/dna_tests.erl +++ /dev/null @@ -1,30 +0,0 @@ --module(dna_tests). - --include_lib("eunit/include/eunit.hrl"). - -empty_dna_string_has_no_adenosine_test() -> - ?assertEqual(dna:count("", "A"), 0). - -repetitive_cytidine_gets_counted_test() -> - ?assertEqual(dna:count("CCCCC", "C"), 5). - -counts_only_thymidine_test() -> - ?assertEqual(dna:count("GGGGGTAACCCGG", "T"), 1). - -dna_has_no_uracil_test() -> - ?assertEqual(dna:count("GATTACA", "U"), 0). - -validates_nucleotides_test() -> - ?assertException(error, "Invalid nucleotide", dna:count("GACT", "X")). - -empty_dna_string_has_no_nucleotides_test() -> - ?assertEqual(dna:nucleotide_counts(""), - [{"A", 0}, {"T", 0}, {"C", 0}, {"G", 0}]). - -repetitive_sequence_has_only_guanosine_test() -> - ?assertEqual(dna:nucleotide_counts("GGGGGGGG"), - [{"A", 0}, {"T", 0}, {"C", 0}, {"G", 8}]). - -counts_all_nucleotides_test() -> - ?assertEqual(dna:nucleotide_counts("AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC"), - [{"A", 20}, {"T", 21}, {"C", 12}, {"G", 17}]). diff --git a/nucleotide-count/example.erl b/nucleotide-count/example.erl index 862a3b81..02d4d528 100644 --- a/nucleotide-count/example.erl +++ b/nucleotide-count/example.erl @@ -1,6 +1,6 @@ --module(dna). +-module( nucleotide_count ). --export([count/2, nucleotide_counts/1, validate/1]). +-export( [count/2, dna/1, validate/1] ). count(Dna, N) -> validate(N), @@ -21,8 +21,8 @@ validate(N) -> _ -> erlang:error("Invalid nucleotide") end. -nucleotide_counts(Dna) -> - [{"A", count(Dna, "A")}, +dna( Dna ) -> + {{"A", count(Dna, "A")}, {"T", count(Dna, "T")}, {"C", count(Dna, "C")}, - {"G", count(Dna, "G")}]. + {"G", count(Dna, "G")}}. diff --git a/nucleotide-count/nucleotide_count_tests.erl b/nucleotide-count/nucleotide_count_tests.erl new file mode 100644 index 00000000..ac076acc --- /dev/null +++ b/nucleotide-count/nucleotide_count_tests.erl @@ -0,0 +1,27 @@ +-module( nucleotide_count_tests ). +-include_lib( "eunit/include/eunit.hrl" ). + +empty_dna_string_has_no_adenosine_test() -> + ?assertEqual( nucleotide_count:count("", "A"), 0 ). + +repetitive_cytidine_gets_counted_test() -> + ?assertEqual( nucleotide_count:count("CCCCC", "C"), 5 ). + +counts_only_thymidine_test() -> + ?assertEqual( nucleotide_count:count("GGGGGTAACCCGG", "T"), 1 ). + +dna_has_no_uracil_test() -> + ?assertEqual( nucleotide_count:count("GATTACA", "U"), 0 ). + +validates_nucleotides_test() -> + ?assertException( error, "Invalid nucleotide", nucleotide_count:count("GACT", "X") ). + +empty_dna_string_has_no_nucleotides_test() -> + ?assertEqual( nucleotide_count:dna(""), {{"A", 0}, {"T", 0}, {"C", 0}, {"G", 0}} ). + +repetitive_sequence_has_only_guanosine_test() -> + ?assertEqual( nucleotide_count:dna("GGGGGGGG"), {{"A", 0}, {"T", 0}, {"C", 0}, {"G", 8}} ). + +counts_all_nucleotides_test() -> + ?assertEqual( nucleotide_count:dna("AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC"), + {{"A", 20}, {"T", 21}, {"C", 12}, {"G", 17}} ). diff --git a/phone-number/phone_test.erl b/phone-number/phone_test.erl new file mode 100644 index 00000000..4dbb49aa --- /dev/null +++ b/phone-number/phone_test.erl @@ -0,0 +1,29 @@ +% To run tests: +% elc *.erl +% erl -noshell -eval "eunit:test(phone, [verbose])" -s init stop +% +-module(phone_test). + +-include_lib("eunit/include/eunit.hrl"). + +cleans_number_test() -> + ?assertEqual(phone:number("(123) 456-7890"), "1234567890"). + +cleans_number_with_dots_test() -> + ?assertEqual(phone:number("123.456.7890"), "1234567890"). + +valid_when_eleven_digits_test() -> + ?assertEqual(phone:number("11234567890"), "1234567890"). + +invalid_when_eleven_digits_test() -> + ?assertEqual(phone:number("21234567890"), "0000000000"). + +invalid_when_nine_digits_test() -> + ?assertEqual(phone:number("123456789"), "0000000000"). + +area_code_test() -> + ?assertEqual(phone:areacode("1234567890"), "123"). + +pretty_print_test() -> + ?assertEqual(phone:pretty_print("1234567890"), "(123) 456-7890"), + ?assertEqual(phone:pretty_print("11234567890"), "(123) 456-7890"). diff --git a/phone-number/phone_tests.erl b/phone-number/phone_tests.erl index 3e7d9212..31d51fcf 100644 --- a/phone-number/phone_tests.erl +++ b/phone-number/phone_tests.erl @@ -2,7 +2,7 @@ % elc *.erl % erl -noshell -eval "eunit:test(phone, [verbose])" -s init stop % --module(phone_tests). +-module( phone_tests ). -include_lib("eunit/include/eunit.hrl"). diff --git a/point-mutations/dna.erl b/point-mutations/dna.erl deleted file mode 100644 index 57c5efe7..00000000 --- a/point-mutations/dna.erl +++ /dev/null @@ -1,6 +0,0 @@ --module(dna). - --export([hammingDistance/2]). - -hammingDistance(_, _) -> - 0. diff --git a/point-mutations/dna_tests.erl b/point-mutations/dna_tests.erl deleted file mode 100644 index c8133d33..00000000 --- a/point-mutations/dna_tests.erl +++ /dev/null @@ -1,3 +0,0 @@ --module(dna_tests). - --include_lib("eunit/include/eunit.hrl"). diff --git a/rna-transcription/example.erl b/rna-transcription/example.erl index 97d3c45f..0f7a4125 100644 --- a/rna-transcription/example.erl +++ b/rna-transcription/example.erl @@ -1,8 +1,9 @@ --module(dna). --export([to_rna/1]). +-module( rna_transcription ). +-export( [from_dna/1] ). + +from_dna( Strand ) -> lists:map( fun transcribe_to_rna/1, Strand ). + -to_rna(Strand) -> - lists:map(fun transcribe_to_rna/1, Strand). transcribe_to_rna($T) -> $U; diff --git a/rna-transcription/rna_transcription_test.erl b/rna-transcription/rna_transcription_test.erl deleted file mode 100644 index d015c973..00000000 --- a/rna-transcription/rna_transcription_test.erl +++ /dev/null @@ -1,20 +0,0 @@ --module(rna_transcription_test). --include_lib("eunit/include/eunit.hrl"). - -transcribes_cytidine_unchanged_test() -> - ?assertEqual("C", dna:to_rna("C")). - -transcribes_guanosine_unchanged_test() -> - ?assertEqual("G", dna:to_rna("G")). - -transcribes_adenosine_unchanged_test() -> - ?assertEqual("A", dna:to_rna("A")). - -transcribes_thymidine_to_uracil_test() -> - ?assertEqual("U", dna:to_rna("T")). - -transcribes_all_occurences_test() -> - ?assertEqual( - "ACGUGGUCUUAA", - dna:to_rna("ACGTGGTCTTAA") - ). diff --git a/rna-transcription/rna_transcription_tests.erl b/rna-transcription/rna_transcription_tests.erl new file mode 100644 index 00000000..19e3ae4f --- /dev/null +++ b/rna-transcription/rna_transcription_tests.erl @@ -0,0 +1,17 @@ +-module( rna_transcription_tests ). +-include_lib( "eunit/include/eunit.hrl" ). + +transcribes_cytidine_unchanged_test() -> + ?assertEqual( "C", rna_transcription:from_dna("C") ). + +transcribes_guanosine_unchanged_test() -> + ?assertEqual( "G", rna_transcription:from_dna("G") ). + +transcribes_adenosine_unchanged_test() -> + ?assertEqual("A", rna_transcription:from_dna("A") ). + +transcribes_thymidine_to_uracil_test() -> + ?assertEqual( "U", rna_transcription:from_dna("T") ). + +transcribes_all_occurences_test() -> + ?assertEqual( "ACGUGGUCUUAA", rna_transcription:from_dna("ACGTGGTCTTAA") ). diff --git a/robot-name/example.erl b/robot-name/example.erl new file mode 100644 index 00000000..0f3f509d --- /dev/null +++ b/robot-name/example.erl @@ -0,0 +1,31 @@ +-module( robot_name ). + +-export( [ask/1, create/0, reset/1] ). + +ask( Robot ) -> + Robot ! {name, erlang:self()}, + receive + {name, Answer} -> Answer + end. + +create() -> erlang:spawn( fun() -> loop( random_name() ) end ). + +reset( Robot ) -> Robot ! reset. + + + +loop( Name ) -> + receive + {name, Pid} -> + Pid ! {name, Name}, + loop( Name ); + reset -> loop( random_name() ) + end. + +random_name() -> + C1 = random:uniform( 25 ) - 1 + $A, + C2 = random:uniform( 25 ) - 1 + $A, + N1 = random:uniform( 10 ) - 1 + $0, + N2 = random:uniform( 10 ) - 1 + $0, + N3 = random:uniform( 10 ) - 1 + $0, + [C1, C2, N1, N2, N3]. diff --git a/robot-name/robot_name_tests.erl b/robot-name/robot_name_tests.erl new file mode 100644 index 00000000..7c874863 --- /dev/null +++ b/robot-name/robot_name_tests.erl @@ -0,0 +1,28 @@ +-module( robot_name_tests ). +-include_lib( "eunit/include/eunit.hrl" ). + +boot_test() -> + Robot = robot_name:create(), + Name = robot_name:ask( Robot ), + ?assert( erlang:length(Name) =:= 5 ), + [C1, C2, N1, N2, N3] = Name, + ?assert( is_robot_character(C1) ), + ?assert( is_robot_character(C2) ), + ?assert( is_robot_number(N1) ), + ?assert( is_robot_number(N2) ), + ?assert( is_robot_number(N3) ). + +reset_test() -> + Robot = robot_name:create(), + Name1 = robot_name:ask( Robot ), + robot_name:reset( Robot ), + Name2 = robot_name:ask( Robot ), + ?assert( Name1 =/= Name2 ). + + + +is_robot_character( C ) when C >= $A, C =< $Z -> true; +is_robot_character( _N ) -> false. + +is_robot_number( N ) when N >= $0, N =< $9 -> true; +is_robot_number( _N ) -> false. diff --git a/trinary/Makefile b/trinary/Makefile deleted file mode 100644 index 3dc88157..00000000 --- a/trinary/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -SRC=$(wildcard *.erl) - -compile: $(SRC) - @erlc -pa . $(SRC) - -clean: - @$(RM) -r *.beam - -test: clean compile - @erl -pa . -eval 'eunit:test(trinary_tests), init:stop().' diff --git a/trinary/example.erl b/trinary/example.erl index 324ab7a2..7b87c5d8 100644 --- a/trinary/example.erl +++ b/trinary/example.erl @@ -1,64 +1,13 @@ --module(example). --export([to_decimal/1]). --define(BASE, 3). +-module( trinary ). -%% -%% trinary/ternary (base 3) to decimal (base 10) -%% +-export( [to_decimal/1] ). -to_decimal(StringNumeric) -> - % numeric character list indexed by position - IndexedList = list_index(numeric_or(StringNumeric, "")), +to_decimal( String ) -> + try + erlang:list_to_integer( String, 3 ) - % tokenize string into a list of numeric characters - Tokens = lists:foldl(fun accumulate/2, [], IndexedList), + catch + _:_ -> 0 - % integer sum - round(lists:sum(Tokens)). - -%% -%% if string is all numeric, return it; otherwise, return given default -%% - -numeric_or(StringNumeric, Or) -> case re:run(StringNumeric, "^[0-9]+$") of - {match, _} -> StringNumeric; - nomatch -> Or -end. - -%% -%% builds a numeric character list indexed by position (i.e. [{Num, Index}, ...]) -%% - -list_index(StringNumeric) -> - {Tuples, _} = lists:mapfoldr(fun index_accumulator/2, 0, StringNumeric), Tuples. - -%% -%% Iterator to build tuples like `{Item, Index}` which correspond -%% to each item and its position in a list. -%% -%% element 1: numeric character -%% element 2: posision in the list (zero based) -- increase by one for each iteration -%% - -index_accumulator(Item, Index) -> {{Item, Index}, Index + 1}. - -%% -%% accumulate list values -%% - -accumulate(T, Sum) -> - % destructure tuple into local vars - {Digit, Index} = T, - - % cast binary into integer - Integer = binary_to_integer(<>), - - % append list to complete accumulation - Sum ++ [trinary(Integer, Index)]. - -%% -%% trinary algorithm (apply to each numeric character) -%% - -trinary(Integer, Index) -> Integer * math:pow(?BASE, Index). + end. diff --git a/trinary/trinary_tests.erl b/trinary/trinary_tests.erl index ba27ab42..56e0a45a 100644 --- a/trinary/trinary_tests.erl +++ b/trinary/trinary_tests.erl @@ -1,34 +1,32 @@ --module(trinary_tests). --import(example, [to_decimal/1]). --include_lib("eunit/include/eunit.hrl"). +-module( trinary_tests ). +-include_lib( "eunit/include/eunit.hrl" ). trinary_1_is_decimal_1_test() -> - ?assertEqual(1, example:to_decimal("1")). + ?assertEqual( 1, trinary:to_decimal("1") ). -%% trinary_2_is_decimal_2_test() -> -%% ?assertEqual(2, example:to_decimal("2")). +trinary_2_is_decimal_2_test() -> + ?assertEqual( 2, trinary:to_decimal("2") ). -%% trinary_10_is_decimal_3_test() -> -%% ?assertEqual(3, example:to_decimal("10")). +trinary_10_is_decimal_3_test() -> + ?assertEqual( 3, trinary:to_decimal("10") ). -%% trinary_11_is_decimal_4_test() -> -%% ?assertEqual(4, example:to_decimal("11")). +trinary_11_is_decimal_4_test() -> + ?assertEqual( 4, trinary:to_decimal("11") ). -%% trinary_100_is_decimal_9_test() -> -%% ?assertEqual(9, example:to_decimal("100")). +trinary_100_is_decimal_9_test() -> + ?assertEqual( 9, trinary:to_decimal("100") ). -%% trinary_112_is_decimal_14_test() -> -%% ?assertEqual(14, example:to_decimal("112")). +trinary_112_is_decimal_14_test() -> + ?assertEqual( 14, trinary:to_decimal("112") ). -%% trinary_222_is_decimal_26_test() -> -%% ?assertEqual(26, example:to_decimal("222")). +trinary_222_is_decimal_26_test() -> + ?assertEqual( 26, trinary:to_decimal("222") ). -%% trinary_1120_is_decimal_42_test() -> -%% ?assertEqual(42, example:to_decimal("1120")). +trinary_1120_is_decimal_42_test() -> + ?assertEqual( 42, trinary:to_decimal("1120") ). -%% trinary_1122000120_is_decimal_32091_test() -> -%% ?assertEqual(32091, example:to_decimal("1122000120")). - -%% invalid_trinary_is_decimal_0_test() -> -%% ?assertEqual(0, example:to_decimal("carrot")). +trinary_1122000120_is_decimal_32091_test() -> + ?assertEqual( 32091, trinary:to_decimal("1122000120") ). +invalid_trinary_is_decimal_0_test() -> + ?assertEqual( 0, trinary:to_decimal("carrot") ). diff --git a/word-count/word_count_tests.erl b/word-count/word_count_tests.erl new file mode 100644 index 00000000..73fd98c3 --- /dev/null +++ b/word-count/word_count_tests.erl @@ -0,0 +1,66 @@ +-module( word_count_tests ). +-include_lib("eunit/include/eunit.hrl"). + +%% dict should be used to implement wound_count:count/1. + +count_one_word_test() -> + assert_count( + "word", + [{"word", 1}]). + +count_one_of_each_test() -> + assert_count( + "one of each", + [{"one", 1}, + {"of", 1}, + {"each", 1}]). + +count_multiple_occurrences_test() -> + assert_count( + "one fish two fish red fish blue fish", + [{"one", 1}, + {"two", 1}, + {"fish", 4}, + {"red", 1}, + {"blue", 1}]). + +ignore_punctuation_test() -> + assert_count( + "car : carpet as java : javascript!!&@$%^&", + [{"car", 1}, + {"carpet", 1}, + {"as", 1}, + {"java", 1}, + {"javascript", 1}]). + +include_numbers_test() -> + assert_count( + "testing, 1, 2 testing", + [{"testing", 2}, + {"1", 1}, + {"2", 1}]). + +normalize_case_test() -> + assert_count( + "go Go GO", + [{"go", 3}]). + +prefix_punctuation_test() -> + assert_count( + "!%%#testing, 1, 2 testing", + [{"testing", 2}, + {"1", 1}, + {"2", 1}]). + +symbols_are_separators_test() -> + assert_count( + "hey,my_spacebar_is_broken.", + [{"hey", 1}, + {"my", 1}, + {"spacebar", 1}, + {"is", 1}, + {"broken", 1}]). + +assert_count(S, Expect) -> + ?assertEqual(orddict:from_list(dict:to_list(word_count:count(S))), + orddict:from_list(Expect)).