From 73ac5d1407a84e06c0c22ff31748d06aa74d3c99 Mon Sep 17 00:00:00 2001 From: Emmanuel Delaborde Date: Thu, 3 Oct 2019 11:05:33 +1300 Subject: [PATCH 1/5] implement exercise binary-search-tree --- config.json | 12 ++ exercises/binary-search-tree/README.md | 60 ++++++++++ exercises/binary-search-tree/rebar.config | 30 +++++ .../src/binary_search_tree.app.src | 9 ++ .../src/binary_search_tree.erl | 21 ++++ exercises/binary-search-tree/src/example.erl | 18 +++ .../test/binary_search_tree_tests.erl | 112 ++++++++++++++++++ 7 files changed, 262 insertions(+) create mode 100644 exercises/binary-search-tree/README.md create mode 100644 exercises/binary-search-tree/rebar.config create mode 100644 exercises/binary-search-tree/src/binary_search_tree.app.src create mode 100644 exercises/binary-search-tree/src/binary_search_tree.erl create mode 100644 exercises/binary-search-tree/src/example.erl create mode 100644 exercises/binary-search-tree/test/binary_search_tree_tests.erl diff --git a/config.json b/config.json index cb0f173b..cc3fccc0 100644 --- a/config.json +++ b/config.json @@ -809,6 +809,18 @@ "topics": [ "lists" ] + }, + { + "slug": "binary-search-tree", + "uuid": "a8f7f17e-567b-43ec-9ee5-6288367f0ae4", + "core": false, + "unlocked_by": null, + "difficulty": 3, + "topics": [ + "recursion", + "searching", + "trees" + ] } ] } diff --git a/exercises/binary-search-tree/README.md b/exercises/binary-search-tree/README.md new file mode 100644 index 00000000..01d4572a --- /dev/null +++ b/exercises/binary-search-tree/README.md @@ -0,0 +1,60 @@ +# Binary Search Tree + +Insert and search for numbers in a binary tree. + +When we need to represent sorted data, an array does not make a good +data structure. + +Say we have the array `[1, 3, 4, 5]`, and we add 2 to it so it becomes +`[1, 3, 4, 5, 2]` now we must sort the entire array again! We can +improve on this by realizing that we only need to make space for the new +item `[1, nil, 3, 4, 5]`, and then adding the item in the space we +added. But this still requires us to shift many elements down by one. + +Binary Search Trees, however, can operate on sorted data much more +efficiently. + +A binary search tree consists of a series of connected nodes. Each node +contains a piece of data (e.g. the number 3), a variable named `left`, +and a variable named `right`. The `left` and `right` variables point at +`nil`, or other nodes. Since these other nodes in turn have other nodes +beneath them, we say that the left and right variables are pointing at +subtrees. All data in the left subtree is less than or equal to the +current node's data, and all data in the right subtree is greater than +the current node's data. + +For example, if we had a node containing the data 4, and we added the +data 2, our tree would look like this: + + 4 + / + 2 + +If we then added 6, it would look like this: + + 4 + / \ + 2 6 + +If we then added 3, it would look like this + + 4 + / \ + 2 6 + \ + 3 + +And if we then added 1, 5, and 7, it would look like this + + 4 + / \ + / \ + 2 6 + / \ / \ + 1 3 5 7 +## Source + +Josh Cheek [https://twitter.com/josh_cheek](https://twitter.com/josh_cheek) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. \ No newline at end of file diff --git a/exercises/binary-search-tree/rebar.config b/exercises/binary-search-tree/rebar.config new file mode 100644 index 00000000..db5d9076 --- /dev/null +++ b/exercises/binary-search-tree/rebar.config @@ -0,0 +1,30 @@ +%% Erlang compiler options +{erl_opts, [debug_info, warnings_as_errors]}. + +{deps, [{erl_exercism, "0.1.2"}]}. + +{dialyzer, [ + {warnings, [underspecs, no_return]}, + {get_warnings, true}, + {plt_apps, top_level_deps}, % top_level_deps | all_deps + {plt_extra_apps, []}, + {plt_location, local}, % local | "/my/file/name" + {plt_prefix, "rebar3"}, + {base_plt_apps, [stdlib, kernel, crypto]}, + {base_plt_location, global}, % global | "/my/file/name" + {base_plt_prefix, "rebar3"} +]}. + +%% eunit:test(Tests) +{eunit_tests, []}. +%% Options for eunit:test(Tests, Opts) +{eunit_opts, [verbose]}. + +%% == xref == + +{xref_warnings, true}. + +%% xref checks to run +{xref_checks, [undefined_function_calls, undefined_functions, + locals_not_used, exports_not_used, + deprecated_function_calls, deprecated_functions]}. diff --git a/exercises/binary-search-tree/src/binary_search_tree.app.src b/exercises/binary-search-tree/src/binary_search_tree.app.src new file mode 100644 index 00000000..3abdf481 --- /dev/null +++ b/exercises/binary-search-tree/src/binary_search_tree.app.src @@ -0,0 +1,9 @@ +{application, binary_search_tree, + [{description, "exercism.io - binary-search-tree"}, + {vsn, "0.0.1"}, + {modules, []}, + {registered, []}, + {applications, [kernel, + stdlib]}, + {env, []} + ]}. \ No newline at end of file diff --git a/exercises/binary-search-tree/src/binary_search_tree.erl b/exercises/binary-search-tree/src/binary_search_tree.erl new file mode 100644 index 00000000..71df5350 --- /dev/null +++ b/exercises/binary-search-tree/src/binary_search_tree.erl @@ -0,0 +1,21 @@ +-module(binary_search_tree). + +-export([empty/0, value/1, left/1, right/1, insert/2, to_list/1]). + +%% empty tree +empty() -> undefined. + +%% value at the top of _BST +value(_BST) -> undefined. + +%% left subtree +left(_BST) -> undefined. + +%% right subtree +right(_BST) -> undefined. + +%% insert _Value into _BST +insert(_BST, _Value) -> undefined. + +%% convert _BST to a sorted list +to_list(_BST) -> undefined. \ No newline at end of file diff --git a/exercises/binary-search-tree/src/example.erl b/exercises/binary-search-tree/src/example.erl new file mode 100644 index 00000000..56808450 --- /dev/null +++ b/exercises/binary-search-tree/src/example.erl @@ -0,0 +1,18 @@ +-module(example). + +-export([empty/0, value/1, left/1, right/1, insert/2, to_list/1]). + +empty() -> empty. + +value({V,_,_}) -> V. + +left({_, L,_}) -> L. + +right({_, _, R}) -> R. + +insert(empty, V) -> {V, empty, empty}; +insert({V1, L, R}, V2) when V1 < V2 -> {V1, L, insert(R, V2)}; +insert({V1, L, R}, V2) when V1 >= V2 -> {V1, insert(L, V2), R}. + +to_list(empty) -> []; +to_list({V, L, R}) -> to_list(L) ++ [V] ++ to_list(R). \ No newline at end of file diff --git a/exercises/binary-search-tree/test/binary_search_tree_tests.erl b/exercises/binary-search-tree/test/binary_search_tree_tests.erl new file mode 100644 index 00000000..b581eca6 --- /dev/null +++ b/exercises/binary-search-tree/test/binary_search_tree_tests.erl @@ -0,0 +1,112 @@ +%% Based on canonical data version 1.4.0 +%% https://github.com/exercism/problem-specifications/raw/master/exercises/bob/canonical-data.json +%% This file is automatically generated from the exercises canonical data. + +-module(binary_search_tree_tests). + +-include_lib("erl_exercism/include/exercism.hrl"). +-include_lib("eunit/include/eunit.hrl"). + +'1_data_is_retained_test'() -> + T = binary_search_tree:insert(binary_search_tree:empty(), 4), + ?assertMatch(4, binary_search_tree:value(T)). + +'2_smaller_number_at_left_node_test'() -> + T = binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:empty(), 4), + 2), + ?assertMatch(4, binary_search_tree:value(T)), + ?assertMatch(2, binary_search_tree:value(binary_search_tree:left(T))). + +'3_same number_at_left_node_test'() -> + T = binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:empty(), 4), + 4), + ?assertMatch(4, binary_search_tree:value(T)), + ?assertMatch(4, binary_search_tree:value(binary_search_tree:left(T))). + +'4_greater_number_at_right_node_test'() -> + T = binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:empty(), 4), + 5), + ?assertMatch(4, binary_search_tree:value(T)), + ?assertMatch(5, binary_search_tree:value(binary_search_tree:right(T))). + +'5_can_create_complex_tree_test'() -> + T = binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:empty(), + 4), + 2), + 6), + 1), + 3), + 5), + 7), + ?assertMatch(4, binary_search_tree:value(T)), + ?assertMatch(2, binary_search_tree:value(binary_search_tree:left(T))), + ?assertMatch(1, binary_search_tree:value( + binary_search_tree:left( + binary_search_tree:left(T)))), + ?assertMatch(3, binary_search_tree:value( + binary_search_tree:right( + binary_search_tree:left(T)))), + ?assertMatch(6, binary_search_tree:value(binary_search_tree:right(T))), + ?assertMatch(5, binary_search_tree:value( + binary_search_tree:left( + binary_search_tree:right(T)))), + ?assertMatch(7, binary_search_tree:value( + binary_search_tree:right( + binary_search_tree:right(T)))). + +'6_can_sort_single_number_test'() -> + T = binary_search_tree:insert(binary_search_tree:empty(), 2), + ?assertMatch([2], binary_search_tree:to_list(T)). + +'7_can_sort_if_second_number_is_smaller_than_first_test'() -> + T = binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:empty(), + 2), + 1), + ?assertMatch([1, 2], binary_search_tree:to_list(T)). + +'8_can_sort_if_second_number_is_same_as_first_test'() -> + T = binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:empty(), + 2), + 2), + ?assertMatch([2, 2], binary_search_tree:to_list(T)). + +'9_can_sort_if_second_number_is_greater_than_first_test'() -> + T = binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:empty(), + 2), + 3), + ?assertMatch([2, 3], binary_search_tree:to_list(T)). + +'10_can_sort_complex_tree_test'() -> + T = binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:insert( + binary_search_tree:empty(), + 2), + 1), + 3), + 6), + 7), + 5), + ?assertMatch([1, 2, 3, 5, 6, 7], binary_search_tree:to_list(T)). \ No newline at end of file From 63c61b10a58dd33b844537eb3e941b79365248ac Mon Sep 17 00:00:00 2001 From: Emmanuel Delaborde Date: Fri, 11 Oct 2019 11:00:13 +1300 Subject: [PATCH 2/5] implementation of binary-search-tree exercise --- config.json | 14 ++- exercises/binary-search-tree/README.md | 60 +++++++++++ exercises/binary-search-tree/rebar.config | 30 ++++++ .../src/binary_search_tree.app.src | 9 ++ .../src/binary_search_tree.erl | 21 ++++ exercises/binary-search-tree/src/example.erl | 18 ++++ .../test/binary_search_tree_tests.erl | 101 ++++++++++++++++++ 7 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 exercises/binary-search-tree/README.md create mode 100644 exercises/binary-search-tree/rebar.config create mode 100644 exercises/binary-search-tree/src/binary_search_tree.app.src create mode 100644 exercises/binary-search-tree/src/binary_search_tree.erl create mode 100644 exercises/binary-search-tree/src/example.erl create mode 100644 exercises/binary-search-tree/test/binary_search_tree_tests.erl diff --git a/config.json b/config.json index 45d681ab..f8e2c94d 100644 --- a/config.json +++ b/config.json @@ -841,6 +841,18 @@ "lists", "recursion" ] + }, + { + "slug": "binary-search-tree", + "uuid": "a8f7f17e-567b-43ec-9ee5-6288367f0ae4", + "core": false, + "unlocked_by": "strain", + "difficulty": 3, + "topics": [ + "recursion", + "searching", + "trees" + ] } ] -} +} \ No newline at end of file diff --git a/exercises/binary-search-tree/README.md b/exercises/binary-search-tree/README.md new file mode 100644 index 00000000..01d4572a --- /dev/null +++ b/exercises/binary-search-tree/README.md @@ -0,0 +1,60 @@ +# Binary Search Tree + +Insert and search for numbers in a binary tree. + +When we need to represent sorted data, an array does not make a good +data structure. + +Say we have the array `[1, 3, 4, 5]`, and we add 2 to it so it becomes +`[1, 3, 4, 5, 2]` now we must sort the entire array again! We can +improve on this by realizing that we only need to make space for the new +item `[1, nil, 3, 4, 5]`, and then adding the item in the space we +added. But this still requires us to shift many elements down by one. + +Binary Search Trees, however, can operate on sorted data much more +efficiently. + +A binary search tree consists of a series of connected nodes. Each node +contains a piece of data (e.g. the number 3), a variable named `left`, +and a variable named `right`. The `left` and `right` variables point at +`nil`, or other nodes. Since these other nodes in turn have other nodes +beneath them, we say that the left and right variables are pointing at +subtrees. All data in the left subtree is less than or equal to the +current node's data, and all data in the right subtree is greater than +the current node's data. + +For example, if we had a node containing the data 4, and we added the +data 2, our tree would look like this: + + 4 + / + 2 + +If we then added 6, it would look like this: + + 4 + / \ + 2 6 + +If we then added 3, it would look like this + + 4 + / \ + 2 6 + \ + 3 + +And if we then added 1, 5, and 7, it would look like this + + 4 + / \ + / \ + 2 6 + / \ / \ + 1 3 5 7 +## Source + +Josh Cheek [https://twitter.com/josh_cheek](https://twitter.com/josh_cheek) + +## Submitting Incomplete Solutions +It's possible to submit an incomplete solution so you can see how others have completed the exercise. \ No newline at end of file diff --git a/exercises/binary-search-tree/rebar.config b/exercises/binary-search-tree/rebar.config new file mode 100644 index 00000000..db5d9076 --- /dev/null +++ b/exercises/binary-search-tree/rebar.config @@ -0,0 +1,30 @@ +%% Erlang compiler options +{erl_opts, [debug_info, warnings_as_errors]}. + +{deps, [{erl_exercism, "0.1.2"}]}. + +{dialyzer, [ + {warnings, [underspecs, no_return]}, + {get_warnings, true}, + {plt_apps, top_level_deps}, % top_level_deps | all_deps + {plt_extra_apps, []}, + {plt_location, local}, % local | "/my/file/name" + {plt_prefix, "rebar3"}, + {base_plt_apps, [stdlib, kernel, crypto]}, + {base_plt_location, global}, % global | "/my/file/name" + {base_plt_prefix, "rebar3"} +]}. + +%% eunit:test(Tests) +{eunit_tests, []}. +%% Options for eunit:test(Tests, Opts) +{eunit_opts, [verbose]}. + +%% == xref == + +{xref_warnings, true}. + +%% xref checks to run +{xref_checks, [undefined_function_calls, undefined_functions, + locals_not_used, exports_not_used, + deprecated_function_calls, deprecated_functions]}. diff --git a/exercises/binary-search-tree/src/binary_search_tree.app.src b/exercises/binary-search-tree/src/binary_search_tree.app.src new file mode 100644 index 00000000..3abdf481 --- /dev/null +++ b/exercises/binary-search-tree/src/binary_search_tree.app.src @@ -0,0 +1,9 @@ +{application, binary_search_tree, + [{description, "exercism.io - binary-search-tree"}, + {vsn, "0.0.1"}, + {modules, []}, + {registered, []}, + {applications, [kernel, + stdlib]}, + {env, []} + ]}. \ No newline at end of file diff --git a/exercises/binary-search-tree/src/binary_search_tree.erl b/exercises/binary-search-tree/src/binary_search_tree.erl new file mode 100644 index 00000000..71df5350 --- /dev/null +++ b/exercises/binary-search-tree/src/binary_search_tree.erl @@ -0,0 +1,21 @@ +-module(binary_search_tree). + +-export([empty/0, value/1, left/1, right/1, insert/2, to_list/1]). + +%% empty tree +empty() -> undefined. + +%% value at the top of _BST +value(_BST) -> undefined. + +%% left subtree +left(_BST) -> undefined. + +%% right subtree +right(_BST) -> undefined. + +%% insert _Value into _BST +insert(_BST, _Value) -> undefined. + +%% convert _BST to a sorted list +to_list(_BST) -> undefined. \ No newline at end of file diff --git a/exercises/binary-search-tree/src/example.erl b/exercises/binary-search-tree/src/example.erl new file mode 100644 index 00000000..56808450 --- /dev/null +++ b/exercises/binary-search-tree/src/example.erl @@ -0,0 +1,18 @@ +-module(example). + +-export([empty/0, value/1, left/1, right/1, insert/2, to_list/1]). + +empty() -> empty. + +value({V,_,_}) -> V. + +left({_, L,_}) -> L. + +right({_, _, R}) -> R. + +insert(empty, V) -> {V, empty, empty}; +insert({V1, L, R}, V2) when V1 < V2 -> {V1, L, insert(R, V2)}; +insert({V1, L, R}, V2) when V1 >= V2 -> {V1, insert(L, V2), R}. + +to_list(empty) -> []; +to_list({V, L, R}) -> to_list(L) ++ [V] ++ to_list(R). \ No newline at end of file diff --git a/exercises/binary-search-tree/test/binary_search_tree_tests.erl b/exercises/binary-search-tree/test/binary_search_tree_tests.erl new file mode 100644 index 00000000..0bdaabc3 --- /dev/null +++ b/exercises/binary-search-tree/test/binary_search_tree_tests.erl @@ -0,0 +1,101 @@ +-module(binary_search_tree_tests). + +-include_lib("erl_exercism/include/exercism.hrl"). + +-include_lib("eunit/include/eunit.hrl"). + +'1_data_is_retained_test'() -> + T = + binary_search_tree:insert(binary_search_tree:empty(), + 4), + ?assertMatch(4, (binary_search_tree:value(T))). + +'2_smaller_number_at_left_node_test'() -> + T = + binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:empty(), + 4), + 2), + ?assertMatch(4, (binary_search_tree:value(T))), + ?assertMatch(2, + (binary_search_tree:value(binary_search_tree:left(T)))). + +'3_same number_at_left_node_test'() -> + T = + binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:empty(), + 4), + 4), + ?assertMatch(4, (binary_search_tree:value(T))), + ?assertMatch(4, + (binary_search_tree:value(binary_search_tree:left(T)))). + +'4_greater_number_at_right_node_test'() -> + T = + binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:empty(), + 4), + 5), + ?assertMatch(4, (binary_search_tree:value(T))), + ?assertMatch(5, + (binary_search_tree:value(binary_search_tree:right(T)))). + +'5_can_create_complex_tree_test'() -> + T = + binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:empty(), + 4), + 2), + 6), + 1), + 3), + 5), + 7), + ?assertMatch(4, (binary_search_tree:value(T))), + ?assertMatch(2, + (binary_search_tree:value(binary_search_tree:left(T)))), + ?assertMatch(1, + (binary_search_tree:value(binary_search_tree:left(binary_search_tree:left(T))))), + ?assertMatch(3, + (binary_search_tree:value(binary_search_tree:right(binary_search_tree:left(T))))), + ?assertMatch(6, + (binary_search_tree:value(binary_search_tree:right(T)))), + ?assertMatch(5, + (binary_search_tree:value(binary_search_tree:left(binary_search_tree:right(T))))), + ?assertMatch(7, + (binary_search_tree:value(binary_search_tree:right(binary_search_tree:right(T))))). + +'6_can_sort_single_number_test'() -> + T = + binary_search_tree:insert(binary_search_tree:empty(), + 2), + ?assertMatch([2], (binary_search_tree:to_list(T))). + +'7_can_sort_if_second_number_is_smaller_than_first_test'() -> + T = + binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:empty(), + 2), + 1), + ?assertMatch([1, 2], (binary_search_tree:to_list(T))). + +'8_can_sort_if_second_number_is_same_as_first_test'() -> + T = + binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:empty(), + 2), + 2), + ?assertMatch([2, 2], (binary_search_tree:to_list(T))). + +'9_can_sort_if_second_number_is_greater_than_first_test'() -> + T = + binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:empty(), + 2), + 3), + ?assertMatch([2, 3], (binary_search_tree:to_list(T))). + +'10_can_sort_complex_tree_test'() -> + T = + binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:insert(binary_search_tree:empty(), + 2), + 1), + 3), + 6), + 7), + 5), + ?assertMatch([1, 2, 3, 5, 6, 7], + (binary_search_tree:to_list(T))). From 432e2bd474e45942f76113ff5b3f4426165a4840 Mon Sep 17 00:00:00 2001 From: voila Date: Fri, 11 Oct 2019 11:14:53 +1300 Subject: [PATCH 3/5] Update config.json --- config.json | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/config.json b/config.json index 8fe4f868..eb79337a 100644 --- a/config.json +++ b/config.json @@ -830,8 +830,7 @@ "lists" ] }, - { -<<<<<<< HEAD + "slug": "simple-linked-list", "uuid": "56a794de-40ee-4ff2-a1dd-f9b83f62d4b0", "core": false, @@ -848,12 +847,6 @@ "uuid": "a8f7f17e-567b-43ec-9ee5-6288367f0ae4", "core": false, "unlocked_by": "strain", -======= - "slug": "binary-search-tree", - "uuid": "a8f7f17e-567b-43ec-9ee5-6288367f0ae4", - "core": false, - "unlocked_by": null, ->>>>>>> 73ac5d1407a84e06c0c22ff31748d06aa74d3c99 "difficulty": 3, "topics": [ "recursion", @@ -862,4 +855,4 @@ ] } ] -} \ No newline at end of file +} From 5f2f4a3e2f24bb02936effe7f69ce60c4be8bb53 Mon Sep 17 00:00:00 2001 From: Emmanuel Delaborde Date: Fri, 11 Oct 2019 11:20:03 +1300 Subject: [PATCH 4/5] fix config.json --- config.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/config.json b/config.json index eb79337a..d2c7fb05 100644 --- a/config.json +++ b/config.json @@ -26,8 +26,8 @@ "unlocked_by": null, "difficulty": 1, "topics": [ - "strings", - "arity" + "arity", + "strings" ] }, { @@ -830,7 +830,7 @@ "lists" ] }, - + { "slug": "simple-linked-list", "uuid": "56a794de-40ee-4ff2-a1dd-f9b83f62d4b0", "core": false, @@ -855,4 +855,4 @@ ] } ] -} +} \ No newline at end of file From d7e79b87f8f335bf08a4325b786e9ae5b259b5df Mon Sep 17 00:00:00 2001 From: Emmanuel Delaborde Date: Sat, 12 Oct 2019 17:59:52 +1300 Subject: [PATCH 5/5] fix indentation in tests, and other minot fixes --- config.json | 2 +- exercises/binary-search-tree/README.md | 26 +++- .../src/binary_search_tree.app.src | 4 +- .../src/binary_search_tree.erl | 12 +- exercises/binary-search-tree/src/example.erl | 8 +- .../test/binary_search_tree_tests.erl | 138 +++++++----------- 6 files changed, 94 insertions(+), 96 deletions(-) diff --git a/config.json b/config.json index d2c7fb05..77eb083f 100644 --- a/config.json +++ b/config.json @@ -855,4 +855,4 @@ ] } ] -} \ No newline at end of file +} diff --git a/exercises/binary-search-tree/README.md b/exercises/binary-search-tree/README.md index 01d4572a..0e5531b5 100644 --- a/exercises/binary-search-tree/README.md +++ b/exercises/binary-search-tree/README.md @@ -52,9 +52,33 @@ And if we then added 1, 5, and 7, it would look like this 2 6 / \ / \ 1 3 5 7 + +## Running tests + +In order to run the tests, issue the following command from the exercise +directory: + +For running the tests provided, `rebar3` is used as it is the official build and +dependency management tool for erlang now. Please refer to [the tracks installation +instructions](http://exercism.io/languages/erlang/installation) on how to do that. + +In order to run the tests, you can issue the following command from the exercise +directory. + +```bash +$ rebar3 eunit +``` + +## Questions? + +For detailed information about the Erlang track, please refer to the +[help page](http://exercism.io/languages/erlang) on the Exercism site. +This covers the basic information on setting up the development +environment expected by the exercises. + ## Source Josh Cheek [https://twitter.com/josh_cheek](https://twitter.com/josh_cheek) ## Submitting Incomplete Solutions -It's possible to submit an incomplete solution so you can see how others have completed the exercise. \ No newline at end of file +It's possible to submit an incomplete solution so you can see how others have completed the exercise. diff --git a/exercises/binary-search-tree/src/binary_search_tree.app.src b/exercises/binary-search-tree/src/binary_search_tree.app.src index 3abdf481..73eb2f6e 100644 --- a/exercises/binary-search-tree/src/binary_search_tree.app.src +++ b/exercises/binary-search-tree/src/binary_search_tree.app.src @@ -1,9 +1,9 @@ {application, binary_search_tree, [{description, "exercism.io - binary-search-tree"}, - {vsn, "0.0.1"}, + {vsn, "1.0.0"}, {modules, []}, {registered, []}, {applications, [kernel, stdlib]}, {env, []} - ]}. \ No newline at end of file + ]}. diff --git a/exercises/binary-search-tree/src/binary_search_tree.erl b/exercises/binary-search-tree/src/binary_search_tree.erl index 71df5350..08d23b35 100644 --- a/exercises/binary-search-tree/src/binary_search_tree.erl +++ b/exercises/binary-search-tree/src/binary_search_tree.erl @@ -1,12 +1,12 @@ -module(binary_search_tree). - --export([empty/0, value/1, left/1, right/1, insert/2, to_list/1]). + +-export([empty/0, data/1, left/1, right/1, insert/2, sorted_data/1]). %% empty tree empty() -> undefined. -%% value at the top of _BST -value(_BST) -> undefined. +%% data at the top of _BST +data(_BST) -> undefined. %% left subtree left(_BST) -> undefined. @@ -18,4 +18,6 @@ right(_BST) -> undefined. insert(_BST, _Value) -> undefined. %% convert _BST to a sorted list -to_list(_BST) -> undefined. \ No newline at end of file +sorted_data(_BST) -> undefined. + + diff --git a/exercises/binary-search-tree/src/example.erl b/exercises/binary-search-tree/src/example.erl index 56808450..1d104fb5 100644 --- a/exercises/binary-search-tree/src/example.erl +++ b/exercises/binary-search-tree/src/example.erl @@ -1,10 +1,10 @@ -module(example). --export([empty/0, value/1, left/1, right/1, insert/2, to_list/1]). +-export([empty/0, data/1, left/1, right/1, insert/2, sorted_data/1]). empty() -> empty. -value({V,_,_}) -> V. +data({V,_,_}) -> V. left({_, L,_}) -> L. @@ -14,5 +14,5 @@ insert(empty, V) -> {V, empty, empty}; insert({V1, L, R}, V2) when V1 < V2 -> {V1, L, insert(R, V2)}; insert({V1, L, R}, V2) when V1 >= V2 -> {V1, insert(L, V2), R}. -to_list(empty) -> []; -to_list({V, L, R}) -> to_list(L) ++ [V] ++ to_list(R). \ No newline at end of file +sorted_data(empty) -> []; +sorted_data({V, L, R}) -> sorted_data(L) ++ [V] ++ sorted_data(R). diff --git a/exercises/binary-search-tree/test/binary_search_tree_tests.erl b/exercises/binary-search-tree/test/binary_search_tree_tests.erl index 00f58ba4..b22e2f16 100644 --- a/exercises/binary-search-tree/test/binary_search_tree_tests.erl +++ b/exercises/binary-search-tree/test/binary_search_tree_tests.erl @@ -1,3 +1,5 @@ +%% These tests were manually created from canonical data, version 1.0.0 +%% (https://github.com/exercism/problem-specifications/blob/d5a4db7d282b16110e376f0ccfa91c80967b8b40/exercises/binary-search-tree/canonical-data.json) -module(binary_search_tree_tests). -include_lib("erl_exercism/include/exercism.hrl"). @@ -5,104 +7,74 @@ '1_data_is_retained_test'() -> T = binary_search_tree:insert(binary_search_tree:empty(), 4), - ?assertMatch(4, binary_search_tree:value(T)). + ?assertMatch(4, binary_search_tree:data(T)). -'2_smaller_number_at_left_node_test'() -> - T = binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:empty(), 4), - 2), - ?assertMatch(4, binary_search_tree:value(T)), - ?assertMatch(2, binary_search_tree:value(binary_search_tree:left(T))). +'2_smaller_number_at_left_node_test'() -> + T0 = binary_search_tree:empty(), + T1 = binary_search_tree:insert(T0, 4), + T2 = binary_search_tree:insert(T1, 2), + ?assertMatch(4, binary_search_tree:data(T2)), + ?assertMatch(2, binary_search_tree:data(binary_search_tree:left(T2))). '3_same number_at_left_node_test'() -> - T = binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:empty(), 4), - 4), - ?assertMatch(4, binary_search_tree:value(T)), - ?assertMatch(4, binary_search_tree:value(binary_search_tree:left(T))). + T0 = binary_search_tree:empty(), + T1 = binary_search_tree:insert(T0, 4), + T2 = binary_search_tree:insert(T1, 4), + ?assertMatch(4, binary_search_tree:data(T2)), + ?assertMatch(4, binary_search_tree:data(binary_search_tree:left(T2))). '4_greater_number_at_right_node_test'() -> - T = binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:empty(), 4), - 5), - ?assertMatch(4, binary_search_tree:value(T)), - ?assertMatch(5, binary_search_tree:value(binary_search_tree:right(T))). + T0 = binary_search_tree:empty(), + T1 = binary_search_tree:insert(T0, 4), + T2 = binary_search_tree:insert(T1, 5), + ?assertMatch(4, binary_search_tree:data(T2)), + ?assertMatch(5, binary_search_tree:data(binary_search_tree:right(T2))). '5_can_create_complex_tree_test'() -> - T = binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:empty(), - 4), - 2), - 6), - 1), - 3), - 5), - 7), - ?assertMatch(4, binary_search_tree:value(T)), - ?assertMatch(2, binary_search_tree:value(binary_search_tree:left(T))), - ?assertMatch(1, binary_search_tree:value( - binary_search_tree:left( - binary_search_tree:left(T)))), - ?assertMatch(3, binary_search_tree:value( - binary_search_tree:right( - binary_search_tree:left(T)))), - ?assertMatch(6, binary_search_tree:value(binary_search_tree:right(T))), - ?assertMatch(5, binary_search_tree:value( - binary_search_tree:left( - binary_search_tree:right(T)))), - ?assertMatch(7, binary_search_tree:value( - binary_search_tree:right( - binary_search_tree:right(T)))). + T0 = binary_search_tree:empty(), + T1 = binary_search_tree:insert(T0, 4), + T2 = binary_search_tree:insert(T1, 2), + T3 = binary_search_tree:insert(T2, 6), + T4 = binary_search_tree:insert(T3, 1), + T5 = binary_search_tree:insert(T4, 3), + T6 = binary_search_tree:insert(T5, 5), + T7 = binary_search_tree:insert(T6, 7), + ?assertMatch(4, binary_search_tree:data(T7)), + ?assertMatch(2, binary_search_tree:data(binary_search_tree:left(T7))), + ?assertMatch(1, binary_search_tree:data(binary_search_tree:left(binary_search_tree:left(T7)))), + ?assertMatch(3, binary_search_tree:data(binary_search_tree:right(binary_search_tree:left(T7)))), + ?assertMatch(6, binary_search_tree:data(binary_search_tree:right(T7))), + ?assertMatch(5, binary_search_tree:data(binary_search_tree:left(binary_search_tree:right(T7)))), + ?assertMatch(7, binary_search_tree:data(binary_search_tree:right(binary_search_tree:right(T7)))). '6_can_sort_single_number_test'() -> T = binary_search_tree:insert(binary_search_tree:empty(), 2), - ?assertMatch([2], binary_search_tree:to_list(T)). + ?assertMatch([2], binary_search_tree:sorted_data(T)). '7_can_sort_if_second_number_is_smaller_than_first_test'() -> - T = binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:empty(), - 2), - 1), - ?assertMatch([1, 2], binary_search_tree:to_list(T)). + T0 = binary_search_tree:empty(), + T1 = binary_search_tree:insert(T0, 2), + T2 = binary_search_tree:insert(T1, 1), + ?assertMatch([1, 2], binary_search_tree:sorted_data(T2)). '8_can_sort_if_second_number_is_same_as_first_test'() -> - T = binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:empty(), - 2), - 2), - ?assertMatch([2, 2], binary_search_tree:to_list(T)). + T0 = binary_search_tree:empty(), + T1 = binary_search_tree:insert(T0, 2), + T2 = binary_search_tree:insert(T1, 2), + ?assertMatch([2, 2], binary_search_tree:sorted_data(T2)). '9_can_sort_if_second_number_is_greater_than_first_test'() -> - T = binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:empty(), - 2), - 3), - ?assertMatch([2, 3], binary_search_tree:to_list(T)). + T0 = binary_search_tree:empty(), + T1 = binary_search_tree:insert(T0, 2), + T2 = binary_search_tree:insert(T1, 3), + ?assertMatch([2, 3], binary_search_tree:sorted_data(T2)). '10_can_sort_complex_tree_test'() -> - T = binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:insert( - binary_search_tree:empty(), - 2), - 1), - 3), - 6), - 7), - 5), - ?assertMatch([1, 2, 3, 5, 6, 7], binary_search_tree:to_list(T)). + T0 = binary_search_tree:empty(), + T1 = binary_search_tree:insert(T0, 2), + T2 = binary_search_tree:insert(T1, 1), + T3 = binary_search_tree:insert(T2, 3), + T4 = binary_search_tree:insert(T3, 6), + T5 = binary_search_tree:insert(T4, 7), + T6 = binary_search_tree:insert(T5, 5), + ?assertMatch([1, 2, 3, 5, 6, 7], binary_search_tree:sorted_data(T6)).