From fbea0a562f52b850e3afc12dfa08f6e1d9dacbe9 Mon Sep 17 00:00:00 2001 From: Mislav Date: Thu, 15 Nov 2018 13:28:51 +0100 Subject: [PATCH 01/12] Exercise 1 --- exercise/01/containers.cpp | 55 ++++++++++++++++++++++++++++++++++++++ exercise/01/containers.h | 3 +++ exercise/01/e01.sln | 25 +++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 exercise/01/containers.cpp create mode 100644 exercise/01/e01.sln diff --git a/exercise/01/containers.cpp b/exercise/01/containers.cpp new file mode 100644 index 0000000..dbc24f4 --- /dev/null +++ b/exercise/01/containers.cpp @@ -0,0 +1,55 @@ +#include "containers.h" +#include +#include + +void remove_element(std::vector& v, int index) +{ + v.erase(v.cbegin() + index); +} + +void input_element(std::vector& v, int index, const std::wstring& value) +{ + v.insert(v.cbegin() + index, value); +} + +int list_nth_element(const std::list& c, int index) +{ + auto it = c.cbegin(); + std::advance(it, index); + return *it; +} + +void list_sort_desc(std::list& c) +{ + c.sort(std::greater()); +} + +int unique_numbers(std::wistream& ins) +{ + std::unordered_set set{}; + int n{}; + + while (ins >> n) set.emplace(n); + return set.size(); +} + +word_frequency::word_frequency(std::wistream& in) +{ + std::wstring s{}; + while (in >> s) + { + for (auto& chr : s) chr = ::tolower(chr); + freq_[s] += 1; + } +} + +int word_frequency::frequency(const std::wstring& s) +{ + if (freq_.find(s) != freq_.end()) return freq_[s]; + return 0; +} + +int word_frequency::count() +{ + return freq_.size(); +} diff --git a/exercise/01/containers.h b/exercise/01/containers.h index 8e1b172..dbae8cb 100644 --- a/exercise/01/containers.h +++ b/exercise/01/containers.h @@ -2,6 +2,7 @@ #include #include #include +#include void remove_element(std::vector& v, int index); void input_element(std::vector& v, int index, const std::wstring& value); @@ -13,6 +14,8 @@ int unique_numbers(std::wistream&); class word_frequency { +private: + std::map freq_; public: word_frequency(std::wistream&); int frequency(const std::wstring& s); diff --git a/exercise/01/e01.sln b/exercise/01/e01.sln new file mode 100644 index 0000000..e72b5ba --- /dev/null +++ b/exercise/01/e01.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2050 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "e01", "e01.vcxproj", "{DD752318-EA08-4316-9EFE-C1A42F5526F4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DD752318-EA08-4316-9EFE-C1A42F5526F4}.Debug|x86.ActiveCfg = Debug|Win32 + {DD752318-EA08-4316-9EFE-C1A42F5526F4}.Debug|x86.Build.0 = Debug|Win32 + {DD752318-EA08-4316-9EFE-C1A42F5526F4}.Release|x86.ActiveCfg = Release|Win32 + {DD752318-EA08-4316-9EFE-C1A42F5526F4}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {705A05C1-6D84-4F05-8B4D-E9EA3B8FE694} + EndGlobalSection +EndGlobal From 3013338056d0aa498109db75866a3d085c1cc62f Mon Sep 17 00:00:00 2001 From: Mislav Date: Thu, 15 Nov 2018 13:32:10 +0100 Subject: [PATCH 02/12] wchar to lower function --- exercise/01/containers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercise/01/containers.cpp b/exercise/01/containers.cpp index dbc24f4..876fa3c 100644 --- a/exercise/01/containers.cpp +++ b/exercise/01/containers.cpp @@ -38,7 +38,7 @@ word_frequency::word_frequency(std::wistream& in) std::wstring s{}; while (in >> s) { - for (auto& chr : s) chr = ::tolower(chr); + for (auto& chr : s) chr = ::towlower(chr); freq_[s] += 1; } } From ca62aa17f71d5f77cd43ea14bfbcdf699ca4a990 Mon Sep 17 00:00:00 2001 From: Mislav Date: Thu, 15 Nov 2018 13:40:09 +0100 Subject: [PATCH 03/12] to lower function, transparent functor for sort --- exercise/01/containers.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/exercise/01/containers.cpp b/exercise/01/containers.cpp index 876fa3c..70083b8 100644 --- a/exercise/01/containers.cpp +++ b/exercise/01/containers.cpp @@ -2,6 +2,17 @@ #include #include + +namespace +{ + std::wstring to_lower(std::wstring const& s) + { + std::wstring ret{}; + for (auto& chr : s) ret += ::towlower(chr); + return ret; + } +} + void remove_element(std::vector& v, int index) { v.erase(v.cbegin() + index); @@ -21,7 +32,7 @@ int list_nth_element(const std::list& c, int index) void list_sort_desc(std::list& c) { - c.sort(std::greater()); + c.sort(std::greater<>()); } int unique_numbers(std::wistream& ins) @@ -38,14 +49,14 @@ word_frequency::word_frequency(std::wistream& in) std::wstring s{}; while (in >> s) { - for (auto& chr : s) chr = ::towlower(chr); - freq_[s] += 1; + freq_[to_lower(s)] += 1; } } int word_frequency::frequency(const std::wstring& s) { - if (freq_.find(s) != freq_.end()) return freq_[s]; + const auto find_s = to_lower(s); + if (freq_.find(to_lower(find_s)) != freq_.end()) return freq_[find_s]; return 0; } @@ -53,3 +64,4 @@ int word_frequency::count() { return freq_.size(); } + From 217767ff426691b1c0494fd1c1d3d5aeb4141f45 Mon Sep 17 00:00:00 2001 From: Mislav Date: Thu, 15 Nov 2018 13:41:23 +0100 Subject: [PATCH 04/12] one function call less --- exercise/01/containers.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercise/01/containers.cpp b/exercise/01/containers.cpp index 70083b8..f242e7a 100644 --- a/exercise/01/containers.cpp +++ b/exercise/01/containers.cpp @@ -56,7 +56,7 @@ word_frequency::word_frequency(std::wistream& in) int word_frequency::frequency(const std::wstring& s) { const auto find_s = to_lower(s); - if (freq_.find(to_lower(find_s)) != freq_.end()) return freq_[find_s]; + if (freq_.find(find_s) != freq_.end()) return freq_[find_s]; return 0; } From 4ad055447c86b567e4ae1043c0d97430a0ecd876 Mon Sep 17 00:00:00 2001 From: Mislav Date: Thu, 15 Nov 2018 13:47:15 +0100 Subject: [PATCH 05/12] const correctness --- exercise/01/containers.cpp | 8 ++++---- exercise/01/containers.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/exercise/01/containers.cpp b/exercise/01/containers.cpp index f242e7a..10964c8 100644 --- a/exercise/01/containers.cpp +++ b/exercise/01/containers.cpp @@ -13,17 +13,17 @@ namespace } } -void remove_element(std::vector& v, int index) +void remove_element(std::vector& v, const int index) { v.erase(v.cbegin() + index); } -void input_element(std::vector& v, int index, const std::wstring& value) +void input_element(std::vector& v, const int index, const std::wstring& value) { v.insert(v.cbegin() + index, value); } -int list_nth_element(const std::list& c, int index) +int list_nth_element(const std::list& c, const int index) { auto it = c.cbegin(); std::advance(it, index); @@ -60,7 +60,7 @@ int word_frequency::frequency(const std::wstring& s) return 0; } -int word_frequency::count() +int word_frequency::count() const noexcept { return freq_.size(); } diff --git a/exercise/01/containers.h b/exercise/01/containers.h index dbae8cb..e6068ab 100644 --- a/exercise/01/containers.h +++ b/exercise/01/containers.h @@ -17,7 +17,7 @@ class word_frequency private: std::map freq_; public: - word_frequency(std::wistream&); + explicit word_frequency(std::wistream&); int frequency(const std::wstring& s); - int count(); + int count() const noexcept; }; From 0025ffda517583b501fffbf111b0d17dc082f202 Mon Sep 17 00:00:00 2001 From: Mislav Date: Thu, 15 Nov 2018 13:54:44 +0100 Subject: [PATCH 06/12] frequency funcstions cleanup --- exercise/01/containers.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/exercise/01/containers.cpp b/exercise/01/containers.cpp index 10964c8..d20f6f5 100644 --- a/exercise/01/containers.cpp +++ b/exercise/01/containers.cpp @@ -8,7 +8,7 @@ namespace std::wstring to_lower(std::wstring const& s) { std::wstring ret{}; - for (auto& chr : s) ret += ::towlower(chr); + for (auto& chr : s) ret += towlower(chr); return ret; } } @@ -55,13 +55,11 @@ word_frequency::word_frequency(std::wistream& in) int word_frequency::frequency(const std::wstring& s) { - const auto find_s = to_lower(s); - if (freq_.find(find_s) != freq_.end()) return freq_[find_s]; - return 0; + const auto find_s = freq_.find(to_lower(s)); + return find_s != freq_.end() ? find_s->second : 0; } int word_frequency::count() const noexcept { - return freq_.size(); + return freq_.size(); } - From a9f8e5bfe8996a31dead144883fab471967600bd Mon Sep 17 00:00:00 2001 From: Mislav Date: Thu, 15 Nov 2018 16:27:19 +0100 Subject: [PATCH 07/12] work in progress --- exercise/02/algorithms_test.cpp | 422 ++++++++++++++++++-------------- exercise/02/e02.sln | 25 ++ 2 files changed, 267 insertions(+), 180 deletions(-) create mode 100644 exercise/02/e02.sln diff --git a/exercise/02/algorithms_test.cpp b/exercise/02/algorithms_test.cpp index 9df3595..c3ff529 100644 --- a/exercise/02/algorithms_test.cpp +++ b/exercise/02/algorithms_test.cpp @@ -11,184 +11,246 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework; TEST_CLASS(test_standard_algorithms_usage) { public: - TEST_METHOD(test_01) - { - std::wstringstream ss(L"14 -78 22"); - std::vector v; - // TODO: read values from input stream into vector - - Assert::AreEqual(3u, v.size()); - Assert::AreEqual(14, v[0]); - Assert::AreEqual(-78, v[1]); - Assert::AreEqual(22, v[2]); - - } - TEST_METHOD(test_02a) - { - std::vector v(10); - // TODO: fill vector with incremental values - Assert::AreEqual(10u, v.size()); - Assert::IsTrue(std::is_sorted(v.cbegin(), v.cend())); - Assert::AreEqual( 1, v[0]); - Assert::AreEqual(10, v[9]); - } - TEST_METHOD(test_02b) - { - // generate - std::vector v(10); - // TODO: fill vector with incremental values (by 2) - Assert::IsTrue(std::is_sorted(v.cbegin(), v.cend())); - Assert::IsTrue(v.cend() == std::adjacent_find(v.cbegin(), v.cend(), [](int a, int b) { return b - a != 2; })); - Assert::AreEqual(1, v[0]); - Assert::AreEqual(19, v[9]); - } - - TEST_METHOD(test_03a) - { - std::vector v = { 1, 5, 10 } ; - // TODO: change all values in a vector - Assert::AreEqual(3u, v.size()); - Assert::AreEqual(1, v[0]); - Assert::AreEqual(125, v[1]); - Assert::AreEqual(1000, v[2]); - } - TEST_METHOD(test_03b) - { - int x[] = { 3, 5, 10 }; - std::vector y = { 4, 12, 10 }; - std::vector d; - - // TODO: calculate distances from origin (from x and y collections) to new vector - Assert::AreEqual(3u, d.size()); - Assert::AreEqual(5., d[0]); - Assert::AreEqual(13., d[1]); - Assert::AreEqual(sqrt(200), d[2]); - } - TEST_METHOD(test_04a) - { - std::wstringstream ss(L"1.5 2.5 3.5"); - auto res = // TODO: sum of all values in input stream - Assert::AreEqual(7.5, res); - } - TEST_METHOD(test_04b) - { - std::vector v { L"A", L"V", L"L", L"!" }; - auto res = // TODO: concatenated string with additional prefix - Assert::AreEqual(L"GO AVL!", res.c_str()); - } - TEST_METHOD(test_04c) - { - struct person { std::wstring name; int age; }; - std::vector v{ {L"Pero", 33}, {L"Iva", 25} }; - auto total_age = // TODO: sum of all ages - Assert::AreEqual(58, total_age); - } - - TEST_METHOD(test_05a) - { - std::vector v { -5, 8, 11, 0, -9, 77, -4 }; - auto number_of_negative = // TODO: - Assert::AreEqual(3, number_of_negative); - } - TEST_METHOD(test_05b) - { - std::vector v { 1.5, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99 }; - auto number_of_invalid = // TODO: - Assert::AreEqual(3, number_of_invalid); - } - TEST_METHOD(test_05c) - { - struct point { int x, y; }; - std::vector v{ {1,1}, {-5,3}, {2,2}, {-7,-6}, {9,-4} }; - auto number_in_first_quadrant = // TODO: - Assert::AreEqual(2, number_in_first_quadrant); - } - - TEST_METHOD(test_06) - { - std::vector v { 33, 16, 24, 41, 25, 19, 9 }; - auto first_prime = // TODO: - Assert::AreEqual(41, first_prime); - } - TEST_METHOD(test_07a) - { - std::vector v{ 1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99 }; - // TODO: change every invalid value (1e10) with -1 - Assert::AreEqual(-1., v[0]); - Assert::AreEqual(-1., v[4]); - Assert::AreEqual(-1., v[6]); - } - TEST_METHOD(test_07b) - { - std::wstring s(L"ponedjeljak"); - // TODO: change every vowel with x - Assert::AreEqual(L"pxnxdjxljxk", s.c_str()); - } - TEST_METHOD(test_08a) - { - std::vector v{ 1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99 }; - // TODO: delete all invalid values (1e10) - Assert::AreEqual(5u, v.size()); - Assert::AreEqual(8., v[0]); - Assert::AreEqual(99., v[4]); - } - - TEST_METHOD(test_08b) - { - std::wstring s(L"ponedjeljak"); - // TODO: delete all vowels - Assert::AreEqual(L"pndjljk", s.c_str()); - } - TEST_METHOD(test_09) - { - struct exam { std::wstring name; int points, grade; }; - std::vector v{ {L"Pero", 55, 2}, {L"Iva", 93, 5}, {L"Marko", 89, 5} }; - // TODO: sort vector by grade, then by points - Assert::AreEqual(L"Iva", v[0].name.c_str()); - Assert::AreEqual(L"Marko", v[1].name.c_str()); - Assert::AreEqual(L"Pero", v[2].name.c_str()); - - } - TEST_METHOD(test_10a) - { - // nth_element - std::vector v(2e7); - // half of the values less than 1000 - std::generate(v.begin(), v.begin() + v.size() / 2, []() { return rand() % 1000; }); - // other half of the values greater than 1000 - std::generate(v.begin() + v.size() / 2, v.end(), []() { return 1001 + rand() % 1000; }); - v.push_back(1000); // to be median - std::random_shuffle(v.begin(), v.end()); - - using namespace std::chrono; - auto t1 = steady_clock::now(); - // TODO: put median value in the middle of vector. fast. - auto t2 = steady_clock::now(); - auto dur = duration_cast(t2 - t1); - Assert::AreEqual(1000., v[v.size() / 2]); // median value - Assert::IsTrue(dur.count() < 1000, std::to_wstring(dur.count()).c_str()); // faster than 1 second - } - TEST_METHOD(test_10b) - { - struct employee { std::wstring name; int salary; }; - std::vector v{ {L"Iva", 2000}, {L"Pero", 1000}, {L"Marko", 10000} }; - // TODO: put employee with median salary in the middle of vector - std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end(), [](const employee& a, const employee& b) { return a.salary < b.salary; }); - Assert::AreEqual(L"Iva", v[v.size() / 2].name.c_str()); // median_salary - } - TEST_METHOD(test_12) - { - std::vector v{ 11, 0.5, -97.23, -23.11, 48.78, 22.96, -77 }; - auto smallest_value = // TODO: - Assert::AreEqual(-97.23, smallest_value); - auto largest_value = // TODO: - Assert::AreEqual(48.78, largest_value); - } - TEST_METHOD(test_13) - { - std::vector atp_points { 8445, 7480, 6220, 5300, 5285 }; - // the most interesting match is the one with the smallest difference - auto smallest_difference = // TODO: - Assert::AreEqual(15, smallest_difference); - } + TEST_METHOD(test_01) + { + std::wstringstream ss(L"14 -78 22"); + std::vector v{}; + + // TODO: read values from input stream into vector + std::copy(std::istream_iterator{ss}, std::istream_iterator{}, + std::back_inserter(v)); + + Assert::AreEqual(3u, v.size()); + Assert::AreEqual(14, v[0]); + Assert::AreEqual(-78, v[1]); + Assert::AreEqual(22, v[2]); + } + + TEST_METHOD(test_02a) + { + std::vector v(10); + + // TODO: fill vector with incremental values + std::iota(v.begin(), v.end(), 1); + + Assert::AreEqual(10u, v.size()); + Assert::IsTrue(std::is_sorted(v.cbegin(), v.cend())); + Assert::AreEqual(1, v[0]); + Assert::AreEqual(10, v[9]); + } + + TEST_METHOD(test_02b) + { + // generate + std::vector v(10); + + // TODO: fill vector with incremental values (by 2) + std::generate(v.begin(), v.end(), []() + { + static int i{-1}; + return i += 2; + }); + + Assert::IsTrue(std::is_sorted(v.cbegin(), v.cend())); + Assert::IsTrue(v.cend() == std::adjacent_find(v.cbegin(), v.cend(), [](int a, int b) { return b - a != 2; })); + Assert::AreEqual(1, v[0]); + Assert::AreEqual(19, v[9]); + } + + TEST_METHOD(test_03a) + { + std::vector v = {1, 5, 10}; + + // TODO: change all values in a vector + std::transform(v.begin(), v.end(), v.begin(), [](auto& elem) { return std::pow(elem, 3); }); + + Assert::AreEqual(3u, v.size()); + Assert::AreEqual(1, v[0]); + Assert::AreEqual(125, v[1]); + Assert::AreEqual(1000, v[2]); + } + + //TEST_METHOD(test_03b) + //{ + // int x[] = {3, 5, 10}; + // std::vector y = {4, 12, 10}; + // std::vector d; + + // // TODO: calculate distances from origin (from x and y collections) to new vector + // auto dist = [](int a, int b) { return std::sqrt(std::pow(a, 2) + std::pow(b, 2)); }; + // std::transform(); + + // Assert::AreEqual(3u, d.size()); + // Assert::AreEqual(5., d[0]); + // Assert::AreEqual(13., d[1]); + // Assert::AreEqual(sqrt(200), d[2]); + //} + + TEST_METHOD(test_04a) + { + std::wstringstream ss(L"1.5 2.5 3.5"); + + // TODO: sum of all values in input stream + auto res = std::accumulate(std::istream_iterator{ss}, std::istream_iterator{}, + 0.); + Assert::AreEqual(7.5, res); + } + + TEST_METHOD(test_04b) + { + std::vector v{L"A", L"V", L"L", L"!"}; + // TODO: concatenated string with additional prefix + auto res = std::accumulate(v.cbegin(), v.cend(), std::wstring{L"GO "}); + Assert::AreEqual(L"GO AVL!", res.c_str()); + } + + TEST_METHOD(test_04c) + { + struct person + { + std::wstring name; + int age; + }; + std::vector v{{L"Pero", 33}, {L"Iva", 25}}; + // TODO: sum of all ages + auto total_age = std::accumulate(v.cbegin(), v.cend(), 0, [](int acc, auto const& p) { return acc + p.age; }); + + Assert::AreEqual(58, total_age); + } + + TEST_METHOD(test_05a) + { + std::vector v{-5, 8, 11, 0, -9, 77, -4}; + auto number_of_negative = std::count_if(v.cbegin(), v.cend(), [](int elem) { return elem < 0; }); + Assert::AreEqual(3, number_of_negative); + } + + TEST_METHOD(test_05b) + { + std::vector v{1.5, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99}; + //condition not defined + auto number_of_invalid = std::count_if(v.cbegin(), v.cend(), [](double elem) { return elem >= 100.; }); + Assert::AreEqual(3, number_of_invalid); + } + + TEST_METHOD(test_05c) + { + struct point + { + int x, y; + }; + std::vector v{{1, 1}, {-5, 3}, {2, 2}, {-7, -6}, {9, -4}}; + auto number_in_first_quadrant = std::count_if(v.cbegin(), v.cend(), [](auto const& p) + { + return p.x >= 0 && p.y >= 0; + }); + Assert::AreEqual(2, number_in_first_quadrant); + } + + + TEST_METHOD(test_06) + { + std::vector v{33, 16, 24, 41, 25, 19, 9}; + auto first_prime = std::find(v.cbegin(), v.cend(), ); + Assert::AreEqual(41, first_prime); + } + // + // TEST_METHOD(test_07a) + // { + // std::vector v{1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99}; + // // TODO: change every invalid value (1e10) with -1 + // Assert::AreEqual(-1., v[0]); + // Assert::AreEqual(-1., v[4]); + // Assert::AreEqual(-1., v[6]); + // } + // + // TEST_METHOD(test_07b) + // { + // std::wstring s(L"ponedjeljak"); + // // TODO: change every vowel with x + // Assert::AreEqual(L"pxnxdjxljxk", s.c_str()); + // } + // + // TEST_METHOD(test_08a) + // { + // std::vector v{1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99}; + // // TODO: delete all invalid values (1e10) + // Assert::AreEqual(5u, v.size()); + // Assert::AreEqual(8., v[0]); + // Assert::AreEqual(99., v[4]); + // } + // + // TEST_METHOD(test_08b) + // { + // std::wstring s(L"ponedjeljak"); + // // TODO: delete all vowels + // Assert::AreEqual(L"pndjljk", s.c_str()); + // } + // + // TEST_METHOD(test_09) + // { + // struct exam + // { + // std::wstring name; + // int points, grade; + // }; + // std::vector v{{L"Pero", 55, 2}, {L"Iva", 93, 5}, {L"Marko", 89, 5}}; + // // TODO: sort vector by grade, then by points + // Assert::AreEqual(L"Iva", v[0].name.c_str()); + // Assert::AreEqual(L"Marko", v[1].name.c_str()); + // Assert::AreEqual(L"Pero", v[2].name.c_str()); + // } + // + // TEST_METHOD(test_10a) + // { + // // nth_element + // std::vector v(2e7); + // // half of the values less than 1000 + // std::generate(v.begin(), v.begin() + v.size() / 2, []() { return rand() % 1000; }); + // // other half of the values greater than 1000 + // std::generate(v.begin() + v.size() / 2, v.end(), []() { return 1001 + rand() % 1000; }); + // v.push_back(1000); // to be median + // std::random_shuffle(v.begin(), v.end()); + // + // using namespace std::chrono; + // auto t1 = steady_clock::now(); + // // TODO: put median value in the middle of vector. fast. + // auto t2 = steady_clock::now(); + // auto dur = duration_cast(t2 - t1); + // Assert::AreEqual(1000., v[v.size() / 2]); // median value + // Assert::IsTrue(dur.count() < 1000, std::to_wstring(dur.count()).c_str()); // faster than 1 second + // } + // + // TEST_METHOD(test_10b) + // { + // struct employee + // { + // std::wstring name; + // int salary; + // }; + // std::vector v{{L"Iva", 2000}, {L"Pero", 1000}, {L"Marko", 10000}}; + // // TODO: put employee with median salary in the middle of vector + // std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end(), [](const employee& a, const employee& b) + // { + // return a.salary < b.salary; + // }); + // Assert::AreEqual(L"Iva", v[v.size() / 2].name.c_str()); // median_salary + // } + // + // TEST_METHOD(test_12) + // { + // std::vector v{11, 0.5, -97.23, -23.11, 48.78, 22.96, -77}; + // auto smallest_value = // TODO: + // Assert::AreEqual(-97.23, smallest_value); + // auto largest_value = // TODO: + // Assert::AreEqual(48.78, largest_value); + // } + // + // TEST_METHOD(test_13) + // { + // std::vector atp_points{8445, 7480, 6220, 5300, 5285}; + // // the most interesting match is the one with the smallest difference + // auto smallest_difference = // TODO: + // Assert::AreEqual(15, smallest_difference); + // } }; diff --git a/exercise/02/e02.sln b/exercise/02/e02.sln new file mode 100644 index 0000000..d2f5fd3 --- /dev/null +++ b/exercise/02/e02.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2050 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "e02", "e02.vcxproj", "{DD752318-EA08-4316-9EFE-C1A42F5526F4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {DD752318-EA08-4316-9EFE-C1A42F5526F4}.Debug|x86.ActiveCfg = Debug|Win32 + {DD752318-EA08-4316-9EFE-C1A42F5526F4}.Debug|x86.Build.0 = Debug|Win32 + {DD752318-EA08-4316-9EFE-C1A42F5526F4}.Release|x86.ActiveCfg = Release|Win32 + {DD752318-EA08-4316-9EFE-C1A42F5526F4}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {14C0160B-BC26-4CE5-BA70-DCC73C90E281} + EndGlobalSection +EndGlobal From 5e41f49c17e883fba8e170fce4814d5a4626c255 Mon Sep 17 00:00:00 2001 From: Mislav Date: Thu, 15 Nov 2018 16:41:24 +0100 Subject: [PATCH 08/12] WIP --- exercise/02/algorithms_test.cpp | 49 ++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/exercise/02/algorithms_test.cpp b/exercise/02/algorithms_test.cpp index c3ff529..a54d230 100644 --- a/exercise/02/algorithms_test.cpp +++ b/exercise/02/algorithms_test.cpp @@ -70,21 +70,23 @@ TEST_CLASS(test_standard_algorithms_usage) Assert::AreEqual(1000, v[2]); } - //TEST_METHOD(test_03b) - //{ - // int x[] = {3, 5, 10}; - // std::vector y = {4, 12, 10}; - // std::vector d; + TEST_METHOD(test_03b) + { + int x[] = {3, 5, 10}; + std::vector y = {4, 12, 10}; + std::vector d; - // // TODO: calculate distances from origin (from x and y collections) to new vector - // auto dist = [](int a, int b) { return std::sqrt(std::pow(a, 2) + std::pow(b, 2)); }; - // std::transform(); + // TODO: calculate distances from origin (from x and y collections) to new vector + std::transform(std::begin(x), std::end(x), y.cbegin(), std::back_inserter(d), [](int a, int b) + { + return std::sqrt(std::pow(a, 2) + std::pow(b, 2)); + }); - // Assert::AreEqual(3u, d.size()); - // Assert::AreEqual(5., d[0]); - // Assert::AreEqual(13., d[1]); - // Assert::AreEqual(sqrt(200), d[2]); - //} + Assert::AreEqual(3u, d.size()); + Assert::AreEqual(5., d[0]); + Assert::AreEqual(13., d[1]); + Assert::AreEqual(sqrt(200), d[2]); + } TEST_METHOD(test_04a) { @@ -147,13 +149,22 @@ TEST_CLASS(test_standard_algorithms_usage) Assert::AreEqual(2, number_in_first_quadrant); } - - TEST_METHOD(test_06) + + TEST_METHOD(test_06) + { + std::vector v{33, 16, 24, 41, 25, 19, 9}; + auto first_prime = *std::find_if(v.cbegin(), v.cend(), [](int elem) { - std::vector v{33, 16, 24, 41, 25, 19, 9}; - auto first_prime = std::find(v.cbegin(), v.cend(), ); - Assert::AreEqual(41, first_prime); - } + int threshold = std::sqrt(elem); + for (int i = 2; i <= threshold; ++i) + { + if (elem % i == 0) return false; + } + return true; + }); + Assert::AreEqual(41, first_prime); + } + // // TEST_METHOD(test_07a) // { From efad34a695e1ddb31a1dbb2c26d6fc14d018a75e Mon Sep 17 00:00:00 2001 From: Mislav Date: Thu, 15 Nov 2018 16:57:02 +0100 Subject: [PATCH 09/12] WIP --- exercise/02/algorithms_test.cpp | 45 ++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/exercise/02/algorithms_test.cpp b/exercise/02/algorithms_test.cpp index a54d230..9270ab9 100644 --- a/exercise/02/algorithms_test.cpp +++ b/exercise/02/algorithms_test.cpp @@ -165,23 +165,34 @@ TEST_CLASS(test_standard_algorithms_usage) Assert::AreEqual(41, first_prime); } - // - // TEST_METHOD(test_07a) - // { - // std::vector v{1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99}; - // // TODO: change every invalid value (1e10) with -1 - // Assert::AreEqual(-1., v[0]); - // Assert::AreEqual(-1., v[4]); - // Assert::AreEqual(-1., v[6]); - // } - // - // TEST_METHOD(test_07b) - // { - // std::wstring s(L"ponedjeljak"); - // // TODO: change every vowel with x - // Assert::AreEqual(L"pxnxdjxljxk", s.c_str()); - // } - // + + TEST_METHOD(test_07a) + { + std::vector v{1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99}; + + // TODO: change every invalid value (1e10) with -1 + std::replace(v.begin(), v.end(), 1e10, -1.); + + Assert::AreEqual(-1., v[0]); + Assert::AreEqual(-1., v[4]); + Assert::AreEqual(-1., v[6]); + } + + TEST_METHOD(test_07b) + { + std::wstring s(L"ponedjeljak"); + + // TODO: change every vowel with x + std::replace_if(s.begin(), s.end(), [](auto const& chr) + { + std::wstring set{L"AEIOUaeiou"}; + std::wstring search_for{ chr }; + return std::includes(set.cbegin(), set.cend(), search_for.cbegin(), search_for.cend()); + }, L"x"); + + Assert::AreEqual(L"pxnxdjxljxk", s.c_str()); + } + // TEST_METHOD(test_08a) // { // std::vector v{1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99}; From 4c96362073d073f3ac6e776cae52e63e571dad49 Mon Sep 17 00:00:00 2001 From: Mislav Date: Thu, 15 Nov 2018 16:58:53 +0100 Subject: [PATCH 10/12] WIP --- exercise/02/algorithms_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercise/02/algorithms_test.cpp b/exercise/02/algorithms_test.cpp index 9270ab9..d3bc2e9 100644 --- a/exercise/02/algorithms_test.cpp +++ b/exercise/02/algorithms_test.cpp @@ -188,7 +188,7 @@ TEST_CLASS(test_standard_algorithms_usage) std::wstring set{L"AEIOUaeiou"}; std::wstring search_for{ chr }; return std::includes(set.cbegin(), set.cend(), search_for.cbegin(), search_for.cend()); - }, L"x"); + }, L'x'); Assert::AreEqual(L"pxnxdjxljxk", s.c_str()); } From 72a3a010bf256910f44aa938a519e9ebd53272db Mon Sep 17 00:00:00 2001 From: Mislav Date: Thu, 15 Nov 2018 22:57:40 +0100 Subject: [PATCH 11/12] Solutions for exercise 2. All tests pass (in release build). Some code is awful, but it attempts oneliners as much as possible. --- exercise/02/algorithms_test.cpp | 234 ++++++++++++++------------------ 1 file changed, 101 insertions(+), 133 deletions(-) diff --git a/exercise/02/algorithms_test.cpp b/exercise/02/algorithms_test.cpp index d3bc2e9..7f3d757 100644 --- a/exercise/02/algorithms_test.cpp +++ b/exercise/02/algorithms_test.cpp @@ -1,25 +1,25 @@ #include "CppUnitTest.h" using namespace Microsoft::VisualStudio::CppUnitTestFramework; - #include #include #include #include #include #include - +auto is_vowel = [](auto const& chr) +{ + static const std::wstring set{L"AEIOUaeiou"}; + std::wstring search_for{chr}; + return std::includes(set.cbegin(), set.cend(), search_for.cbegin(), search_for.cend()); +}; TEST_CLASS(test_standard_algorithms_usage) { public: TEST_METHOD(test_01) { std::wstringstream ss(L"14 -78 22"); - std::vector v{}; - - // TODO: read values from input stream into vector - std::copy(std::istream_iterator{ss}, std::istream_iterator{}, - std::back_inserter(v)); - + std::vector v{}; // TODO: read values from input stream into vector + std::copy(std::istream_iterator{ss}, std::istream_iterator{}, std::back_inserter(v)); Assert::AreEqual(3u, v.size()); Assert::AreEqual(14, v[0]); Assert::AreEqual(-78, v[1]); @@ -28,11 +28,8 @@ TEST_CLASS(test_standard_algorithms_usage) TEST_METHOD(test_02a) { - std::vector v(10); - - // TODO: fill vector with incremental values + std::vector v(10); // TODO: fill vector with incremental values std::iota(v.begin(), v.end(), 1); - Assert::AreEqual(10u, v.size()); Assert::IsTrue(std::is_sorted(v.cbegin(), v.cend())); Assert::AreEqual(1, v[0]); @@ -42,15 +39,12 @@ TEST_CLASS(test_standard_algorithms_usage) TEST_METHOD(test_02b) { // generate - std::vector v(10); - - // TODO: fill vector with incremental values (by 2) + std::vector v(10); // TODO: fill vector with incremental values (by 2) std::generate(v.begin(), v.end(), []() { static int i{-1}; return i += 2; }); - Assert::IsTrue(std::is_sorted(v.cbegin(), v.cend())); Assert::IsTrue(v.cend() == std::adjacent_find(v.cbegin(), v.cend(), [](int a, int b) { return b - a != 2; })); Assert::AreEqual(1, v[0]); @@ -59,11 +53,8 @@ TEST_CLASS(test_standard_algorithms_usage) TEST_METHOD(test_03a) { - std::vector v = {1, 5, 10}; - - // TODO: change all values in a vector + std::vector v = {1, 5, 10}; // TODO: change all values in a vector std::transform(v.begin(), v.end(), v.begin(), [](auto& elem) { return std::pow(elem, 3); }); - Assert::AreEqual(3u, v.size()); Assert::AreEqual(1, v[0]); Assert::AreEqual(125, v[1]); @@ -74,14 +65,11 @@ TEST_CLASS(test_standard_algorithms_usage) { int x[] = {3, 5, 10}; std::vector y = {4, 12, 10}; - std::vector d; - - // TODO: calculate distances from origin (from x and y collections) to new vector + std::vector d; // TODO: calculate distances from origin (from x and y collections) to new vector std::transform(std::begin(x), std::end(x), y.cbegin(), std::back_inserter(d), [](int a, int b) { return std::sqrt(std::pow(a, 2) + std::pow(b, 2)); }); - Assert::AreEqual(3u, d.size()); Assert::AreEqual(5., d[0]); Assert::AreEqual(13., d[1]); @@ -90,18 +78,14 @@ TEST_CLASS(test_standard_algorithms_usage) TEST_METHOD(test_04a) { - std::wstringstream ss(L"1.5 2.5 3.5"); - - // TODO: sum of all values in input stream - auto res = std::accumulate(std::istream_iterator{ss}, std::istream_iterator{}, - 0.); + std::wstringstream ss(L"1.5 2.5 3.5"); // TODO: sum of all values in input stream + auto res = std::accumulate(std::istream_iterator{ss}, std::istream_iterator{}, 0.); Assert::AreEqual(7.5, res); } TEST_METHOD(test_04b) { - std::vector v{L"A", L"V", L"L", L"!"}; - // TODO: concatenated string with additional prefix + std::vector v{L"A", L"V", L"L", L"!"}; // TODO: concatenated string with additional prefix auto res = std::accumulate(v.cbegin(), v.cend(), std::wstring{L"GO "}); Assert::AreEqual(L"GO AVL!", res.c_str()); } @@ -113,10 +97,8 @@ TEST_CLASS(test_standard_algorithms_usage) std::wstring name; int age; }; - std::vector v{{L"Pero", 33}, {L"Iva", 25}}; - // TODO: sum of all ages + std::vector v{{L"Pero", 33}, {L"Iva", 25}}; // TODO: sum of all ages auto total_age = std::accumulate(v.cbegin(), v.cend(), 0, [](int acc, auto const& p) { return acc + p.age; }); - Assert::AreEqual(58, total_age); } @@ -129,9 +111,8 @@ TEST_CLASS(test_standard_algorithms_usage) TEST_METHOD(test_05b) { - std::vector v{1.5, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99}; - //condition not defined - auto number_of_invalid = std::count_if(v.cbegin(), v.cend(), [](double elem) { return elem >= 100.; }); + std::vector v{1.5, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99}; //condition not defined + auto number_of_invalid = std::count(v.cbegin(), v.cend(), 1e10); Assert::AreEqual(3, number_of_invalid); } @@ -149,7 +130,6 @@ TEST_CLASS(test_standard_algorithms_usage) Assert::AreEqual(2, number_in_first_quadrant); } - TEST_METHOD(test_06) { std::vector v{33, 16, 24, 41, 25, 19, 9}; @@ -165,14 +145,10 @@ TEST_CLASS(test_standard_algorithms_usage) Assert::AreEqual(41, first_prime); } - TEST_METHOD(test_07a) { - std::vector v{1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99}; - - // TODO: change every invalid value (1e10) with -1 + std::vector v{1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99}; // TODO: change every invalid value (1e10) with -1 std::replace(v.begin(), v.end(), 1e10, -1.); - Assert::AreEqual(-1., v[0]); Assert::AreEqual(-1., v[4]); Assert::AreEqual(-1., v[6]); @@ -180,99 +156,91 @@ TEST_CLASS(test_standard_algorithms_usage) TEST_METHOD(test_07b) { - std::wstring s(L"ponedjeljak"); + std::wstring s(L"ponedjeljak"); // TODO: change every vowel with x + std::replace_if(s.begin(), s.end(), is_vowel, L'x'); + Assert::AreEqual(L"pxnxdjxljxk", s.c_str()); + } - // TODO: change every vowel with x - std::replace_if(s.begin(), s.end(), [](auto const& chr) + TEST_METHOD(test_08a) + { + std::vector v{1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99}; // TODO: delete all invalid values (1e10) + v.erase(std::remove(v.begin(), v.end(), 1e10), v.end()); + Assert::AreEqual(5u, v.size()); + Assert::AreEqual(8., v[0]); + Assert::AreEqual(99., v[4]); + } + + TEST_METHOD(test_08b) + { + std::wstring s(L"ponedjeljak"); // TODO: delete all vowels + s.erase(std::remove_if(s.begin(), s.end(), is_vowel), s.end()); + Assert::AreEqual(L"pndjljk", s.c_str()); + } + + TEST_METHOD(test_09) + { + struct exam { - std::wstring set{L"AEIOUaeiou"}; - std::wstring search_for{ chr }; - return std::includes(set.cbegin(), set.cend(), search_for.cbegin(), search_for.cend()); - }, L'x'); + std::wstring name; + int points, grade; + }; + std::vector v{{L"Pero", 55, 2}, {L"Iva", 93, 5}, {L"Marko", 89, 5}}; // TODO: sort vector by grade, then by points + std::sort(v.begin(), v.end(), [](auto const& lhs, auto const& rhs) { return lhs.points > rhs.points; }); + std::stable_sort(v.begin(), v.end(), [](auto const& lhs, auto const& rhs) { return lhs.grade > rhs.grade; }); + Assert::AreEqual(L"Iva", v[0].name.c_str()); + Assert::AreEqual(L"Marko", v[1].name.c_str()); + Assert::AreEqual(L"Pero", v[2].name.c_str()); + } - Assert::AreEqual(L"pxnxdjxljxk", s.c_str()); + TEST_METHOD(test_10a) + { + // nth_element + std::vector v(2e7); // half of the values less than 1000 + std::generate(v.begin(), v.begin() + v.size() / 2, []() { return rand() % 1000; }); // other half of the values greater than 1000 + std::generate(v.begin() + v.size() / 2, v.end(), []() { return 1001 + rand() % 1000; }); + v.push_back(1000); // to be median + std::random_shuffle(v.begin(), v.end()); + using namespace std::chrono; + auto t1 = steady_clock::now(); // TODO: put median value in the middle of vector. fast. + std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end()); + auto t2 = steady_clock::now(); + auto dur = duration_cast(t2 - t1); + Assert::AreEqual(1000., v[v.size() / 2]); // median value + Assert::IsTrue(dur.count() < 1000, std::to_wstring(dur.count()).c_str()); // faster than 1 second } - // TEST_METHOD(test_08a) - // { - // std::vector v{1e10, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99}; - // // TODO: delete all invalid values (1e10) - // Assert::AreEqual(5u, v.size()); - // Assert::AreEqual(8., v[0]); - // Assert::AreEqual(99., v[4]); - // } - // - // TEST_METHOD(test_08b) - // { - // std::wstring s(L"ponedjeljak"); - // // TODO: delete all vowels - // Assert::AreEqual(L"pndjljk", s.c_str()); - // } - // - // TEST_METHOD(test_09) - // { - // struct exam - // { - // std::wstring name; - // int points, grade; - // }; - // std::vector v{{L"Pero", 55, 2}, {L"Iva", 93, 5}, {L"Marko", 89, 5}}; - // // TODO: sort vector by grade, then by points - // Assert::AreEqual(L"Iva", v[0].name.c_str()); - // Assert::AreEqual(L"Marko", v[1].name.c_str()); - // Assert::AreEqual(L"Pero", v[2].name.c_str()); - // } - // - // TEST_METHOD(test_10a) - // { - // // nth_element - // std::vector v(2e7); - // // half of the values less than 1000 - // std::generate(v.begin(), v.begin() + v.size() / 2, []() { return rand() % 1000; }); - // // other half of the values greater than 1000 - // std::generate(v.begin() + v.size() / 2, v.end(), []() { return 1001 + rand() % 1000; }); - // v.push_back(1000); // to be median - // std::random_shuffle(v.begin(), v.end()); - // - // using namespace std::chrono; - // auto t1 = steady_clock::now(); - // // TODO: put median value in the middle of vector. fast. - // auto t2 = steady_clock::now(); - // auto dur = duration_cast(t2 - t1); - // Assert::AreEqual(1000., v[v.size() / 2]); // median value - // Assert::IsTrue(dur.count() < 1000, std::to_wstring(dur.count()).c_str()); // faster than 1 second - // } - // - // TEST_METHOD(test_10b) - // { - // struct employee - // { - // std::wstring name; - // int salary; - // }; - // std::vector v{{L"Iva", 2000}, {L"Pero", 1000}, {L"Marko", 10000}}; - // // TODO: put employee with median salary in the middle of vector - // std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end(), [](const employee& a, const employee& b) - // { - // return a.salary < b.salary; - // }); - // Assert::AreEqual(L"Iva", v[v.size() / 2].name.c_str()); // median_salary - // } - // - // TEST_METHOD(test_12) - // { - // std::vector v{11, 0.5, -97.23, -23.11, 48.78, 22.96, -77}; - // auto smallest_value = // TODO: - // Assert::AreEqual(-97.23, smallest_value); - // auto largest_value = // TODO: - // Assert::AreEqual(48.78, largest_value); - // } - // - // TEST_METHOD(test_13) - // { - // std::vector atp_points{8445, 7480, 6220, 5300, 5285}; - // // the most interesting match is the one with the smallest difference - // auto smallest_difference = // TODO: - // Assert::AreEqual(15, smallest_difference); - // } + TEST_METHOD(test_10b) + { + struct employee + { + std::wstring name; + int salary; + }; + std::vector v{{L"Iva", 2000}, {L"Pero", 1000}, {L"Marko", 10000}}; // TODO: put employee with median salary in the middle of vector + std::nth_element(v.begin(), v.begin() + v.size() / 2, v.end(), [](const employee& a, const employee& b) + { + return a.salary < b.salary; + }); + Assert::AreEqual(L"Iva", v[v.size() / 2].name.c_str()); // median_salary + } + + TEST_METHOD(test_12) + { + std::vector v{11, 0.5, -97.23, -23.11, 48.78, 22.96, -77}; + auto min_max = std::minmax_element(v.cbegin(), v.cend()); + auto smallest_value = *min_max.first; + Assert::AreEqual(-97.23, smallest_value); + auto largest_value = *min_max.second; + Assert::AreEqual(48.78, largest_value); + } + + TEST_METHOD(test_13) + { + std::vector atp_points{8445, 7480, 6220, 5300, 5285}; // the most interesting match is the one with the smallest difference + //awful, but its oneliner + auto smallest_difference = *std::min_element( + std::next(std::adjacent_difference(atp_points.begin(), atp_points.end(), atp_points.begin(), + [](auto const& a, auto const& b) { return std::abs(a - b); }), -atp_points.size()), atp_points.end()); + Assert::AreEqual(15, smallest_difference); + } }; From 258a266e4bde8acd82880dcfac14cd6ce31d110e Mon Sep 17 00:00:00 2001 From: Mislav Date: Thu, 15 Nov 2018 23:09:43 +0100 Subject: [PATCH 12/12] bugfix for test 13. solution wouldnt work if there first element was smaller than the smallest diffrence --- exercise/02/algorithms_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercise/02/algorithms_test.cpp b/exercise/02/algorithms_test.cpp index 7f3d757..b625196 100644 --- a/exercise/02/algorithms_test.cpp +++ b/exercise/02/algorithms_test.cpp @@ -240,7 +240,7 @@ TEST_CLASS(test_standard_algorithms_usage) //awful, but its oneliner auto smallest_difference = *std::min_element( std::next(std::adjacent_difference(atp_points.begin(), atp_points.end(), atp_points.begin(), - [](auto const& a, auto const& b) { return std::abs(a - b); }), -atp_points.size()), atp_points.end()); + [](auto const& a, auto const& b) { return std::abs(a - b); }), -(atp_points.size()-1)), atp_points.end()); Assert::AreEqual(15, smallest_difference); } };