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
53 changes: 53 additions & 0 deletions exercise/01/containers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "containers.h"
#include <map>
#include <set>

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

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

int list_nth_element(const std::list<int>& 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<int>& c) {
c.sort(cmp);
}

int unique_numbers(std::wistream& stream) {
std::wstring str;
std::set<std::wstring> 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();
}
2 changes: 2 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 @@ -13,6 +14,7 @@ int unique_numbers(std::wistream&);

class word_frequency
{
std::map<std::wstring, int> string_map_;
public:
word_frequency(std::wistream&);
int frequency(const std::wstring& s);
Expand Down
4 changes: 2 additions & 2 deletions exercise/01/containers_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
106 changes: 63 additions & 43 deletions exercise/02/algorithms_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ TEST_CLASS(test_standard_algorithms_usage)
{
std::wstringstream ss(L"14 -78 22");
std::vector<int> v;
// TODO: read values from input stream into vector
using it_type = std::istream_iterator<int, wchar_t>;
std::copy(it_type(ss), it_type(), std::back_inserter(v));

Assert::AreEqual(3u, v.size());
Assert::AreEqual(14, v[0]);
Expand All @@ -26,130 +27,144 @@ TEST_CLASS(test_standard_algorithms_usage)
TEST_METHOD(test_02a)
{
std::vector<int> 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<int> v(10);
// TODO: fill vector with incremental values (by 2)
int current = -1;
std::generate(v.begin(), v.end(), [&current]() { 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<int> 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<int> y = { 4, 12, 10 };
std::vector<double> d;
std::transform(y.begin(), y.end(), x, std::back_inserter(d), std::hypot<int, int>);

// 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<double, wchar_t>;
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<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 "), std::plus<std::wstring>());

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<person> 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<int> 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<double> 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<point> 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<int> 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<double> 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<double> 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<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(), [](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<double> v(2e7);
Expand All @@ -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<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)
TEST_METHOD(test_10b)
{
struct employee { std::wstring name; int salary; };
std::vector<employee> 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<double> 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<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> 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);
}
};