From 7252e23f01c7e70d11e67f00dcc5595886b53e88 Mon Sep 17 00:00:00 2001 From: Vahagn Khachatryan Date: Mon, 7 May 2018 12:11:59 +0100 Subject: [PATCH] diagonal.cpp --- puzzles/interviews/training/diagonal.cpp | 172 +++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 puzzles/interviews/training/diagonal.cpp diff --git a/puzzles/interviews/training/diagonal.cpp b/puzzles/interviews/training/diagonal.cpp new file mode 100644 index 0000000..5421773 --- /dev/null +++ b/puzzles/interviews/training/diagonal.cpp @@ -0,0 +1,172 @@ +/* +VIM: let b:lcppflags="-std=c++14 -O2 -pthread -I." +VIM: let b:wcppflags="/O2 /EHsc /DWIN32" +VIM-: let b:cppflags=g:Iboost.g:Itbb +VIM-: let b:ldflags=g:Lboost.g:Ltbb +VIM-: let b:ldlibpath=g:Bboost.g:Btbb +VIM-: let b:argv="" +*/ +#include +#include +#include +#include +#include + +/* + * Give a N*N square matrix, return an array of its anti-diagonals. Look at the + * example for more details. + * + * Example: + * Input: + * 1 2 3 + * 4 5 6 + * 7 8 9 + * + * Return the following : + * [ + * [1], + * [2, 4], + * [3, 5, 7], + * [6, 8], + * [9] + * ] + * + * Input : + * 1 2 + * 3 4 + * + * Return the following : + * [ + * [1], + * [2, 3], + * [4] + * ] + */ + +std::vector > diagonal(const std::vector > &A) +{ + size_t m = A.size(); + size_t n = A.front().size(); + + std::vector > v(n+m-1); + + int step = 0; + size_t k = 0; + for ( size_t i = 0; i < m; ++i, ++k ){ + size_t c = std::min(i+1, n); + v[k].resize(c); + for ( size_t j = 0; j < c; ++j){ + v[k][c-1-j] = A[i-j][j]; + } + } + + for ( size_t i = 1; i < n; ++i, ++k ){ + size_t c = std::min(n-i, m); + v[k].resize(c); + for ( size_t j = 0; j < c; ++j){ + v[k][c-1-j] = A[m-1-j][i+j]; + } + } + + return v; +} + +std::vector> diagonal2(const std::vector > &A) +{ + size_t m = A.size(); + size_t n = A.front().size(); + size_t mn_min = std::min(n,m); + size_t r_count = n+m-1; + + std::vector> v(n+m-1); + + for ( int i = 0; i < m; ++i ){ + for ( int j = 0; j < n; ++j ){ + size_t r = i+j; + + auto q = i; + if ( r >= n ) { + q -= r-n+1; + } + + if ( !v[r].size() ){ + auto rr = std::min( r_count-r, r+1); + v[r].resize(std::min(rr,mn_min)); + } + + v[r][q] = A[i][j]; + } + } + + return v; +} + +void print( const std::vector>& A ) +{ + return; + for ( const auto& a : A ){ + for ( auto i : a ){ + std::cout << i << ' '; + } + std::cout << std::endl; + } +} + +template +void test( SOLUTION s ) +{ + print( s( { + { 1, 2, 3 }, + { 4, 5, 6 }, + { 7, 8, 9 } + } ) ); + print( s( { + { 1, 2, 3 }, + { 4, 5, 6 }, + { 7, 8, 9 }, + { 10, 11, 12 }, + { 13, 14, 15 }, + { 16, 17, 18 } + } ) ); + print( s( { + { 1, 2, 3, 4, 5 }, + { 6, 7, 8, 9, 10 }, + { 11, 12, 13, 14, 15 } + } ) ); +} + +int main ( void ) +{try{ + test(diagonal); + test(diagonal2); + + auto begin = std::chrono::high_resolution_clock::now(); + + test(diagonal2); + + auto mid = std::chrono::high_resolution_clock::now(); + + test(diagonal); + + auto end = std::chrono::high_resolution_clock::now(); + std::chrono::duration seconds = end - begin; + std::chrono::duration seconds1 = mid - begin; + std::chrono::duration seconds2 = end - mid; + std::cout << "Time: " << seconds.count() << std::endl; + std::cout << "Time1: " << seconds1.count() << std::endl; + std::cout << "Time2: " << seconds2.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; +}} +