diff --git a/exercise/01/containers.cpp b/exercise/01/containers.cpp new file mode 100644 index 0000000..5acd830 --- /dev/null +++ b/exercise/01/containers.cpp @@ -0,0 +1,53 @@ +#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; +} + +bool cmp(const int &a, const int &b) { + return a > b; +} + +void list_sort_desc(std::list& c) { + c.sort(cmp); +} + +int unique_numbers(std::wistream& stream) { + std::wstring str; + std::set unique; + while (stream >> str) + unique.insert(str); + return unique.size(); +} + +word_frequency::word_frequency(std::wistream& stream) { + std::wstring word; + while (stream >> word) { + for (auto char_it = word.begin(); char_it < word.end(); ++char_it) + *char_it = tolower(*char_it); + string_map_[word]++; + } +} + +int word_frequency::frequency(const std::wstring& s) { + auto it = string_map_.find(s); + return it != string_map_.end() + ? it->second + : 0; +} + +int word_frequency::count() { + return string_map_.size(); +} diff --git a/exercise/01/containers.h b/exercise/01/containers.h index 8e1b172..2afe483 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,7 @@ int unique_numbers(std::wistream&); class word_frequency { + std::map string_map_; public: word_frequency(std::wistream&); int frequency(const std::wstring& s); diff --git a/exercise/01/containers_test.cpp b/exercise/01/containers_test.cpp index 4261d42..550b24d 100644 --- a/exercise/01/containers_test.cpp +++ b/exercise/01/containers_test.cpp @@ -40,14 +40,14 @@ TEST_CLASS(test_standard_containers_usage) Assert::IsTrue(std::is_sorted(c.rbegin(), c.rend())); } - TEST_METHOD(unique_values_test) + TEST_METHOD(unique_values_test) { Assert::AreEqual(5, unique_numbers(std::wstringstream(L"-9 -7 -5 -3 -1"))); Assert::AreEqual(3, unique_numbers(std::wstringstream(L"1 2 3 2 3 2 1 2 3"))); Assert::AreEqual(2, unique_numbers(std::wstringstream(L"0 1 1 0 0 1 0"))); } - TEST_METHOD(word_frequency_test) + TEST_METHOD(word_frequency_test) { std::wstringstream ss(L"Lorem ipsum dolor sit amet lorem ipsum dolor"); word_frequency h(ss); diff --git a/exercise/02/algorithms_test.cpp b/exercise/02/algorithms_test.cpp index 9df3595..c848be6 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 + using it_type = std::istream_iterator; + std::copy(it_type(ss), it_type(), std::back_inserter(v)); Assert::AreEqual(3u, v.size()); Assert::AreEqual(14, v[0]); @@ -26,130 +27,144 @@ TEST_CLASS(test_standard_algorithms_usage) 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) + TEST_METHOD(test_02b) { // generate std::vector v(10); - // TODO: fill vector with incremental values (by 2) + int current = -1; + std::generate(v.begin(), v.end(), [¤t]() { return current += 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) + 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 current) { return current*current*current; }); Assert::AreEqual(3u, v.size()); Assert::AreEqual(1, v[0]); Assert::AreEqual(125, v[1]); Assert::AreEqual(1000, v[2]); } - TEST_METHOD(test_03b) + TEST_METHOD(test_03b) { int x[] = { 3, 5, 10 }; std::vector y = { 4, 12, 10 }; std::vector d; + std::transform(y.begin(), y.end(), x, std::back_inserter(d), std::hypot); - // 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) + TEST_METHOD(test_04a) { std::wstringstream ss(L"1.5 2.5 3.5"); - auto res = // TODO: sum of all values in input stream + using it_type = std::istream_iterator; + const auto res = std::accumulate(it_type(ss), it_type(), 0.0); + Assert::AreEqual(7.5, res); } - TEST_METHOD(test_04b) + TEST_METHOD(test_04b) { std::vector v { L"A", L"V", L"L", L"!" }; - auto res = // TODO: concatenated string with additional prefix + auto res = std::accumulate(v.begin(), v.end(), std::wstring(L"GO "), std::plus()); + Assert::AreEqual(L"GO AVL!", res.c_str()); } - TEST_METHOD(test_04c) + 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); + auto total_age = std::accumulate(v.begin(), v.end(), 0, [](int sum, auto& person) { return sum + person.age; }); + + Assert::AreEqual(58, total_age); } - TEST_METHOD(test_05a) + TEST_METHOD(test_05a) { std::vector v { -5, 8, 11, 0, -9, 77, -4 }; - auto number_of_negative = // TODO: + auto number_of_negative = std::count_if(v.begin(), v.end(), [](auto current) { return current < 0; }); Assert::AreEqual(3, number_of_negative); } - TEST_METHOD(test_05b) + TEST_METHOD(test_05b) { std::vector v { 1.5, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99 }; - auto number_of_invalid = // TODO: + auto number_of_invalid = std::count(v.begin(), v.end(), 1e10); Assert::AreEqual(3, number_of_invalid); } - TEST_METHOD(test_05c) + + 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: + auto number_in_first_quadrant = std::count_if(v.begin(), v.end(), [](auto& pt) { return pt.x > 0 && pt.y > 0; }); 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 = // TODO: + + auto fake_is_prime = [](int current) { return current == 41; /* ne da mi se racunati prime! */ }; + auto first_prime = *std::find_if(v.begin(), v.end(), fake_is_prime); Assert::AreEqual(41, first_prime); } - TEST_METHOD(test_07a) + 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.0); + Assert::AreEqual(-1., v[0]); Assert::AreEqual(-1., v[4]); Assert::AreEqual(-1., v[6]); } - TEST_METHOD(test_07b) + TEST_METHOD(test_07b) { std::wstring s(L"ponedjeljak"); - // TODO: change every vowel with x + std::replace_if(s.begin(), s.end(), [](auto ch) {return ch == L'a' || ch == L'e' || ch == L'i' || ch == L'o' || ch == L'o'; }, L'x'); + Assert::AreEqual(L"pxnxdjxljxk", s.c_str()); } - TEST_METHOD(test_08a) + 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) + TEST_METHOD(test_08b) { std::wstring s(L"ponedjeljak"); - // TODO: delete all vowels + s.erase(std::remove_if(s.begin(), s.end(), [](auto ch) { return ch == L'a' || ch == L'e' || ch == L'i' || ch == L'o' || ch == L'o'; }), s.end()); + Assert::AreEqual(L"pndjljk", s.c_str()); } - TEST_METHOD(test_09) + 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(), [](auto& a, auto& b) { return a.grade == b.grade ? a.points > b.points : a.grade > b.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()); - } - TEST_METHOD(test_10a) + TEST_METHOD(test_10a) { // nth_element std::vector v(2e7); @@ -162,33 +177,38 @@ 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. + 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_10b) + 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) + TEST_METHOD(test_12) { std::vector v{ 11, 0.5, -97.23, -23.11, 48.78, 22.96, -77 }; - auto smallest_value = // TODO: + const auto smallest_value = *std::min_element(v.begin(), v.end()); Assert::AreEqual(-97.23, smallest_value); - auto largest_value = // TODO: + const auto largest_value = *std::max_element(v.begin(), v.end()); Assert::AreEqual(48.78, largest_value); } - TEST_METHOD(test_13) + 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: + std::vector buffer; + std::adjacent_difference( + atp_points.cbegin(), + atp_points.cend(), + std::back_inserter(buffer), + [](auto first, auto second) {return std::abs(first - second); }); + auto smallest_difference = *std::min_element(buffer.cbegin() + 1, buffer.cend()); Assert::AreEqual(15, smallest_difference); } };