From 539e4b00771adebe6de9c0d32eaa19758782ce7c Mon Sep 17 00:00:00 2001 From: Vahagn Khachatryan Date: Fri, 26 Mar 2021 19:34:05 +0000 Subject: [PATCH] 2021/winter interview training for facebook/google --- puzzles/training/all_possible_subsets.cpp | 74 +++++++++++ puzzles/training/array_inversion_count.cpp | 89 +++++++++++++ .../training/build_and_run_last_changed.sh | 5 + puzzles/training/consolidate_contacts.cpp | 86 +++++++++++++ puzzles/training/disjoint_intervals.cpp | 118 ++++++++++++++++++ puzzles/training/gas_station.cpp | 61 +++++++++ puzzles/training/majority_element.cpp | 34 +++++ 7 files changed, 467 insertions(+) create mode 100644 puzzles/training/all_possible_subsets.cpp create mode 100644 puzzles/training/array_inversion_count.cpp create mode 100644 puzzles/training/build_and_run_last_changed.sh create mode 100644 puzzles/training/consolidate_contacts.cpp create mode 100644 puzzles/training/disjoint_intervals.cpp create mode 100644 puzzles/training/gas_station.cpp create mode 100644 puzzles/training/majority_element.cpp diff --git a/puzzles/training/all_possible_subsets.cpp b/puzzles/training/all_possible_subsets.cpp new file mode 100644 index 0000000..9d3b1c7 --- /dev/null +++ b/puzzles/training/all_possible_subsets.cpp @@ -0,0 +1,74 @@ +/* +VIM: let b:cf5build="clang -std=c++20 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}" +VIM: let b:cf5run="{OUT}" +*/ +#include +#include +#include +#include + +/* +Problem Description + For given set of N elements print all possible subsets. + +Sample inputs - Expected outputs + {"a"} -> + <- empty set + a + {"a", "b"} -> + <- empty set + a + b + a b +Input corner cases + Empty input set yields to one empty subset. +*/ + +void printAllSubsets(const std::vector &inputSet, std::ostream &os) +{ + std::vector subset(inputSet.size(), false); + + while (){ + + std::cout << '['; + for (size_t i = 0; i < inputSet.size(); ++i){ + if (subset[i]){ + std::cout << inputSet[i] << ' '; + } + } + std::cout << ']' << std::endl; + + + std:: + + } + std::vector + +} + +int main ( void ) +{try{ + auto begin = std::chrono::high_resolution_clock::now(); + + + //...... + const std::vector inputSet = {"a", "b", "c", "d"}; + printAllSubsets(inputSet, std::cout); + + 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/training/array_inversion_count.cpp b/puzzles/training/array_inversion_count.cpp new file mode 100644 index 0000000..ae559c7 --- /dev/null +++ b/puzzles/training/array_inversion_count.cpp @@ -0,0 +1,89 @@ +/* +VIM: let b:cf5build="clang -std=c++20 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}" +VIM: let b:cf5run="{OUT}" +*/ +#include +#include +#include +#include +#include +#include +#include +#include + +/* +https://app.codility.com/programmers/lessons/99-future_training/array_inversion_count/ + +An array A consisting of N integers is given. An inversion is a pair of indexes (P, Q) such that P < Q and A[Q] < A[P]. + +Write a function: + + int solution(vector &A); + +that computes the number of inversions in A, or returns −1 if it exceeds 1,000,000,000. + +For example, in the following array: + A[0] = -1 A[1] = 6 A[2] = 3 + A[3] = 4 A[4] = 7 A[5] = 4 + +there are four inversions: + (1,2) (1,3) (1,5) (4,5) + +so the function should return 4. + +Write an efficient algorithm for the following assumptions: + + N is an integer within the range [0..100,000]; + each element of array A is an integer within the range [−2,147,483,648..2,147,483,647]. + +*/ + +int solution(const std::vector& v) +{ + std::vector iv(v.size(),0); + for (size_t i=0; i 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/training/build_and_run_last_changed.sh b/puzzles/training/build_and_run_last_changed.sh new file mode 100644 index 0000000..f96dcbd --- /dev/null +++ b/puzzles/training/build_and_run_last_changed.sh @@ -0,0 +1,5 @@ +#!/bin/sh +SRC=$(ls -t *.cpp | head -1) + +set -x +clang -std=c++20 -O2 -pthread -lstdc++ -I. $SRC && ./a.out diff --git a/puzzles/training/consolidate_contacts.cpp b/puzzles/training/consolidate_contacts.cpp new file mode 100644 index 0000000..d230b6d --- /dev/null +++ b/puzzles/training/consolidate_contacts.cpp @@ -0,0 +1,86 @@ +/* +VIM: let b:cf5build="clang -std=c++20 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}" +VIM: let b:cf5run="{OUT}" +*/ +#include +#include +#include +#include +#include + +/* + +std::unordered_map> +*/ + +using contacts_type = std::unordered_map>; +using emails_type = std::unordered_map>; + + +void + all_contacts( + const std::string& contact, + std::unordered_set& visited_contacts, + const contacts_type& contacts, + const emails_type& emails, + std::unordered_set& merged_emails) +{ + visited_contacts.insert(contact); + for (const auto& email: contacts[contact]){ + if (merged_emails.count(email)==0){ + merged_emails.insert(email); + for (const auto& merging_contacts : emails[email]){ + all_contacts(merging_contacts, visited_contacts, contacts, emails, merged_emails ); + } + } + } +} + + +contacts_type merge( const contacts_type& contacts){ + + std::unordered_map> emails; + + for (const auto& contact : contacts){ + for (const auto& email : contact.second){ + emails[email].insert(contact.first); + } + } + + contacts_type merged_contacts; + std::unordered_set visited_contacts; + for (const auto& contact : contacts){ + if (visited_contacts.count(contact.first) == 0){ + auto& merged_emails = merged_contacts[contact.first]; + all_contacts(contact.first, visited_contacts, contacts, emails, merged_emails); + } + } + + return merged_contacts; +} + + +int main ( void ) +{try{ + auto begin = std::chrono::high_resolution_clock::now(); + + + //...... + + 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/training/disjoint_intervals.cpp b/puzzles/training/disjoint_intervals.cpp new file mode 100644 index 0000000..ec60b88 --- /dev/null +++ b/puzzles/training/disjoint_intervals.cpp @@ -0,0 +1,118 @@ + [2, 9] + [3, 13] + [3, 10] + [3, 8] + [3, 6] + [3, 7] + [4, 8] + [4, 4] * + [4, 10] + [5, 11] + [7, 7] * + [7, 8] + [7, 12] + [7, 15] + [9, 12] + [9, 10] * + +/* + +Disjoint Intervals (https://www.interviewbit.com/problems/disjoint-intervals/) + + Asked in: + Google + +Problem Description + +Given a set of N intervals denoted by 2D array A of size N x 2, the task is to find the length of maximal set of mutually disjoint intervals. + +Two intervals [x, y] & [p, q] are said to be disjoint if they do not have any point in common. + +Return a integer denoting the length of maximal set of mutually disjoint intervals. + + + +Problem Constraints + +1 <= N <= 105 + +1 <= A[i][0] <= A[i][1] <= 109 + + + +Input Format + +First and only argument is a 2D array A of size N x 2 denoting the N intervals. + + +Output Format + +Return a integer denoting the length of maximal set of mutually disjoint intervals. + + +Example Input + +Input 1: + + A = [ + [1, 4] + [2, 3] + [4, 6] + [8, 9] + ] + +Input 2: + + A = [ + [1, 9] + [2, 3] + [5, 7] + ] + + + +Example Output + +Output 1: + + 3 + +Output 2: + + 2 + + + +Example Explanation + +Explanation 1: + + Intervals: [ [1, 4], [2, 3], [4, 6], [8, 9] ] + Intervals [2, 3] and [1, 4] overlap. + We must include [2, 3] because if [1, 4] is included thenwe cannot include [4, 6]. + We can include at max three disjoint intervals: [[2, 3], [4, 6], [8, 9]] + +Explanation 2: + + Intervals: [ [1, 9], [2, 3], [5, 7] ] + We can include at max two disjoint intervals: [[2, 3], [5, 7]] +*/ +int Solution::solve(vector > &A) { + + std::sort(A.begin(),A.end(), + [](const vector& op1, const vector& op2){ + return (op1[0] < op2[0] ); + }); + + int c = 1; + auto it = A.begin(); + for (auto jt = A.begin()+1; jt != A.end(); ++jt){ + if (it->at(1) < jt->at(0)){ + c++; + it = jt; + } if (jt->at(1) < it->at(1)){ + it = jt; + } + } + return c; +} \ No newline at end of file diff --git a/puzzles/training/gas_station.cpp b/puzzles/training/gas_station.cpp new file mode 100644 index 0000000..14ae470 --- /dev/null +++ b/puzzles/training/gas_station.cpp @@ -0,0 +1,61 @@ +/* + +Gas Station + + Asked in: + Bloomberg + Google + DE Shaw + Amazon + Flipkart + +Given two integer arrays A and B of size N. +There are N gas stations along a circular route, where the amount of gas at station i is A[i]. + +You have a car with an unlimited gas tank and it costs B[i] of gas to travel from station i +to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. + +Return the minimum starting gas station’s index if you can travel around the circuit once, otherwise return -1. + +You can only travel in one direction. i to i+1, i+2, … n-1, 0, 1, 2.. Completing the circuit means starting at i and +ending up at i again. + + + +Input Format + +The first argument given is the integer array A. +The second argument given is the integer array B. + +Output Format + +Return the minimum starting gas station's index if you can travel around the circuit once, otherwise return -1. + +For Example + +Input 1: + A = [1, 2] + B = [2, 1] +Output 1: + 1 + Explanation 1: + If you start from index 0, you can fill in A[0] = 1 amount of gas. Now your tank has 1 unit of gas. But you need B[0] = 2 gas to travel to station 1. + If you start from index 1, you can fill in A[1] = 2 amount of gas. Now your tank has +*/ +int Solution::canCompleteCircuit(const vector &A, const vector &B) { + int f = 0; + int mf = 0; + size_t mi = -1; + for (size_t i =0; i < A.size(); ++i){ + f += A[i]-B[i]; + if (f < mf){ + mf = f; + mi = i; + } + if ((i+1) == A.size() && f < 0){ + return -1; + } + } + + return (mi+1) % A.size(); +} diff --git a/puzzles/training/majority_element.cpp b/puzzles/training/majority_element.cpp new file mode 100644 index 0000000..47f42bf --- /dev/null +++ b/puzzles/training/majority_element.cpp @@ -0,0 +1,34 @@ +/* +Majority Element (https://www.interviewbit.com/problems/majority-element/) + + Asked in: + Microsoft + Yahoo + Google + Amazon + +Given an array of size n, find the majority element. The majority element is the element that appears more than floor(n/2) times. + +You may assume that the array is non-empty and the majority element always exist in the array. + +Example : + +Input : [2, 1, 2] +Return : 2 which occurs 2 times which is greater than 3/2. + +*/ +int Solution::majorityElement(const vector &A) { + int c =0; + int e =0; + for (int a : A){ + if (c == 0){ + e = a; + c++; + } else if ( e != a ){ + c--; + } else { + c++; + } + } + return e; +}