Tower Research Interview Experience

Role: Core Software Engineer Intern
College: Tier 2
Experience: 6-month SDE Intern at MakeMyTrip
Rounds: 3 (2 Technical + 1 HR)


Round 1 (DSA + Problem Solving)

Question:
Given a binary grid with exactly two islands (groups of 1s), find the minimum number of 0s that must be flipped to 1s to connect the two islands.

I have provided the code I wrote in the interview below

Show Code
#include <climits>
#include <cmath>
#include <cstdio>
#include <iterator>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
#include <limits>
#include <bits/stdc++.h>
using namespace std;

vector<pair<int,int>>direction={{-1,0},{0,-1},{0,1},{1,0}};

bool insideBoundary(int x,int y,int height,int width){
   return (x>=0 and y>=0 and x<height and y<width);
}

int minDistance(int height,int width,vector<vector<int>>&grid){
    queue<pair<int,int>> multiSourceBfs;
    vector<vector<int>>dist(height,vector<int>(width,INT_MAX));
    pair<int,int>source={-1,-1};
    for(int row=0;row<height;row++){
       for(int col=0;col<width;col++){
          if(grid[row][col]==1){
           source={row,col};
           break;
          }
       }
   }
   queue<pair<int,int>> bfs;
   bfs.push(source);
   while(!bfs.empty()){
       pair<int,int> node= bfs.front();
       bfs.pop();
       if(dist[node.first][node.second]<INT_MAX) continue;
      
       dist[node.first][node.second]=0;
       multiSourceBfs.push({node.first,node.second});
      
       for(auto dir:direction){
           int nx=node.first+dir.first,ny=node.second+dir.second;
           if(insideBoundary(nx,ny,height,width) and grid[nx][ny]==1){
               bfs.push({nx,ny});
           }
       }
   }

   while(!multiSourceBfs.empty()){
       pair<int,int> node= multiSourceBfs.front();
       multiSourceBfs.pop();
      
       if(grid[node.first][node.second]==1 and dist[node.first][node.second]>0) return dist[node.first][node.second]-1;
       for(auto dir:direction){
           int nx=node.first+dir.first,ny=node.second+dir.second;
           if(insideBoundary(nx,ny,height,width) and dist[nx][ny]>dist[node.first][node.second]+1){
               dist[nx][ny]=dist[node.first][node.second]+1;
               multiSourceBfs.push({nx,ny});
           }
       }
   }

   return -1;
}

int main() {
   int height, width;
   cin>>height>>width;
   vector<vector<int>>grid(height,vector<int>(width,0));
   for(int row=0;row<height;row++){
       for(int col=0;col<width;col++){
           cin>>grid[row][col];
       }
   }
   int ans=minDistance(height,width,grid);
   cout<<"Ans: "<<ans<<endl;
   return 0;
}

Q2: Is vector memory contiguous? Why? How?
Q3: Difference between pass-by-value and pass-by-reference.
Q4: Threads, cache types (L1, L2, L3), why L1 cache is fast, what is its size, and why don’t we increase it?
Q5: Indexes in databases — why not use multiple indexes, what is partitioning, and what is sharding?


Round 2 (DSA + OOP)

Given multiple orders with statuses, identify completed and cancelled orders.
Completed orders have gone through all stages (placed, processed, shipped, delivered).
Cancelled orders can have cancelled after any stage.

I have provided the code I wrote in the interview below

Show Code
#include <cmath>
#include <cstdio>
#include <unordered_map>
#include <vector>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;

struct order{
     int order_id;
     int customer_id;
     string status;
     order(int order_id,int customer_id,string status): order_id(order_id),customer_id(customer_id),status(status){}   
};

class markCompletedOrder{

   unordered_map<string,int> statusToStatusCode={
       {"cancelled",0},
       {"placed",1},
       {"processed",2},
       {"shipped",3},
       {"delivered",4}
   };
   vector<order>orders;
   unordered_map<int,set<int>>orderStatusmap; // key=>order_id, value: set<status_code>
   vector<int>cancelled,completed;

   void CountCompletedOrder(){
       for(auto ord:orders){
           if(statusToStatusCode.find(ord.status)==statusToStatusCode.end()){
               cout<<"[Error] : invalid status code"<<endl;
               return;
           }
           orderStatusmap[ord.order_id].insert(statusToStatusCode[ord.status]);
       }
       for(auto val:orderStatusmap){
           set<int>allStatus=val.second;
           if(*allStatus.begin()==0){
               cancelled.push_back(val.first);
               continue;
           }
           if(allStatus.size()==statusToStatusCode.size()-1){
               completed.push_back(val.first);
           }
       }
   }

   public:
   markCompletedOrder(vector<order>&orders){
       this->orders=orders;
       CountCompletedOrder(); 
   }
   int getCompletedOrder(){
       return completed.size();
   }
   int getCancelledOrder(){
       return cancelled.size();
   }
   vector<int>completedOrder(){
       return completed;
   }
};

int main() {
   int countOrders;
   cin>>countOrders;
   vector<order>orders;
   for(int i=0;i<countOrders;i++){
       int order_id,customer_id;
       string status;
       cin>>order_id>>customer_id>>status;
       orders.push_back(order(order_id,customer_id,status));
   }
   markCompletedOrder *completed= new markCompletedOrder(orders);
   cout<<completed->getCompletedOrder()<<endl;
  
   cout<<"completed order ids are: ";
   for(auto it:completed->completedOrder()){
       cout<<it<<" ";
   }
   cout<<endl;
   return 0;
}

Round 3 (HR)

Mostly standard HR questions:

  • Why Tower Research?
  • Walk me through your projects
  • Internship experience at MakeMyTrip
  • Any offers in hand?

Summary

It was a rigorous yet enjoyable interview experience.
The technical rounds focused heavily on problem-solving, memory management, and understanding of computer architecture.
System design concepts like indexing, sharding, and caching were explored in detail.

Verdict: Selected

Comments (7)