From 0e4cbb799c3f58931952676b3fa0be94fd2814f5 Mon Sep 17 00:00:00 2001 From: Vahagn Khachatryan Date: Wed, 19 Aug 2020 22:13:39 +0100 Subject: [PATCH] Some training puzzles. --- .../training/max_points_on_a_line.cpp | 116 ++++++++++++++ .../training/multithreaded_queue.cpp | 148 ++++++++++++++++++ .../interviews/training/string_addition.cpp | 84 ++++++++++ 3 files changed, 348 insertions(+) create mode 100644 puzzles/interviews/training/max_points_on_a_line.cpp create mode 100644 puzzles/interviews/training/multithreaded_queue.cpp create mode 100644 puzzles/interviews/training/string_addition.cpp diff --git a/puzzles/interviews/training/max_points_on_a_line.cpp b/puzzles/interviews/training/max_points_on_a_line.cpp new file mode 100644 index 0000000..a0e2788 --- /dev/null +++ b/puzzles/interviews/training/max_points_on_a_line.cpp @@ -0,0 +1,116 @@ +/* +VIM: let b:lcppflags="-std=c++14 -O2 -pthread -I." +VIM: let b:wcppflags="/O2 /EHsc /DWIN32" +*/ +#include "stdafx.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* +https://leetcode.com/problems/max-points-on-a-line/ + +Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. +*/ + +struct Point { + int x; + int y; + Point() : x(0), y(0) {} + Point(int a, int b) : x(a), y(b) {} +}; + +struct pairhash { + std::size_t operator() (const Point& p) const { + return std::hash()(p.x) ^ std::hash()(p.y); + } +}; + +bool operator == (const Point& p1, const Point& p2) { + return p1.x == p2.x && p1.y == p2.y; +} + +Point ratio(int x, int y) { + if (x == 0) { + return Point(0, 1); + } + else if (y == 0) { + return Point(1, 0); + } + else if ( x < 0 ) { + x = -x; + y = -y; + } + + int a = std::max(abs(x), abs(y)); + int b = std::min(abs(x), abs(y)); + for (int c; (c = a % b); a = b, b = c); + return Point(x / b, y / b); +} + +int solve(const std::vector& v) { + + std::unordered_map vv; + for (const auto& p : v) { + vv[p]++; + } + + if (vv.empty()) { + return 0; + } + else if (vv.size()==1) { + return vv.begin()->second; + } + + int max_points = 1; + for (auto i = vv.begin(); i != vv.end(); i++) { + std::unordered_map s; + for (auto j = std::next(i); j != vv.end(); j++) { + const auto line = ratio(i->first.x - j->first.x, i->first.y - j->first.y); + s[line] += j->second; + max_points = std::max(max_points, s[line] + i->second); + } + } + + return max_points; +} + +int main() +{ + try { + auto begin = std::chrono::high_resolution_clock::now(); + + std::cout << solve({ { 1,1 },{ 2,2 },{ 3,3 } }) << std::endl; + std::cout << solve({ { 1,1 },{ 3,2 },{ 5,3 },{ 4,1 },{ 2,3 },{ 1,4 } }) << std::endl; + std::cout << solve({ { 2, 3 },{ 3, 3 },{ -5, 3 } }) << std::endl; + std::cout << solve({ { 2, 2 },{ 3, 3 },{ 2, 2 },{ 3, 3 } }) << std::endl; + std::cout << solve({ { 2, 2 },{ 2, 3 },{ 3, 2 },{ 3, 3 } }) << std::endl; + + + auto end = std::chrono::high_resolution_clock::now(); + std::chrono::duration seconds = end - begin; + std::cout << "Time: " << seconds.count() << std::endl; + return 0; + } + catch (const std::exception& e) + { + std::cerr << std::endl + << "std::exception(\"" << e.what() << "\")." << std::endl; + return 2; + } + catch (...) + { + std::cerr << std::endl + << "unknown exception." << std::endl; + return 1; + } +} diff --git a/puzzles/interviews/training/multithreaded_queue.cpp b/puzzles/interviews/training/multithreaded_queue.cpp new file mode 100644 index 0000000..6136b08 --- /dev/null +++ b/puzzles/interviews/training/multithreaded_queue.cpp @@ -0,0 +1,148 @@ +/* +VIM: let b:lcppflags="-std=c++14 -O2 -pthread -I." +VIM: let b:wcppflags="/O2 /EHsc /DWIN32" +*/ +#include "stdafx.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + Queue. +*/ + +thread_local size_t this_tid; + +template +class MtQueue { + + std::queue m_queue; + std::mutex m_mutex; + std::condition_variable m_push_cond; + std::condition_variable m_pop_cond; + std::atomic m_stopped; + + static const size_t max_queue = 100; + + +public: + + /* Stop Queue */ + void stop() { + std::unique_lock lock(m_mutex); + m_stopped.store(true); + m_pop_cond.notify_all(); + m_push_cond.notify_all(); + } + + /* Blocks when */ + bool push(M m) { + std::unique_lock lock(m_mutex); + while (m_queue.size() >= max_queue && !m_stopped.load()) { + printf(" %lld: is full.\n", this_tid); + m_push_cond.wait(lock); + } + if (m_stopped.load()) { + return false; + } + m_queue.push(m); + printf("%lld: size %lld.\n", this_tid, m_queue.size()); + m_pop_cond.notify_one(); + return true; + } + + /* Blocks when empty.*/ + bool pop(M& m) { + std::unique_lock lock(m_mutex); + while (m_queue.empty() && !m_stopped.load()) { + printf(" %lld: is empty.\n", this_tid); + m_pop_cond.wait(lock); + } + if (m_stopped.load()) { + return false; + } + m = m_queue.front(); + m_queue.pop(); + printf("%lld: size %lld.\n", this_tid, m_queue.size()); + m_push_cond.notify_one(); + return true; + } + +}; + +void test() { + MtQueue q; + + auto push_proc = [&q](size_t tid) { + this_tid = tid; + int i = 0; + while (q.push(2)) { + if (++i % 101 == 0) { + auto m = std::chrono::milliseconds(100); + //printf("%lld: pusher waiting for %lldms.\n", this_tid, m.count()); + //std::this_thread::sleep_for(m); + } + } + }; + auto pop_proc = [&q](size_t tid) { + this_tid = tid; + int m; + while (q.pop(m)) { + + //printf("%lld: popper waiting for %dms.\n", this_tid, m); + std::this_thread::sleep_for(std::chrono::milliseconds(m)); + } + }; + + + std::vector v; + v.reserve(16); + v.emplace_back(push_proc, v.size()); + v.emplace_back(pop_proc, v.size()); + v.emplace_back(pop_proc, v.size()); + v.emplace_back(pop_proc, v.size()); + v.emplace_back(pop_proc, v.size()); + v.emplace_back(pop_proc, v.size()); + + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + q.stop(); + printf(" STOPPING.\n"); + for (auto& t : v) { + t.join(); + } +} + +int main() +{ + try { + auto begin = std::chrono::high_resolution_clock::now(); + + while (true) { + test(); + } + + auto end = std::chrono::high_resolution_clock::now(); + std::chrono::duration seconds = end - begin; + std::cout << "Time: " << seconds.count() << std::endl; + return 0; + } + catch (const std::exception& e) + { + std::cerr << std::endl + << "std::exception(\"" << e.what() << "\")." << std::endl; + return 2; + } + catch (...) + { + std::cerr << std::endl + << "unknown exception." << std::endl; + return 1; + } +} diff --git a/puzzles/interviews/training/string_addition.cpp b/puzzles/interviews/training/string_addition.cpp new file mode 100644 index 0000000..022a80c --- /dev/null +++ b/puzzles/interviews/training/string_addition.cpp @@ -0,0 +1,84 @@ +/* +VIM: let b:lcppflags="-std=c++14 -O2 -pthread -I." +VIM: let b:wcppflags="/O2 /EHsc /DWIN32" +*/ +#include "stdafx.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + given an array representing a non-negative integer (ex: 123 represented + as [1,2,3]), return the next integer (output: [1,2,4]). + run through all edge cases (ex: [9,9,9,9,9,9,9,9] etc) +*/ + +int dig(char ch) { + return ch - '0'; +} + +char chr(int dig) { + return dig + '0'; +} + +std::string incr(std::string n) { + int carry = 1; + for (size_t i = n.size(); i-- > 0; ) { + int ds = dig(n[i]) + carry; + if (ds >= 10) { + carry = ds / 10; + ds %= 10; + } + else { + carry = 0; + } + n[i] = chr(ds); + } + + if (carry) { + return chr(carry) + n; + } + else { + return n; + } +} + +int main() +{ + try { + auto begin = std::chrono::high_resolution_clock::now(); + + std::cout << incr("0") << std::endl; + std::cout << incr("1") << std::endl; + std::cout << incr("9") << std::endl; + std::cout << incr("10") << std::endl; + std::cout << incr("15") << std::endl; + std::cout << incr("19") << std::endl; + std::cout << incr("99") << std::endl; + std::cout << incr("9999999") << std::endl; + + auto end = std::chrono::high_resolution_clock::now(); + std::chrono::duration seconds = end - begin; + std::cout << "Time: " << seconds.count() << std::endl; + return 0; + } + catch (const std::exception& e) + { + std::cerr << std::endl + << "std::exception(\"" << e.what() << "\")." << std::endl; + return 2; + } + catch (...) + { + std::cerr << std::endl + << "unknown exception." << std::endl; + return 1; + } +}