From a2977781a12ee9add841f60f1458b294da95de34 Mon Sep 17 00:00:00 2001 From: Nicolette Date: Thu, 15 Nov 2018 17:41:22 +0100 Subject: [PATCH 1/3] Make exercise 01 green --- exercise/01/containers.cpp | 64 ++++++++++++++++++++++++++++++++++++++ exercise/01/containers.h | 4 +++ 2 files changed, 68 insertions(+) create mode 100644 exercise/01/containers.cpp diff --git a/exercise/01/containers.cpp b/exercise/01/containers.cpp new file mode 100644 index 0000000..8418e14 --- /dev/null +++ b/exercise/01/containers.cpp @@ -0,0 +1,64 @@ +#include "containers.h" +#include +#include + +void remove_element(std::vector& v, int index) +{ + v.erase(v.begin() + index); +} + +void input_element(std::vector& v, int index, const std::wstring & value) +{ + v.insert(v.begin() + index, value); +} + +int list_nth_element(const std::list& c, int index) +{ + std::list::const_iterator it = c.begin(); + std::advance(it, index); + return *it; +} + +void list_sort_desc(std::list& c) +{ + c.sort(); + c.reverse(); +} + +int unique_numbers(std::wistream& stream) +{ + int n; + std::set my_set; + while (stream >> n) + my_set.insert(n); + return my_set.size(); +} + +word_frequency::word_frequency(std::wistream & ss) +{ + std::wstring word; + while (ss >> word) + { + to_lower(word); + ++map_of_words[word]; + } +} + +int word_frequency::frequency(const std::wstring & s) +{ + auto it = map_of_words.find(s); + if (it != map_of_words.end()) + return (*it).second; + return int(); +} + +int word_frequency::count() +{ + return map_of_words.size(); +} + +void word_frequency::to_lower(std::wstring & word) const +{ + for (std::wstring::iterator it = word.begin(); it != word.end(); ++it) + *it = towlower(*it); +} diff --git a/exercise/01/containers.h b/exercise/01/containers.h index 8e1b172..8250bdb 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); @@ -17,4 +18,7 @@ class word_frequency word_frequency(std::wistream&); int frequency(const std::wstring& s); int count(); +private: + std::map map_of_words; + void to_lower(std::wstring& word) const; }; From b6597d776f9f8abdf4180c9ca0b2e362227afaf3 Mon Sep 17 00:00:00 2001 From: Nicolette Date: Thu, 15 Nov 2018 17:43:09 +0100 Subject: [PATCH 2/3] Make exercise 02 green - 01, 02a, 02b, 03a --- exercise/02/algorithms_test.cpp | 128 ++++++++++++++++---------------- 1 file changed, 65 insertions(+), 63 deletions(-) diff --git a/exercise/02/algorithms_test.cpp b/exercise/02/algorithms_test.cpp index 9df3595..54cf869 100644 --- a/exercise/02/algorithms_test.cpp +++ b/exercise/02/algorithms_test.cpp @@ -15,7 +15,8 @@ TEST_CLASS(test_standard_algorithms_usage) { std::wstringstream ss(L"14 -78 22"); std::vector v; - // TODO: read values from input stream into vector + std::istream_iterator it(ss), end; + std::transform(it, end, std::back_inserter(v), [](const std::wstring& str) { return std::stoi(str); }); Assert::AreEqual(3u, v.size()); Assert::AreEqual(14, v[0]); @@ -26,7 +27,8 @@ TEST_CLASS(test_standard_algorithms_usage) TEST_METHOD(test_02a) { std::vector v(10); - // TODO: fill vector with incremental values + int value = 1; + std::generate(v.begin(), v.end(), []() { static int i=1; return i++; }); Assert::AreEqual(10u, v.size()); Assert::IsTrue(std::is_sorted(v.cbegin(), v.cend())); Assert::AreEqual( 1, v[0]); @@ -36,7 +38,7 @@ TEST_CLASS(test_standard_algorithms_usage) { // generate std::vector v(10); - // TODO: fill vector with incremental values (by 2) + std::generate(v.begin(), v.end(), []() { static int i=-1; i=i+2; return i; }); 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]); @@ -46,7 +48,7 @@ TEST_CLASS(test_standard_algorithms_usage) 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(), [](int num) { return pow(num, 3); }); Assert::AreEqual(3u, v.size()); Assert::AreEqual(1, v[0]); Assert::AreEqual(125, v[1]); @@ -64,52 +66,52 @@ TEST_CLASS(test_standard_algorithms_usage) 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_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_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_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 }; @@ -176,19 +178,19 @@ TEST_CLASS(test_standard_algorithms_usage) 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_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); + //} }; From 6f3026489cffd7cdd7683bd11660f579284e3425 Mon Sep 17 00:00:00 2001 From: Nicolette Date: Fri, 16 Nov 2018 16:10:03 +0100 Subject: [PATCH 3/3] Make exercise 02 green - all of them --- exercise/02/algorithms_test.cpp | 180 +++++++++++++++++++------------- 1 file changed, 105 insertions(+), 75 deletions(-) diff --git a/exercise/02/algorithms_test.cpp b/exercise/02/algorithms_test.cpp index 54cf869..eadd366 100644 --- a/exercise/02/algorithms_test.cpp +++ b/exercise/02/algorithms_test.cpp @@ -8,6 +8,23 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework; #include #include +namespace { + bool is_prime(int n) + { + if (n <= 1) return false; + for (int i = 2; i < n; i++) + if (n % i == 0) + return false; + return true; + } + + bool is_invalid(double num) + { + const double invalid = 1e10; + return std::abs(num - invalid) < std::abs(std::min(num, invalid))*std::numeric_limits::epsilon(); + } +} + TEST_CLASS(test_standard_algorithms_usage) { public: @@ -15,25 +32,24 @@ TEST_CLASS(test_standard_algorithms_usage) { std::wstringstream ss(L"14 -78 22"); std::vector v; - std::istream_iterator it(ss), end; - std::transform(it, end, std::back_inserter(v), [](const std::wstring& str) { return std::stoi(str); }); - + std::istream_iterator it(ss), end; + std::copy(it, end, 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); - int value = 1; std::generate(v.begin(), v.end(), []() { static int i=1; return i++; }); 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 @@ -54,82 +70,91 @@ TEST_CLASS(test_standard_algorithms_usage) 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 + std::transform(std::begin(x), std::end(x), y.begin(), std::back_inserter(d), [](int x, int y) { return sqrt(pow(x, 2) + pow(y, 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) - //{ - // 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_04a) + { + std::wstringstream ss(L"1.5 2.5 3.5"); + std::istream_iterator it(ss), end; + auto res = std::accumulate(it, end, 0.0); + Assert::AreEqual(7.5, res); + } + + TEST_METHOD(test_04b) + { + std::vector v { L"A", L"V", L"L", L"!" }; + auto res = std::accumulate(v.begin(), v.end(), 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} }; + auto total_age = std::accumulate(v.begin(), v.end(), 0, [](int sum, const person& p) { return sum + 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::accumulate(v.begin(), v.end(), 0, [](int sum, int input) { return input < 0 ? ++sum : sum; }); + 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 = std::accumulate(v.begin(), v.end(), 0, [](int sum, double input) { return is_invalid(input) ? ++sum : sum; }); + 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::accumulate(v.begin(), v.end(), 0, [](int sum, point input) { return input.x>0&input.y>0? ++sum : sum; }); + 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_if(v.begin(), v.end(), [](int input) {return is_prime(input); }); + 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::transform(v.begin(), v.end(), v.begin(), [](double input) { return is_invalid(input) ? -1 : input; }); 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::transform(s.begin(), s.end(), s.begin(), [](wchar_t input) { return std::wstring(L"aeiou").find(input) != std::wstring::npos ? 'x' : input; }); 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) + v.erase(std::remove_if(v.begin(), v.end(), [](double input) { return is_invalid(input); }), v.end()); Assert::AreEqual(5u, v.size()); Assert::AreEqual(8., v[0]); Assert::AreEqual(99., v[4]); @@ -138,19 +163,20 @@ TEST_CLASS(test_standard_algorithms_usage) TEST_METHOD(test_08b) { std::wstring s(L"ponedjeljak"); - // TODO: delete all vowels + s.erase(std::remove_if(s.begin(), s.end(), [](wchar_t input) { return std::wstring(L"aeiou").find(input) != std::wstring::npos; }), s.end()); 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 + std::sort(v.begin(), v.end(), [](const exam& input1, const exam& input2) { return input1.grade > input2.grade || input1.points > input2.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 @@ -164,12 +190,13 @@ TEST_CLASS(test_standard_algorithms_usage) using namespace std::chrono; auto t1 = steady_clock::now(); - // TODO: put median value in the middle of vector. fast. + 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_10b) { struct employee { std::wstring name; int salary; }; @@ -178,19 +205,22 @@ TEST_CLASS(test_standard_algorithms_usage) 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_12) + { + std::vector v{ 11, 0.5, -97.23, -23.11, 48.78, 22.96, -77 }; + auto smallest_value = std::accumulate(v.begin(), v.end(), DBL_MAX, [](double prev, double input) { return input < prev ? input : prev; }); + Assert::AreEqual(-97.23, smallest_value); + auto largest_value = std::accumulate(v.begin(), v.end(), DBL_MIN, [](double prev, double input) { return input > prev ? input : prev; }); + Assert::AreEqual(48.78, largest_value); + } + + TEST_METHOD(test_13) + { + std::vector atp_points{ 8445, 7480, 6220, 5300, 5285 }; + std::vector result; + adjacent_difference(atp_points.begin(), atp_points.end(), std::back_inserter(result), [](int x, int y) {return abs(x-y); }); + auto smallest_difference = *std::min_element(result.begin(), result.end()); + Assert::AreEqual(15, smallest_difference); + } };