Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions exercise/01/containers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "containers.h"
#include <set>
#include <iostream>

void remove_element(std::vector<int>& v, int index)
{
v.erase(v.begin() + index);
}

void input_element(std::vector<std::wstring>& v, int index, const std::wstring & value)
{
v.insert(v.begin() + index, value);
}

int list_nth_element(const std::list<int>& c, int index)
{
std::list<int>::const_iterator it = c.begin();
std::advance(it, index);
return *it;
}

void list_sort_desc(std::list<int>& c)
{
c.sort();
c.reverse();
}

int unique_numbers(std::wistream& stream)
{
int n;
std::set<int> 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);
}
4 changes: 4 additions & 0 deletions exercise/01/containers.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <string>
#include <vector>
#include <list>
#include <map>

void remove_element(std::vector<int>& v, int index);
void input_element(std::vector<std::wstring>& v, int index, const std::wstring& value);
Expand All @@ -17,4 +18,7 @@ class word_frequency
word_frequency(std::wistream&);
int frequency(const std::wstring& s);
int count();
private:
std::map<std::wstring, int> map_of_words;
void to_lower(std::wstring& word) const;
};
86 changes: 59 additions & 27 deletions exercise/02/algorithms_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,53 @@ using namespace Microsoft::VisualStudio::CppUnitTestFramework;
#include <numeric>
#include <chrono>

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<double>::epsilon();
}
}

TEST_CLASS(test_standard_algorithms_usage)
{
public:
TEST_METHOD(test_01)
{
std::wstringstream ss(L"14 -78 22");
std::vector<int> v;
// TODO: read values from input stream into vector

std::istream_iterator<int, wchar_t> 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<int> v(10);
// TODO: fill vector with incremental values
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
std::vector<int> 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]);
Expand All @@ -46,88 +64,97 @@ TEST_CLASS(test_standard_algorithms_usage)
TEST_METHOD(test_03a)
{
std::vector<int> 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]);
Assert::AreEqual(1000, v[2]);
}

TEST_METHOD(test_03b)
{
int x[] = { 3, 5, 10 };
std::vector<int> y = { 4, 12, 10 };
std::vector<double> 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
std::istream_iterator<double, wchar_t> it(ss), end;
auto res = std::accumulate(it, end, 0.0);
Assert::AreEqual(7.5, res);
}

TEST_METHOD(test_04b)
{
std::vector<std::wstring> 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 "));
Assert::AreEqual(L"GO AVL!", res.c_str());
}

TEST_METHOD(test_04c)
{
struct person { std::wstring name; int age; };
std::vector<person> v{ {L"Pero", 33}, {L"Iva", 25} };
auto total_age = // TODO: sum of all ages
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<int> v { -5, 8, 11, 0, -9, 77, -4 };
auto number_of_negative = // TODO:
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<double> v { 1.5, 8, -11.23, 0, 1e10, 1e10, 1e10, 0, 99 };
auto number_of_invalid = // TODO:
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<point> v{ {1,1}, {-5,3}, {2,2}, {-7,-6}, {9,-4} };
auto number_in_first_quadrant = // TODO:
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<int> v { 33, 16, 24, 41, 25, 19, 9 };
auto first_prime = // TODO:
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<double> 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<double> 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]);
Expand All @@ -136,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<exam> 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
Expand All @@ -162,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<milliseconds>(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; };
Expand All @@ -176,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<double> v{ 11, 0.5, -97.23, -23.11, 48.78, 22.96, -77 };
auto smallest_value = // TODO:
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 = // TODO:
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<int> atp_points { 8445, 7480, 6220, 5300, 5285 };
// the most interesting match is the one with the smallest difference
auto smallest_difference = // TODO:
std::vector<int> atp_points{ 8445, 7480, 6220, 5300, 5285 };
std::vector<int> 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);
}
};