interviews/training->training

This commit is contained in:
2020-08-19 22:39:03 +01:00
parent 0e4cbb799c
commit d84fcbace8
20 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,121 @@
/*
VIM: let b:lcppflags="-std=c++14 -O2 -pthread -I."
VIM: let b:wcppflags="/O2 /EHsc /DWIN32"
VIM-: let b:argv=""
*/
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
/*
* Complete the function below.
*/
bool match(const string& pattern, const string& string) {
auto s = string.begin();
auto p = pattern.begin();
const std::string::const_iterator empty;
auto prev_p = empty;
auto prev_s = s;
while (s != string.end()) {
while ( p != pattern.end() && *p == '*' ) {
p++;
prev_p = p;
prev_s = s;
}
if ( p == pattern.end() ) {
if ( prev_p == p ){
return true;
} else if ( prev_p != empty ) {
p = prev_p;
s = ++prev_s;
} else {
return false;
}
}
else if ( *s == *p ){
s++;
p++;
}
else if ( *p == '?' ){
s++;
p++;
}
else if ( prev_p != empty ) {
p = prev_p;
s = ++prev_s;
}
else {
return false;
}
}
while ( *p == '*' ) {
p++;
}
return p == pattern.end();
}
void test( const std::string& str, const std::string& pattern ){
bool res = match(pattern, str);
std::cout << str << " - " << pattern << " -> " << res <<std::endl;
}
int main() {
#if 1
test( "", "" );
test( "", "*" );
test( "", "?" );
test( "a", "?" );
test( "abc", "abc" );
test( "aaaaabc", "*abc" );
test( "aaaaabc", "a*bc" );
test( "aaaaabc", "*abc*" );
test( "abc", "*abc*" );
test( "abc", "****abc*" );
test( "abcabaabcabacabc", "a*ba*c" );
test( "abcabcabcabccabc", "a*b*cc" );
test( "abcabcabcabccabc", "a*b*c?" );
test( "abcabcabcabccabc", "a*b*b?*" );
test( "abcabcabcabccabc", "*a*?*c*" );
test( "abcabcabcabccabc", "****a****??????*c******" );
#else
ofstream fout(getenv("OUTPUT_PATH"));
bool res;
string _pattern;
getline(cin, _pattern);
string _string;
getline(cin, _string);
res = match(_pattern, _string);
fout << res << endl;
fout.close();
#endif
return 0;
}

View File

@@ -0,0 +1,57 @@
/*
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>
struct node
{
node * left;
node * right;
int value;
};
long long max_value_of_path_sum( node * root )
{
if ( !root ) {
return 0;
}
auto lm = max_value_of_path_sum( root->left );
auto rm = max_value_of_path_sum( root->right );
return root->value + std::max(lm, rm);
}
int main ( void )
{try{
auto begin = std::chrono::high_resolution_clock::now();
//......
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> 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;
}}

View File

@@ -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 <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;
}}

View File

@@ -0,0 +1,77 @@
/*
VIM: let b:lcppflags="-std=c++14 -O2 -pthread -I."
VIM: let b:wcppflags="/O2 /EHsc /DWIN32"
*/
#include "stdafx.h"
#include <iostream>
#include <exception>
#include <chrono>
#include <vector>
#include <algorithm>
/*
You are given a sorted list of distinct integers from 0 to 99, for
instance [0, 1, 2, 50, 52, 75]. Your task is to produce a string
that describes numbers missing from the list; in this case
"3-49,51,53-74,76-99".
Examples:
[] <20>0-99<39>
[0] <20>1-99<39>
[3, 5] <20>0-2,4,6-99<39>
*/
inline
void print_range_if_not_empty(int rb, int re)
{
if (re - rb > 2) {
std::cout << ',' << rb + 1 << '-' << re - 1;
}
else if (re - rb > 1) {
std::cout << ',' << rb + 1;
}
}
void print_gaps(std::vector<int> v)
{
int v_prev = -1;
for (int i = 0; i < v.size(); v_prev = v[i++]) {
print_range_if_not_empty(v_prev, v[i]);
}
print_range_if_not_empty(v_prev, 100);
std::cout << std::endl;
}
int main()
{
try {
auto begin = std::chrono::high_resolution_clock::now();
//......
print_gaps({ 0, 1, 2, 50, 52, 75 });
print_gaps({ 2, 4, 5, 7, 90 });
print_gaps({ 0, 4, 5, 7, 99 });
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> 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;
}
}

View File

@@ -0,0 +1,79 @@
/*
VIM: let b:lcppflags="-std=c++14 -O2 -pthread -I."
VIM: let b:wcppflags="/O2 /EHsc /DWIN32"
*/
#include "stdafx.h"
#include <iostream>
#include <exception>
#include <chrono>
#include <vector>
#include <algorithm>
/*
google-interview-questions
You are given a sorted list of distinct integers from 0 to 99, for
instance [0, 1, 2, 50, 52, 75]. Your task is to produce a string
that describes numbers missing from the list; in this case
"3-49,51,53-74,76-99".
Examples:
[] <20>0-99<39>
[0] <20>1-99<39>
[3, 5] <20>0-2,4,6-99<39>
*/
inline
void print_range_if_not_empty(int rb, int re)
{
if (re-rb > 2) {
std::cout << ',' << rb + 1 << '-' << re - 1;
}
else if (re-rb > 1) {
std::cout << ',' << rb + 1;
}
}
void print_gaps(std::vector<int> v)
{
int v_prev = -1;
for (int i = 0; i < v.size(); v_prev = v[i++]) {
print_range_if_not_empty(v_prev, v[i]);
}
print_range_if_not_empty(v_prev, 100);
std::cout << std::endl;
}
int main()
{
try {
auto begin = std::chrono::high_resolution_clock::now();
//......
print_gaps({ 0, 1, 2, 50, 52, 75 });
print_gaps({ 2, 4, 5, 7, 90 });
print_gaps({ 0, 4, 5, 7, 99 });
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> 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;
}
}

View File

@@ -0,0 +1,120 @@
#include <vector>
#include <unordered_set>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <chrono>
/*
Given an even number ( greater than 2 ), return two prime numbers whose
sum will be equal to given number.
NOTE A solution will always exist. read Goldbachs conjecture
Example:
Input : 4
Output: 2 + 2 = 4
If there are more than one solutions possible, return the lexicographically
smaller solution.
*/
/*
* My understanding is:
* The first solution time complexity is O(n^2/log_n) + O(n) memory complexity.
* The second solution id O(n^2) complexity + O(0) memory complexity.
*/
#define SOLUTION 1
#if SOLUTION == 1
std::vector<size_t> primes;
std::unordered_set<size_t> primes_set;
void init_primes(const size_t n)
{
std::vector<bool> prime_table(n/2+1, true); // Only odd numbers.
primes.push_back(2);
for (auto p = 3; p <= n; p+=2) {
if ( prime_table[p/2] ) {
primes.push_back(p);
for ( int j = p*3; j <= n; j+=p*2 ) {
prime_table[j/2] = false;
}
}
}
primes_set.insert(primes.begin(), primes.end());
}
std::vector<int> primesum(int A)
{
for ( int p : primes ){
if ( primes_set.find(A-p) != primes_set.end() ) {
return {p, A-p};
}
}
return {};
}
#elif SOLUTION == 2
bool is_prime(int a)
{
if ( a <2 )
return false;
int end = std::floor(std::sqrt(a));
for ( int i = 2; i <= end; ++i ){
if ( a % i == 0) {
return false;
}
}
return true;
}
std::vector<int> primesum(int A)
{
for ( int i = 2; i < A; ++i) {
if ( is_prime(i) && is_prime(A-i) ){
return {i,A-i};
}
}
return {};
}
#endif
void solve_and_print(int A){
auto r = primesum(A);
std::cout << r[0] << ' ' << r[1] << std::endl;
}
int main()
{
auto begin = std::chrono::high_resolution_clock::now();
#if SOLUTION == 1
init_primes(16777218);
#endif
solve_and_print(4);
solve_and_print(10);
solve_and_print(16777214);
solve_and_print(16777218);
for ( int i = 4; i < 1000000; i+=2 ){
primesum(i);
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> seconds = end - begin;
std::cout << "Time: " << seconds.count() << std::endl;
}

View File

@@ -0,0 +1,89 @@
/*
VIM: let b:lcppflags="-std=c++14 -O2 -pthread -I."
VIM: let b:wcppflags="/O2 /EHsc /DWIN32"
*/
#include <iostream>
#include <exception>
#include <chrono>
#include <algorithm>
#include <vector>
#include <unordered_map>
/*
snap-inc-interview-questions
You are given an array of integers and a number K. You have to find the any
continue sub-array whose elements sum is K. Please note that, the array may
have positive, negative, and zeros as its element.
The desired complexity is O(N).
Example:
Input: [7 0 9 -10 0 789], K = 0
Output: Array from index 1 to Index 1.
Input: [1 2 3 5 -10] K = 0
Output: Array from Index 1 to Index 4.
If K = -2, Output would have been SubArray from Index 2 to Index 4.
*/
void solution( std::vector<int> v, int K )
{
int f = -1;
int l = -2;
std::unordered_map<int, int> m;
int s = 0;
for ( int i = 0; i < v.size(); ++i ) {
s+= v[i];
auto p = m.emplace( s, i);
if ( !p.second ){
p.first->second = i;
}
}
s = 0;
for ( int i = 0; i < v.size(); ++i ) {
auto r = m.find(s+K);
if ( r != m.end() && l-f < r->second - i){
l = r->second;
f = i;
}
s+= v[i];
}
std::cout << " {";
for ( auto i : v ){
std::cout << i << ", ";
}
std::cout << "}, " << K << " -> (" << f << ", " << l << ")" << std::endl;
}
int main ( void )
{try{
solution({7, 0, 9, -10, 0, 789}, 0);
solution({1, 2, 3, 5, -10}, 0);
solution({1, 2, 3, 5, -10}, -2);
solution({1, 2, 3, 5, -10}, -10);
solution({1, 2, 3, 5, -10}, 1);
solution({7, 2, 9, -10, 0, 789}, 7);
solution({7, 2, 9, -10, 0, 789}, 10000);
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;
}}

View File

@@ -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 <iostream>
#include <exception>
#include <string>
#include <chrono>
#include <vector>
#include <algorithm>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <unordered_map>
#include <unordered_set>
/*
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<int>()(p.x) ^ std::hash<int>()(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<Point>& v) {
std::unordered_map<Point, int, pairhash> 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<Point, int, pairhash> 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<double> 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;
}
}

View File

@@ -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 <iostream>
#include <exception>
#include <string>
#include <chrono>
#include <vector>
#include <algorithm>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <atomic>
/*
Queue.
*/
thread_local size_t this_tid;
template <typename M>
class MtQueue {
std::queue<M> m_queue;
std::mutex m_mutex;
std::condition_variable m_push_cond;
std::condition_variable m_pop_cond;
std::atomic<bool> m_stopped;
static const size_t max_queue = 100;
public:
/* Stop Queue */
void stop() {
std::unique_lock<std::mutex> 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<std::mutex> 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<std::mutex> 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<int> 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<std::thread> 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<double> 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;
}
}

View File

@@ -0,0 +1,35 @@
#
# The number of valid combinations of a strings for given input array a[],
# where a=&gt;1, z =&gt; 26, and 0 &lt;= a[i] &lt;= 9
# {1,1,1} =&gt; {aaa, ak, ka} =&gt; 3
# {1,1,0} =&gt; {aj} =&gt; 1 "/>
#
def valid_comb_aux(s, p, b, e, dyn):
if b in dyn:
print("dyn", p)
return dyn[b]
if b == e:
print("fin", p)
return 1
count = 0
for i in range(b+1, e+1):
if 0 < int(s[b:i]) and int(s[b:i]) <= (ord('z')-ord('a')+1):
p.extend(chr(ord('a')+int(s[b:i])-1))
count = count + valid_comb_aux(s, p, i, e, dyn)
p.pop()
dyn[b] = count
return count
def valid_comb(s):
dyn = {}
return valid_comb_aux(s, [], 0, len(s), dyn)
if __name__ == "__main__":
print(valid_comb("111"))
print(valid_comb("110"))
print(valid_comb("22222"))
# valid_comb("12131456879234522222")

View File

@@ -0,0 +1,115 @@
/*
VIM: let b:lcppflags="-std=c++14 -O2 -pthread"
VIM: let b:wcppflags="/O2 /EHsc /DWIN32"
VIM-: let b:argv=""
*/
#include <iostream>
#include <exception>
#include <vector>
#include <string>
#include <unordered_map>
/*
FB On-site March
Q: Find number of Islands.
XXXOO
OOOXX
XXOOX
Return 3 islands.
1 1 1 O O
O O O 2 2
3 3 O O 2
*/
int number_of_islands( const std::vector<std::string>& board )
{
auto n = board.size();
auto m = board.front().size();
std::unordered_map<int,int> g;
auto idx = [m](size_t i, size_t j){
return i*m+j;
};
auto root = [&g](size_t idx){
for (; g[idx] != idx; idx = g[idx] );
return idx;
};
for (size_t i = 0; i < n; ++i ){
for (size_t j = 0; j < m; ++j){
if (board[i][j] == 'x'){
if (j>0 && board[i][j-1] == 'x'){
g[idx(i,j)]=g[idx(i,j-1)];
if (i>0 && board[i-1][j] == 'x'){
g[root(idx(i-1,j))]=g[idx(i,j)];
}
}
else if (i>0 && board[i-1][j] == 'x'){
g[idx(i,j)]=g[idx(i-1,j)];
}
else {
g[idx(i,j)]=idx(i,j);
}
}
}
}
int count = 0;
for ( const auto& node: g){
if ( node.first == node.second ){
++count;
}
}
return count;
}
int main ( void )
{try{
std::cout << number_of_islands({
"xxxoo",
"oooxx",
"xxoox"
}) << std::endl;
std::cout << number_of_islands({
".xx..",
"xx...",
"xxxxx"
}) << std::endl;
std::cout << number_of_islands({
"....x",
"....x",
"xxxxx"
}) << std::endl;
std::cout << number_of_islands({
"xxxxx",
"xxxxx",
"xxxxx"
}) << std::endl;
std::cout << number_of_islands({
"xxxxx",
"....x",
"xxx.x",
"x...x",
"xxxxx"
}) << 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;
}}

View File

@@ -0,0 +1,50 @@
def permutation(s, b, e):
"""
Prints all permutations.
"""
if b+1 == e:
print(s)
else:
for i in range(b, e-1):
permutation(s, b+1, e)
c = s[i+1]
s[i+1] = s[i]
s[i] = s[b]
s[b] = c
permutation(s, b+1, e)
c = s[b]
s[b] = s[e-1]
s[e-1] = c
def permutation2(s):
"""
Prints all permutations. But in addition doesn't print
multiple instances of same value.
e.g. abb bab bba ( doesn't print two abb )
"""
print(s)
l = len(s)
while True:
i = l-1
while True:
ii = i
i = i - 1
if ord(s[i]) < ord(s[ii]):
j = l-1
while ord(s[i]) >= ord(s[j]):
j = j - 1
s[i], s[j] = s[j], s[i]
s[ii:l] = s[ii:l][::-1]
print(s)
break
if i == 0:
return
if __name__ == "__main__":
s = ['a', 'b', 'c', 'd', 'e', 'e']
permutation(s, 0, len(s))
print("--------------------------------------------")
permutation2(s)

View File

@@ -0,0 +1,80 @@
/*
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 <cmath>
/*
* Given a positive integer which fits in a 32 bit signed integer, find if it
* can be expressed as A^P where P > 1 and A > 0. A and P both should be
* integers.
*/
bool isPower(int X) {
if ( X == 1 ){
return true;
}
double log_X = std::log(X);
long long end = log_X / std::log(2) +1;
for ( int i = 2; i <= end; ++i ) {
double A = std::exp(log_X/double(i));
double rA = std::round(A);
std::cout << "--> A=" << A << " r(" << rA << ") I=" << i << " diff=" << std::fabs(A-rA) << std::endl;
if ( std::fabs(A-rA) < 0.00001 ) {
int int_A = rA;
std::cout << "Testing --> A=" << A << " r("<<int_A << ") I=" << i << std::endl;
long long test = 1;
for ( int j = 0; j < i; ++j ) {
test *= int_A;
}
if ( test == X ) {
std::cout << "X=" << X << " A=" << int_A << " I=" << i << std::endl;
return true;
}
}
}
std::cout << "X=" << X << " no power found." << std::endl;
return false;
}
int main ( void )
{try{
auto begin = std::chrono::high_resolution_clock::now();
isPower(1);
isPower(4);
isPower(3);
isPower(27);
isPower(1024000000);
isPower(1024*1024*1024);
//......
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> 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;
}}

View File

@@ -0,0 +1,103 @@
#include <vector>
#include <string>
#include <iostream>
struct node {
node * root = nullptr;
node * left = nullptr;
node * right = nullptr;
double data = 0;
node( double d, node * r = nullptr )
: root(r)
, data(d)
{}
};
node * prefix_to_tree( const std::vector<double>& v ){
if ( !v.size() ){
return nullptr;
}
node * root = new node(v[0]);
node * current = root;
node * max_node = nullptr;
for ( int i = 1; i < v.size(); ) {
if ( v[i] < current->data ){
max_node = current;
current = new node(v[i++],current);
current->root->left = current;
} else if ( !max_node
|| v[i] < max_node->data ){
current = new node(v[i++],current);
current->root->right = current;
} else if ( current->root ){
current = current->root;
while ( max_node
&& max_node->data <= current->data ) {
node * tmp = max_node;
max_node = max_node->root;
if ( max_node && tmp == max_node->left ){
break;
}
}
} else {
std::cout << "error" << std::endl;
break;
}
if ( !current || !root ) {
std::cout << "errrrrrror" << std::endl;
}
}
std::cout << root << std::endl;
return root;
}
void print( node * root, const std::string& level = "" ){
if ( root ) {
print( root->left, level + " ");
std::cout << level << "- " << root->data << std::endl;
print( root->right, level + " ");
}
}
void traverse( node * root, std::vector<double>& v ){
if ( root ) {
v.push_back(root->data);
traverse(root->left, v);
traverse(root->right, v);
}
}
void test( const std::vector<double>& v ){
auto r = prefix_to_tree( v );
//print( r );
std::vector<double> w;
traverse( r, w );
if ( v.size() != w.size() ) {
std::cout << "v.size() != w.size() => " << v.size() << " != " << w.size() << std::endl;
}
for (int i = 0; i < v.size(); ++i ){
if (v[i]!=w[i]){
std::cout << "error at index " << i << " -> "<< v[i] << " != " << w[i] << std::endl;
}
}
}
int main( void ) {
test( {1} );
test( {2, 1, 3} );
test( {4, 2, 1, 3, 6, 5, 7} );
test( {8, 4, 2, 1, 3, 6, 5, 7, 12, 10, 9, 11, 14, 13, 15} );
test( {8, 4, 2, 3, 6, 5, 7, 12, 10, 9, 11, 14, 13, 15} );
test( {8, 4, 6, 5, 7, 12, 10, 9, 14, 13, 15} );
test( {8, 12, 10, 9, 11, 14, 13, } );
test( {8, 4, 2, 1, 6, 12, 10, 11, 14, 15} );
return 0;
}

View File

@@ -0,0 +1,41 @@
import random
#
# You have a array with integers: e.g. [ 1, -2, 0, 6, 2, -4, 6, 6 ]
# You need to write a function which will evenly return indexes of a
# max value in the array.
# In the example above max value is 6, and its positions are 3, 6 and 7.
# So each run function should return random index from the set.
#
# Try to implement with O(n) for computation and memory.
# Try to reduce memory complexity to O(1).
#
def return_max_evenly(arr):
mv = float('-inf')
mi = -1
mc = 0
for i in range(len(arr)):
if mv < arr[i]:
mv = arr[i]
mi = i
mc = 1
elif mv == arr[i]:
mc = mc + 1
if random.random() < 1./mc:
mi = i
if mi != -1:
return mi
if __name__ == "__main__":
random.seed()
arr = [1, -2, 0, 6, 2, -4, 6, 6]
ret = {}
for i in range(10000):
r = return_max_evenly(arr)
if r in ret:
ret[r] = ret[r] + 1
else:
ret[r] = 1
print(ret)

View File

@@ -0,0 +1,95 @@
/*
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 <string>
/*
Simple wildcard match.
*/
bool wildcard_match(const std::string& input, const std::string& pattern)
{
int j = 0;
int i = 0;
int restart_idx = -1;
while ( i < input.size() )
{
while ( j < pattern.size() && pattern[j] == '*' ){
restart_idx = ++j;
}
if ( j<pattern.size() && pattern[j] == input[i] ) {
++i;
++j;
}
else if ( j>= 0 && pattern[j-1] == '*' ) {
++i;
}
else if ( restart_idx > 0 ) {
i -= j - restart_idx -1;
j = restart_idx;
}
else {
return false;
}
}
while ( j < pattern.size() && pattern[j] == '*' ){
++j;
}
return j == pattern.size();
}
void test(const std::string& input, const std::string& pattern)
{
std::cout << input << " x " << pattern
<< " == " << wildcard_match(input,pattern)
<< std::endl;
}
int main ( void )
{try{
auto begin = std::chrono::high_resolution_clock::now();
test("zebra", "dog");
test("zebra", "zebra");
test("zebra", "*br*");
test("zebra", "*bi*");
test("zebra", "*br*a");
test("zebra", "*br*b");
test("zebra", "z**a");
test("zebra", "z*a");
test("zebra", "x**a");
test("zebrabrb", "*brb*");
test("zebra", "*bra*");
test("zebrazebrazebra", "*bra*zeb*zeb*");
test("zebrbzebrazebra", "*bra*zeb*zeb*");
test("zebrbzebrazebra", "*bra*zeb*");
test("zebrbzebrazebra", "*****bra*zeb*****");
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> 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;
}}

View File

@@ -0,0 +1,106 @@
/*
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 <vector>
#include <algorithm>
/*Given N and M find all stepping numbers in range N to M
The stepping number:
A number is called as a stepping number if the adjacent digits have a difference of 1.
e.g 123 or 101 is stepping number, but 358 is not a stepping number
Example:
N = 10, M = 20
all stepping numbers are 10 , 12
Return the numbers in sorted order.
*/
/*
* Solution: complexity is linear actually. O(n)
* So, a better solution I guess will be to interate over the range
* and check each number on condition.
*/
void f( std::vector<int>& v, int A, int B, int n )
{
if ( A <= n && n <= B ) {
v.push_back(n);
}
else if ( n > B ) {
return;
}
int d = n % 10;
if ( d + 1 <= 9 ){
f( v, A, B, n*10+d+1);
}
if ( d - 1 >= 0 ){
f( v, A, B, n*10+d-1);
}
}
std::vector<int> stepnum(int A, int B)
{
std::vector<int> v;
if ( A <= 0 && 0 <= B ){
v.push_back(0);
}
for ( int i = 1; i <= 9; ++i ){
f( v, A, B, i );
}
std::sort(v.begin(), v.end());
return v;
}
void print( const std::vector<int>& A )
{
for (auto i: A){
std::cout << i << " ";
}
std::cout << std::endl;
}
int main ( void )
{try{
auto begin = std::chrono::high_resolution_clock::now();
//......
print( stepnum(10, 20) );
print( stepnum(0, 1000) );
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> 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;
}}

View File

@@ -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 <iostream>
#include <exception>
#include <string>
#include <chrono>
#include <vector>
#include <algorithm>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <atomic>
/*
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<double> 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;
}
}

View File

@@ -0,0 +1,74 @@
/*
VIM: let b:lcppflags="-std=c++14 -O2 -pthread -I."
VIM: let b:wcppflags="/O2 /EHsc /DWIN32"
*/
#include "stdafx.h"
#include <iostream>
#include <exception>
#include <chrono>
#include <vector>
#include <algorithm>
/*
google-interview-questions
For a given vector of integers and integer K, find the number of non-empty subsets S such that min(S) + max(S) <= K
For example, for K = 8 and vector [2, 4, 5, 7], the solution is 5 ([2], [4], [2, 4], [2, 4, 5], [2, 5])
The time complexity should be O(n2). Approach and code was asked
*/
int countSubsets(std::vector<int> numbers, int k)
{
int total_sum = 0;
for (int i = 0; i < numbers.size(); ++i) {
if (2 * numbers[i] > k) {
continue;
}
int sum = 1;
int max = numbers[i];
int min = numbers[i];
for (int j = i+1; j < numbers.size(); ++j) {
int tmp_max = std::max(max, numbers[j]);
int tmp_min = std::min(min, numbers[j]);
if (tmp_max + tmp_min <= k) {
sum *= 2;
min = tmp_min;
max = tmp_max;
}
}
total_sum += sum;
}
return total_sum;
}
int main()
{try{
auto begin = std::chrono::high_resolution_clock::now();
//......
std::cout << countSubsets({ 2, 4, 5, 7 }, 8) << std::endl;
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> 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;
}}

View File

@@ -0,0 +1,107 @@
/*
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 <vector>
#include <string>
#include <algorithm>
/*
PREFIX
Find shortest unique prefix to represent each word in the list.
Example:
Input: [zebra, dog, duck, dove]
Output: {z, dog, du, dov}
where we can see that
zebra = z
dog = dog
duck = du
dove = dov
NOTE : Assume that no word is prefix of another. In other words, the
representation is always possible.
*/
std::string get_prefix(const std::string& p1, const std::string& p2){
for ( int i = 0; i < p1.size() && i < p2.size(); ++i){
if ( p1[i] != p2[i] ){
return p1.substr(0,i+1);
}
}
return p1;
}
std::vector<std::string> prefix(const std::vector<std::string> &A) {
// Do not write main() function.
// Do not read input, instead use the arguments to the function.
// Do not print the output, instead return values as specified
// Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details
std::vector<std::string> ret(A.size());
std::vector<int> B(A.size());
for ( size_t i = 0; i < A.size(); ++i){
B[i] = i;
}
std::sort(B.begin(), B.end(), [&A](int op1, int op2){
return A[op1] < A[op2];
});
for (int i = 0; i < B.size(); ++i){
std::string p;
if ( i-1 >= 0 ) {
p = get_prefix(A[B[i]],A[B[i-1]]);
}
if ( i+1 < A.size() ){
auto _p = get_prefix(A[B[i]],A[B[i+1]]);
if ( _p.size() > p.size() ) {
p = _p;
}
}
if ( p.empty() ) {
p = A[B[i]].substr(0,1);
}
ret[B[i]] = p;
}
return ret;
}
int main ( void )
{try{
auto begin = std::chrono::high_resolution_clock::now();
auto p = prefix({"zebra", "dog", "duck", "dove"});
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> seconds = end - begin;
std::cout << "Time: " << seconds.count() << std::endl;
for ( const auto& _p : p) {
std::cout << _p << 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;
}}