Files
test/puzzles/interviews/training/diagonal.cpp
2018-05-07 12:11:59 +01:00

173 lines
3.6 KiB
C++

/*
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 <iostream>
#include <exception>
#include <chrono>
#include <algorithm>
#include <vector>
/*
* 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<std::vector<int> > diagonal(const std::vector<std::vector<int> > &A)
{
size_t m = A.size();
size_t n = A.front().size();
std::vector<std::vector<int> > 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<std::vector<int>> diagonal2(const std::vector<std::vector<int> > &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<std::vector<int>> 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<std::vector<int>>& A )
{
return;
for ( const auto& a : A ){
for ( auto i : a ){
std::cout << i << ' ';
}
std::cout << std::endl;
}
}
template <typename SOLUTION>
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<double> seconds = end - begin;
std::chrono::duration<double> seconds1 = mid - begin;
std::chrono::duration<double> 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;
}}