From bc13caeac1ab0831902b581ba26a49f9369cbd10 Mon Sep 17 00:00:00 2001 From: eshulankina Date: Fri, 15 Dec 2017 21:02:53 +0300 Subject: [PATCH 1/7] Added several Arutyunyan R. task solutions --- tasks/arutyunyan_task/task.cpp | 158 +++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 tasks/arutyunyan_task/task.cpp diff --git a/tasks/arutyunyan_task/task.cpp b/tasks/arutyunyan_task/task.cpp new file mode 100644 index 0000000..190c8a6 --- /dev/null +++ b/tasks/arutyunyan_task/task.cpp @@ -0,0 +1,158 @@ +/* Задан массив целых чисел (тип int). Нужно найти, если ли в массиве такое число, что количество чисел меньших данного числа равно заданному числу. Искомое число должно быть максимальным. +Примеры: +[1,1,1,3] - ответ 3 (ровно 3 числа меньше трех) +[1,3,1,1] - ответ 3 +[0,3,1,2] - ответ 3 (одно число меньше единицы, два числа меньше двойки и три числа меньше тройки, но тройка максимальная из них, поэтому ответ три) +[12,1,6] - ответ 0 +[1] - ответ 0 +[1,1] - ответ 0 +*/ + +#include +#include +#include +#include +#include + +namespace SimpleSolution +{ + int32_t run(std::vector v) + { + if (v.size() < 2) + { + return 0; + } + + std::sort(v.begin(), v.end()); + + for (auto index = v.size() - 1; index > 0; --index) + { + if (v[index] == index && v[index - 1] != index) + { + return v[index]; + } + } + + return 0; + } +} + +namespace BinaryHeapSolution +{ + int32_t run(std::vector v) + { + if (v.size() < 2) + { + return 0; + } + + std::make_heap(v.begin(), v.end()); + + while (v.size() > 2) + { + if (v[0] == v.size() - 1 && v[0] != v[1] && v[0] != v[2]) + { + return v[0]; + } + std::pop_heap(v.begin(), v.end()); + v.pop_back(); + } + + if ((v[0] != v[1]) && (v[0] == 1 || v[1] == 1)) return 1; + + return 0; + } +} + +namespace MultisetSolution +{ + int32_t run(const std::vector& values) + { + // O(n*log(n)) + std::multiset> sortValues(values.cbegin(), values.cend()); + + // O(n) + int prevElemCount = sortValues.size() - 1; + for (auto it = sortValues.begin(); it != sortValues.end(); ++it, --prevElemCount) + { + auto isLast(prevElemCount == 0); + auto nextIt = std::next(it); + if (*it == prevElemCount && (isLast || *it != *nextIt)) + { + return *it; + } + } + return 0; + } +}; + +namespace IndexOrientedSolution +{ + int32_t run(const std::vector& values) + { + if (values.empty()) + { + return 0; + } + + auto size(values.size()); + auto totalCount(size); + std::vector valueCounts(size); + // O(n) + for (auto val : values) + { + if (val < 0 || val < size) + { + val = val < 0 ? 0 : val; + ++valueCounts[val]; + } + else + { + --totalCount; + } + } + + // O(n) + for (auto i = valueCounts.size() - 1; i > 0; --i) + { + if (valueCounts[i] > 0) + { + totalCount -= valueCounts[i]; + if (i == totalCount) + { + return i; + } + } + } + return 0; + } +}; + + +int main() +{ + std::vector> testValues = { + { 4, 5, 3, 3, 3, 3, 3, 7, 7 }, + { 5, -1, 4, 7, -1, 4, 17, 6, 1, 3 }, + { -1 }, + { 0 }, + { -4, -3, -2, -1, 5, 5, 5, -1 }, + { 1, 1, 1, 1, 1 }, + { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + { 17, 17, 17 } + }; + + std::vector testResults = { 7, 4, 0, 0, 5, 0, 10, 0 }; + + for (auto i = 0; i < testValues.size(); ++i) + { + auto s_v = SimpleSolution::run(testValues[i]); + assert(s_v == testResults[i]); + auto m_v = MultisetSolution::run(testValues[i]); + assert(m_v == testResults[i]); + auto b_v = BinaryHeapSolution::run(testValues[i]); + assert(b_v == testResults[i]); + auto i_v = IndexOrientedSolution::run(testValues[i]); + assert(i_v == testResults[i]); + } +} \ No newline at end of file From ed6082fa400c7e9cf29c567186fa766955b9d5d9 Mon Sep 17 00:00:00 2001 From: eshulankina Date: Sat, 16 Dec 2017 14:24:56 +0300 Subject: [PATCH 2/7] added perfomance tests --- tasks/arutyunyan_task/measure.h | 18 +++++++++ tasks/arutyunyan_task/task.cpp | 67 ++++++++++++++++++++++++++++----- 2 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 tasks/arutyunyan_task/measure.h diff --git a/tasks/arutyunyan_task/measure.h b/tasks/arutyunyan_task/measure.h new file mode 100644 index 0000000..3605233 --- /dev/null +++ b/tasks/arutyunyan_task/measure.h @@ -0,0 +1,18 @@ +#pragma once +#include + +namespace measure +{ + template + static std::chrono::milliseconds::rep execution(F func, Args&&... args) + { + auto start = std::chrono::system_clock::now(); + + func(std::forward(args)...); + + auto duration = std::chrono::duration_cast + (std::chrono::system_clock::now() - start); + + return duration.count(); + } +}; \ No newline at end of file diff --git a/tasks/arutyunyan_task/task.cpp b/tasks/arutyunyan_task/task.cpp index 190c8a6..26989c9 100644 --- a/tasks/arutyunyan_task/task.cpp +++ b/tasks/arutyunyan_task/task.cpp @@ -1,11 +1,11 @@ -/* Задан массив целых чисел (тип int). Нужно найти, если ли в массиве такое число, что количество чисел меньших данного числа равно заданному числу. Искомое число должно быть максимальным. -Примеры: -[1,1,1,3] - ответ 3 (ровно 3 числа меньше трех) -[1,3,1,1] - ответ 3 -[0,3,1,2] - ответ 3 (одно число меньше единицы, два числа меньше двойки и три числа меньше тройки, но тройка максимальная из них, поэтому ответ три) -[12,1,6] - ответ 0 -[1] - ответ 0 -[1,1] - ответ 0 +/* ����� ������ ����� ����� (��� int). ����� �����, ���� �� � ������� ����� �����, ��� ���������� ����� ������� ������� ����� ����� ��������� �����. ������� ����� ������ ���� ������������. +�������: +[1,1,1,3] - ����� 3 (����� 3 ����� ������ ����) +[1,3,1,1] - ����� 3 +[0,3,1,2] - ����� 3 (���� ����� ������ �������, ��� ����� ������ ������ � ��� ����� ������ ������, �� ������ ������������ �� ���, ������� ����� ���) +[12,1,6] - ����� 0 +[1] - ����� 0 +[1,1] - ����� 0 */ #include @@ -13,6 +13,8 @@ #include #include #include +#include +#include "measure.h" namespace SimpleSolution { @@ -68,6 +70,11 @@ namespace MultisetSolution { int32_t run(const std::vector& values) { + if (values.size() < 2) + { + return 0; + } + // O(n*log(n)) std::multiset> sortValues(values.cbegin(), values.cend()); @@ -90,7 +97,7 @@ namespace IndexOrientedSolution { int32_t run(const std::vector& values) { - if (values.empty()) + if (values.size() < 2) { return 0; } @@ -131,6 +138,7 @@ namespace IndexOrientedSolution int main() { + // correctness tests std::vector> testValues = { { 4, 5, 3, 3, 3, 3, 3, 7, 7 }, { 5, -1, 4, 7, -1, 4, 17, 6, 1, 3 }, @@ -155,4 +163,45 @@ int main() auto i_v = IndexOrientedSolution::run(testValues[i]); assert(i_v == testResults[i]); } + + // performance tests + testValues.clear(); + std::vector bigVector; + for (int i = 0; i < 10000000; ++i) + bigVector.push_back(i); + + // ascending order + testValues.push_back(bigVector); + + // descending order + std::reverse(bigVector.begin(), bigVector.end()); + testValues.push_back(bigVector); + + // random order + std::random_shuffle(bigVector.begin(), bigVector.end()); + testValues.push_back(bigVector); + + // randor order + std::random_shuffle(bigVector.begin(), bigVector.end()); + testValues.push_back(bigVector); + + // randor order + std::random_shuffle(bigVector.begin(), bigVector.end()); + testValues.push_back(bigVector); + + // randor order + std::random_shuffle(bigVector.begin(), bigVector.end()); + testValues.push_back(bigVector); + for (auto i = 0; i < testValues.size(); ++i) + { + std::cout << "\nTest #" << i << "\n"; + auto time = measure::execution(SimpleSolution::run, testValues[i]); + std::cout << "SimpleSolution: " << time << "s \n"; + time = measure::execution(MultisetSolution::run, testValues[i]); + std::cout << "MultisetSolution: " << time << "s \n"; + time = measure::execution(BinaryHeapSolution::run, testValues[i]); + std::cout << "BinaryHeapSolution: " << time << "s \n"; + time = measure::execution(IndexOrientedSolution::run, testValues[i]); + std::cout << "IndexOrientedSolution: " << time << "s \n"; + } } \ No newline at end of file From c161961b8bf648deb8ea4552efd9953942178a2c Mon Sep 17 00:00:00 2001 From: eshulankina Date: Sat, 16 Dec 2017 14:27:49 +0300 Subject: [PATCH 3/7] fixed typo in comments --- tasks/arutyunyan_task/task.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tasks/arutyunyan_task/task.cpp b/tasks/arutyunyan_task/task.cpp index 26989c9..aed9d09 100644 --- a/tasks/arutyunyan_task/task.cpp +++ b/tasks/arutyunyan_task/task.cpp @@ -1,11 +1,11 @@ -/* ����� ������ ����� ����� (��� int). ����� �����, ���� �� � ������� ����� �����, ��� ���������� ����� ������� ������� ����� ����� ��������� �����. ������� ����� ������ ���� ������������. -�������: -[1,1,1,3] - ����� 3 (����� 3 ����� ������ ����) -[1,3,1,1] - ����� 3 -[0,3,1,2] - ����� 3 (���� ����� ������ �������, ��� ����� ������ ������ � ��� ����� ������ ������, �� ������ ������������ �� ���, ������� ����� ���) -[12,1,6] - ����� 0 -[1] - ����� 0 -[1,1] - ����� 0 +/* Задан массив целых чисел (тип int). Нужно найти, если ли в массиве такое число, что количество чисел меньших данного числа равно заданному числу. Искомое число должно быть максимальным. +Примеры: +[1,1,1,3] - ответ 3 (ровно 3 числа меньше трех) +[1,3,1,1] - ответ 3 +[0,3,1,2] - ответ 3 (одно число меньше единицы, два числа меньше двойки и три числа меньше тройки, но тройка максимальная из них, поэтому ответ три) +[12,1,6] - ответ 0 +[1] - ответ 0 +[1,1] - ответ 0 */ #include @@ -181,15 +181,15 @@ int main() std::random_shuffle(bigVector.begin(), bigVector.end()); testValues.push_back(bigVector); - // randor order + // random order std::random_shuffle(bigVector.begin(), bigVector.end()); testValues.push_back(bigVector); - // randor order + // random order std::random_shuffle(bigVector.begin(), bigVector.end()); testValues.push_back(bigVector); - // randor order + // random order std::random_shuffle(bigVector.begin(), bigVector.end()); testValues.push_back(bigVector); for (auto i = 0; i < testValues.size(); ++i) From b47194884660263b3860657a4e8f22e7c94d8cfb Mon Sep 17 00:00:00 2001 From: Pronina Date: Mon, 18 Dec 2017 05:08:24 +0300 Subject: [PATCH 4/7] Moved BinarySolution and a little changed. Reworked performance tests --- tasks/arutyunyan_task/measure.h | 48 +++++++ tasks/arutyunyan_task/task.cpp | 245 ++++++++++++++++++++++++++++++++ 2 files changed, 293 insertions(+) create mode 100644 tasks/arutyunyan_task/measure.h create mode 100644 tasks/arutyunyan_task/task.cpp diff --git a/tasks/arutyunyan_task/measure.h b/tasks/arutyunyan_task/measure.h new file mode 100644 index 0000000..960083a --- /dev/null +++ b/tasks/arutyunyan_task/measure.h @@ -0,0 +1,48 @@ +#pragma once +#include +#include + +namespace measure +{ + namespace chrono + { + template + static std::chrono::milliseconds::rep execution(int32_t count, F func, Args&&... args) + { + std::chrono::milliseconds::rep times_average = 0; + + for (int i = 0; i < count; ++i) + { + auto start = std::chrono::system_clock::now(); + + func(std::forward(args)...); + + times_average += std::chrono::duration_cast + (std::chrono::system_clock::now() - start).count(); + } + + return times_average / count; + } + } +#if defined(_OPENMP) + namespace omp + { + template + static double execution(int32_t count, F func, Args&&... args) + { + double times_average = 0.; + for (int i = 0; i < count; ++i) + { + auto start = omp_get_wtime(); + + func(std::forward(args)...); + + times_average += omp_get_wtime() - start; + } + + return (times_average / count) * 1000; + } + } +#endif +} + diff --git a/tasks/arutyunyan_task/task.cpp b/tasks/arutyunyan_task/task.cpp new file mode 100644 index 0000000..8defe37 --- /dev/null +++ b/tasks/arutyunyan_task/task.cpp @@ -0,0 +1,245 @@ +/* Задан массив целых чисел (тип int). Нужно найти, если ли в массиве такое число, что количество чисел меньших данного числа равно заданному числу. Искомое число должно быть максимальным. +Примеры: +[1,1,1,3] - ответ 3 (ровно 3 числа меньше трех) +[1,3,1,1] - ответ 3 +[0,3,1,2] - ответ 3 (одно число меньше единицы, два числа меньше двойки и три числа меньше тройки, но тройка максимальная из них, поэтому ответ три) +[12,1,6] - ответ 0 +[1] - ответ 0 +[1,1] - ответ 0 +*/ + +#include +#include +#include +#include +#include +#include +#include "measure.h" + +namespace SimpleSolution +{ + int32_t run(std::vector v) + { + if (v.size() < 2) + { + return 0; + } + + //O(nlog(n)) + std::sort(v.begin(), v.end()); + + //O(n) + for (auto index = v.size() - 1; index > 0; --index) + { + if (v[index] == index && v[index - 1] != index) + { + return v[index]; + } + } + + return 0; + } +} + +namespace MultisetSolution +{ + int32_t run(const std::vector& values) + { + if (values.size() < 2) + { + return 0; + } + + // O(n*log(n)) + std::multiset> sortValues(values.cbegin(), values.cend()); + + // O(n) + int prevElemCount = sortValues.size() - 1; + for (auto it = sortValues.begin(); it != sortValues.end(); ++it, --prevElemCount) + { + auto isLast(prevElemCount == 0); + auto nextIt = std::next(it); + if (*it == prevElemCount && (isLast || *it != *nextIt)) + { + return *it; + } + } + return 0; + } +}; + +namespace BinaryHeapSolution +{ + int32_t run(std::vector v) + { + if (v.size() < 2) + { + return 0; + } + else if (v.size() == 2) + { + int32_t el; + if (((el = (v[0] > v[1] ? v[0] : v[1]))) == 1 && v[0] != v[1]) + { + return 1; + } + } + else + { + //O(n) + std::make_heap(v.begin(), v.end()); + + //O(n*log(n)) + while (v.size() > 2) + { + if (v[0] == v.size() - 1 && v[0] != v[1] && v[0] != v[2]) + { + return v[0]; + } + //O(log(n)) + std::pop_heap(v.begin(), v.end()); + //O(1) + v.pop_back(); + } + } + return 0; + } +} + +namespace IndexOrientedSolution +{ + int32_t run(const std::vector& values) + { + if (values.size() < 2) + { + return 0; + } + + auto size(values.size()); + auto totalCount(size); + std::vector valueCounts(size); + // O(n) + for (auto val : values) + { + if (val < 0 || val < size) + { + val = val < 0 ? 0 : val; + ++valueCounts[val]; + } + else + { + --totalCount; + } + } + + // O(n) + for (auto i = valueCounts.size() - 1; i > 0; --i) + { + if (valueCounts[i] > 0) + { + totalCount -= valueCounts[i]; + if (i == totalCount) + { + return i; + } + } + } + return 0; + } +}; + + +int main() +{ + // correctness tests + std::vector> testValues = { + { 4, 5, 3, 3, 3, 3, 3, 7, 7 }, + { 5, -1, 4, 7, -1, 4, 17, 6, 1, 3 }, + { -1 }, + { 0 }, + { -4, -3, -2, -1, 5, 5, 5, -1 }, + { 1, 1, 1, 1, 1 }, + { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + { 17, 17, 17 } + }; + + std::vector testResults = { 7, 4, 0, 0, 5, 0, 10, 0 }; + + for (auto i = 0; i < testValues.size(); ++i) + { + auto s_v = SimpleSolution::run(testValues[i]); + assert(s_v == testResults[i]); + auto m_v = MultisetSolution::run(testValues[i]); + assert(m_v == testResults[i]); + auto b_v = BinaryHeapSolution::run(testValues[i]); + assert(b_v == testResults[i]); + auto i_v = IndexOrientedSolution::run(testValues[i]); + assert(i_v == testResults[i]); + } + + // performance tests + testValues.clear(); + std::vector bigVector; + for (int i = 0; i < 10000000; ++i) + bigVector.push_back(i); + + // ascending order + testValues.push_back(bigVector); + + // descending order + std::reverse(bigVector.begin(), bigVector.end()); + testValues.push_back(bigVector); + + // random order + std::random_shuffle(bigVector.begin(), bigVector.end()); + testValues.push_back(bigVector); + + // random order + std::random_shuffle(bigVector.begin(), bigVector.end()); + testValues.push_back(bigVector); + + // random order + std::random_shuffle(bigVector.begin(), bigVector.end()); + testValues.push_back(bigVector); + + // random order + std::random_shuffle(bigVector.begin(), bigVector.end()); + testValues.push_back(bigVector); + + for (auto i = 0; i < testValues.size(); ++i) + { + const int32_t count = 50; + std::cout << "\nTest #" << i << "\n"; + + auto time = measure::chrono::execution(count, SimpleSolution::run, testValues[i]); + std::cout << "SimpleSolution: " << time << " ms \n"; + + time = measure::chrono::execution(count, MultisetSolution::run, testValues[i]); + std::cout << "MultisetSolution: " << time << " ms \n"; + + time = measure::chrono::execution(count, BinaryHeapSolution::run, testValues[i]); + std::cout << "BinaryHeapSolution: " << time << " ms \n"; + + time = measure::chrono::execution(count, IndexOrientedSolution::run, testValues[i]); + std::cout << "IndexOrientedSolution: " << time << " ms \n"; + } +#if defined(_OPENMP) + for (auto i = 0; i < testValues.size(); ++i) + { + const int32_t count = 50; + std::cout << "\nTest #" << i << "\n"; + + auto time = measure::omp::execution(count, SimpleSolution::run, testValues[i]); + std::cout << "SimpleSolution: " << time << " ms \n"; + + time = measure::omp::execution(count, MultisetSolution::run, testValues[i]); + std::cout << "MultisetSolution: " << time << " ms \n"; + + time = measure::omp::execution(count, BinaryHeapSolution::run, testValues[i]); + std::cout << "BinaryHeapSolution: " << time << " ms \n"; + + time = measure::omp::execution(count, IndexOrientedSolution::run, testValues[i]); + std::cout << "IndexOrientedSolution: " << time << " ms \n"; + } +#endif +} \ No newline at end of file From 1c9d85000fd801ae68e00c74e4ff69fdf746d506 Mon Sep 17 00:00:00 2001 From: eshulankina Date: Mon, 18 Dec 2017 13:37:52 +0300 Subject: [PATCH 5/7] added 2 performance tests --- tasks/arutyunyan_task/measure.h | 2 ++ tasks/arutyunyan_task/task.cpp | 63 ++++++++++++++++++--------------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/tasks/arutyunyan_task/measure.h b/tasks/arutyunyan_task/measure.h index 6fa8130..aff470b 100644 --- a/tasks/arutyunyan_task/measure.h +++ b/tasks/arutyunyan_task/measure.h @@ -1,6 +1,8 @@ #pragma once #include +#if defined(_OPENMP) #include +#endif namespace measure { diff --git a/tasks/arutyunyan_task/task.cpp b/tasks/arutyunyan_task/task.cpp index 8defe37..d49a5a0 100644 --- a/tasks/arutyunyan_task/task.cpp +++ b/tasks/arutyunyan_task/task.cpp @@ -178,14 +178,15 @@ int main() } // performance tests + const int32_t N = 1000000; testValues.clear(); std::vector bigVector; - for (int i = 0; i < 10000000; ++i) + for (int i = 0; i < N; ++i) bigVector.push_back(i); // ascending order testValues.push_back(bigVector); - + // descending order std::reverse(bigVector.begin(), bigVector.end()); testValues.push_back(bigVector); @@ -206,40 +207,44 @@ int main() std::random_shuffle(bigVector.begin(), bigVector.end()); testValues.push_back(bigVector); - for (auto i = 0; i < testValues.size(); ++i) - { - const int32_t count = 50; - std::cout << "\nTest #" << i << "\n"; - - auto time = measure::chrono::execution(count, SimpleSolution::run, testValues[i]); - std::cout << "SimpleSolution: " << time << " ms \n"; + // vector with repeated elements + bigVector = std::vector(N, 4); + testValues.push_back(bigVector); - time = measure::chrono::execution(count, MultisetSolution::run, testValues[i]); - std::cout << "MultisetSolution: " << time << " ms \n"; + // vector with repeated elements with values greater than the vector size + bigVector = std::vector(N, N * 2); + testValues.push_back(bigVector); - time = measure::chrono::execution(count, BinaryHeapSolution::run, testValues[i]); - std::cout << "BinaryHeapSolution: " << time << " ms \n"; + // vector half filled with repeating elements with values greater than the vector size + bigVector = std::vector(N / 2, N * 3); + for (int i = N / 2; i < N; ++i) + { + bigVector.push_back(i); + } + testValues.push_back(bigVector); - time = measure::chrono::execution(count, IndexOrientedSolution::run, testValues[i]); - std::cout << "IndexOrientedSolution: " << time << " ms \n"; + std::cout << "Chrono\n"; + std::cout << "\t\tSimple\t\tM-Set\t\tBinHeap\t\tIndexOr-d\t\t\n\n"; + const int32_t count = 50; + for (auto i = 0; i < testValues.size(); ++i) + { + std::cout << i << "\t\t"; + std::cout << measure::chrono::execution(count, SimpleSolution::run, testValues[i]) << "ms \t\t" + << measure::chrono::execution(count, MultisetSolution::run, testValues[i]) << "ms \t\t" + << measure::chrono::execution(count, BinaryHeapSolution::run, testValues[i]) << "ms \t\t" + << measure::chrono::execution(count, IndexOrientedSolution::run, testValues[i]) << "ms \t\t\n"; } + #if defined(_OPENMP) + std::cout << "OMP\n"; + std::cout << "\t\tSimple\t\tM-Set\t\tBinHeap\t\tIndexOr-d\t\t\n\n"; for (auto i = 0; i < testValues.size(); ++i) { - const int32_t count = 50; - std::cout << "\nTest #" << i << "\n"; - - auto time = measure::omp::execution(count, SimpleSolution::run, testValues[i]); - std::cout << "SimpleSolution: " << time << " ms \n"; - - time = measure::omp::execution(count, MultisetSolution::run, testValues[i]); - std::cout << "MultisetSolution: " << time << " ms \n"; - - time = measure::omp::execution(count, BinaryHeapSolution::run, testValues[i]); - std::cout << "BinaryHeapSolution: " << time << " ms \n"; - - time = measure::omp::execution(count, IndexOrientedSolution::run, testValues[i]); - std::cout << "IndexOrientedSolution: " << time << " ms \n"; + std::cout << i << "\t\t"; + std::cout << measure::omp::execution(count, SimpleSolution::run, testValues[i]) << "ms \t\t" + << measure::omp::execution(count, MultisetSolution::run, testValues[i]) << "ms \t\t" + << measure::omp::execution(count, BinaryHeapSolution::run, testValues[i]) << "ms \t\t" + << measure::omp::execution(count, IndexOrientedSolution::run, testValues[i]) << "ms \t\t\n"; } #endif } \ No newline at end of file From 86b0b397d20c0f30b17f5bd2973f6796e0eaf7c7 Mon Sep 17 00:00:00 2001 From: eshulankina Date: Mon, 18 Dec 2017 13:45:15 +0300 Subject: [PATCH 6/7] updated the vector element count for performance tests --- tasks/arutyunyan_task/task.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/arutyunyan_task/task.cpp b/tasks/arutyunyan_task/task.cpp index d49a5a0..c5f5900 100644 --- a/tasks/arutyunyan_task/task.cpp +++ b/tasks/arutyunyan_task/task.cpp @@ -178,7 +178,7 @@ int main() } // performance tests - const int32_t N = 1000000; + const int32_t N = 10000000; testValues.clear(); std::vector bigVector; for (int i = 0; i < N; ++i) From 440bfc32a26ddf953c9436c8c40cf59a2f4ea4ab Mon Sep 17 00:00:00 2001 From: eshulankina Date: Mon, 18 Dec 2017 23:04:56 +0300 Subject: [PATCH 7/7] changed correctness test container from vector to map --- tasks/arutyunyan_task/Makefile.txt | 2 + tasks/arutyunyan_task/task.cpp | 85 +++++++++++++++--------------- 2 files changed, 45 insertions(+), 42 deletions(-) create mode 100644 tasks/arutyunyan_task/Makefile.txt diff --git a/tasks/arutyunyan_task/Makefile.txt b/tasks/arutyunyan_task/Makefile.txt new file mode 100644 index 0000000..13227c9 --- /dev/null +++ b/tasks/arutyunyan_task/Makefile.txt @@ -0,0 +1,2 @@ +task: task.cpp + g++ -o task task.cpp -O2 -std=c++11 -fopenmp diff --git a/tasks/arutyunyan_task/task.cpp b/tasks/arutyunyan_task/task.cpp index c5f5900..13c7d38 100644 --- a/tasks/arutyunyan_task/task.cpp +++ b/tasks/arutyunyan_task/task.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "measure.h" namespace SimpleSolution @@ -121,9 +122,9 @@ namespace IndexOrientedSolution // O(n) for (auto val : values) { - if (val < 0 || val < size) + val = val < 0 ? 0 : val; + if (val < size) { - val = val < 0 ? 0 : val; ++valueCounts[val]; } else @@ -152,68 +153,68 @@ namespace IndexOrientedSolution int main() { // correctness tests - std::vector> testValues = { - { 4, 5, 3, 3, 3, 3, 3, 7, 7 }, - { 5, -1, 4, 7, -1, 4, 17, 6, 1, 3 }, - { -1 }, - { 0 }, - { -4, -3, -2, -1, 5, 5, 5, -1 }, - { 1, 1, 1, 1, 1 }, - { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, - { 17, 17, 17 } + std::map, int32_t> correctnessTests = { + { { 4, 5, 3, 3, 3, 3, 3, 7, 7 }, 7 }, + { { 5, -1, 4, 7, -1, 4, 17, 6, 1, 3 }, 4 }, + { { -1 }, 0 }, + { { 0 }, 0 }, + { { -4, -3, -2, -1, 5, 5, 5, -1 }, 5 }, + { { 1, 1, 1, 1, 1 }, 0 }, + { { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, 10 }, + { { 17, 17, 17 }, 0 } }; - std::vector testResults = { 7, 4, 0, 0, 5, 0, 10, 0 }; - - for (auto i = 0; i < testValues.size(); ++i) + for (const auto& it : correctnessTests) { - auto s_v = SimpleSolution::run(testValues[i]); - assert(s_v == testResults[i]); - auto m_v = MultisetSolution::run(testValues[i]); - assert(m_v == testResults[i]); - auto b_v = BinaryHeapSolution::run(testValues[i]); - assert(b_v == testResults[i]); - auto i_v = IndexOrientedSolution::run(testValues[i]); - assert(i_v == testResults[i]); + const auto& test = it.first; + const auto& result = it.second; + auto s_v = SimpleSolution::run(test); + assert(s_v == result); + auto m_v = MultisetSolution::run(test); + assert(m_v == result); + auto b_v = BinaryHeapSolution::run(test); + assert(b_v == result); + auto i_v = IndexOrientedSolution::run(test); + assert(i_v == result); } // performance tests const int32_t N = 10000000; - testValues.clear(); + std::vector > performanceTests; std::vector bigVector; for (int i = 0; i < N; ++i) bigVector.push_back(i); // ascending order - testValues.push_back(bigVector); + performanceTests.push_back(bigVector); // descending order std::reverse(bigVector.begin(), bigVector.end()); - testValues.push_back(bigVector); + performanceTests.push_back(bigVector); // random order std::random_shuffle(bigVector.begin(), bigVector.end()); - testValues.push_back(bigVector); + performanceTests.push_back(bigVector); // random order std::random_shuffle(bigVector.begin(), bigVector.end()); - testValues.push_back(bigVector); + performanceTests.push_back(bigVector); // random order std::random_shuffle(bigVector.begin(), bigVector.end()); - testValues.push_back(bigVector); + performanceTests.push_back(bigVector); // random order std::random_shuffle(bigVector.begin(), bigVector.end()); - testValues.push_back(bigVector); + performanceTests.push_back(bigVector); // vector with repeated elements bigVector = std::vector(N, 4); - testValues.push_back(bigVector); + performanceTests.push_back(bigVector); // vector with repeated elements with values greater than the vector size bigVector = std::vector(N, N * 2); - testValues.push_back(bigVector); + performanceTests.push_back(bigVector); // vector half filled with repeating elements with values greater than the vector size bigVector = std::vector(N / 2, N * 3); @@ -221,30 +222,30 @@ int main() { bigVector.push_back(i); } - testValues.push_back(bigVector); + performanceTests.push_back(bigVector); std::cout << "Chrono\n"; std::cout << "\t\tSimple\t\tM-Set\t\tBinHeap\t\tIndexOr-d\t\t\n\n"; const int32_t count = 50; - for (auto i = 0; i < testValues.size(); ++i) + for (auto i = 0; i < performanceTests.size(); ++i) { std::cout << i << "\t\t"; - std::cout << measure::chrono::execution(count, SimpleSolution::run, testValues[i]) << "ms \t\t" - << measure::chrono::execution(count, MultisetSolution::run, testValues[i]) << "ms \t\t" - << measure::chrono::execution(count, BinaryHeapSolution::run, testValues[i]) << "ms \t\t" - << measure::chrono::execution(count, IndexOrientedSolution::run, testValues[i]) << "ms \t\t\n"; + std::cout << measure::chrono::execution(count, SimpleSolution::run, performanceTests[i]) << "ms \t\t" + << measure::chrono::execution(count, MultisetSolution::run, performanceTests[i]) << "ms \t\t" + << measure::chrono::execution(count, BinaryHeapSolution::run, performanceTests[i]) << "ms \t\t" + << measure::chrono::execution(count, IndexOrientedSolution::run, performanceTests[i]) << "ms \t\t\n"; } #if defined(_OPENMP) std::cout << "OMP\n"; std::cout << "\t\tSimple\t\tM-Set\t\tBinHeap\t\tIndexOr-d\t\t\n\n"; - for (auto i = 0; i < testValues.size(); ++i) + for (auto i = 0; i < performanceTests.size(); ++i) { std::cout << i << "\t\t"; - std::cout << measure::omp::execution(count, SimpleSolution::run, testValues[i]) << "ms \t\t" - << measure::omp::execution(count, MultisetSolution::run, testValues[i]) << "ms \t\t" - << measure::omp::execution(count, BinaryHeapSolution::run, testValues[i]) << "ms \t\t" - << measure::omp::execution(count, IndexOrientedSolution::run, testValues[i]) << "ms \t\t\n"; + std::cout << measure::omp::execution(count, SimpleSolution::run, performanceTests[i]) << "ms \t\t" + << measure::omp::execution(count, MultisetSolution::run, performanceTests[i]) << "ms \t\t" + << measure::omp::execution(count, BinaryHeapSolution::run, performanceTests[i]) << "ms \t\t" + << measure::omp::execution(count, IndexOrientedSolution::run, performanceTests[i]) << "ms \t\t\n"; } #endif } \ No newline at end of file