Uber Interview Question
Software EngineersCountry: United States
Interview Type: Phone Interview
"Hi Sivasrinivas, your Uber is arriving now!", 25 => ["Hi Sivasrinivas,(1/3)", "your Uber is arriving(2/3)", "now!(3/3)"]
"01234567890123456789", 15 => ["012345678901234(1/2)", "56789(2/2)"]
utility functions
void printStringArray(vector<string> arr) {
int i;
cout << "[";
for (i = 0; i < arr.size(); i++) {
cout << "\"" << arr[i] << "\"";
if (i != arr.size() - 1) cout << ", ";
}
cout << "]\n";
}
string integerToString(int n) {
string str;
string table[10] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
if (n == 0) return "0";
str = "";
while (n) {
str = table[n % 10] + str;
n /= 10;
}
return str;
}
this is simple with following steps
1. lets begin with position i=0
2. jump to i+25
3. from position i+25 go back unless you get a whitespace... lets say you got whitespace at i+23.
4. send sms from i to i+23 and then set i = i+24 and repeat from step 2
5. follow these steps unless you are out of boudary in step 2.
Steps:
1. Split the String by " "
2. Go through the array and keep adding the elements to a new String until the length is less than charLimit
import java.util.ArrayList;
public class SplitTextDemo {
static ArrayList<String> splitText(String message, int charLimit) {
return splitTextAuxUsingSplit(message, charLimit);
}
static ArrayList<String> splitTextAuxUsingSplit(String message, int charLimitOriginal) {
//Decrease the char limit to accomodate chunk number at the end i.e. (1/3). For now assuming, the message chunks won't be more than 9
int charLimit = charLimitOriginal - 5;
//New arraylist to store message chunks
ArrayList<String> result = new ArrayList<String>();
String[] splitted = message.split(" ");
String temp;
for (int i = 0; i < splitted.length - 1; i++) {
temp = splitted[i];
//while length of temp and the next element combined is less than charLimit, temp = temp + next element
//Last element to be taken care of after this loop
while ((temp + 1 + splitted[i + 1]).length() <= charLimit && i + 1 < splitted.length - 1) { //+1 for space
temp = temp + " " + splitted[i + 1];
i++;
}
result.add(temp);
}
//Take care of the last element
//Add the last element from splitted to the last element of result if their combined length is less than charLimit
String lastElement = result.get(result.size() - 1);
if (lastElement.length() + 1 + splitted[splitted.length - 1].length() < charLimit) { //+1 for space
result.set(result.size() - 1, lastElement + " " + splitted[splitted.length - 1]);
} else {
result.add(splitted[splitted.length - 1]);
}
//append message chunk number for ex (1/3)
int resultSize = result.size();
for(int i = 0; i < resultSize; i++) {
result.set(i, result.get(i) +"("+ (i+1) + "/" + resultSize + ")" );
}
return result;
}
public static void main(String[] args) {
String message;
int charLmit;
message = "Hi Sivasrinivas, your Uber is arriving now! And this is a bigger text";
charLmit = 25;
ArrayList<String> result = splitText(message, charLmit);
for(String item : result) {
System.out.println("Length = " + item.length() + " : " +item );
}
System.out.println(result.toString());
}
}
private static List<string> GetChunks(string message, int messageLimit)
{
var result = new List<string>();
int mbX = 0, mbY = -1;
do
{
mbX = mbY + 1;
mbY = mbX + messageLimit;
while (mbY >= mbX && mbY < message.Length && message[mbY--] != ' ' );
if (mbY < mbX) throw new Exception("Cannot chunk.");
if (mbY >= message.Length) mbY = message.Length;
result.Add(message.Substring(mbX, mbY - mbX));
} while (mbY >= message.Length -1);
return result;
}
private void splitString(String message, int charLimit)
{
if( message != null && charLimit > 0)
{
String[] words = message.split(" ");
ArrayList<String> resultList = new ArrayList<String>();
String newWord="";
for(int i = 0; i< words.length; i++)
{
String checkWord = String.format("%s %s", newWord,words[i]);
if( checkWord.length() <= charLimit)
{
newWord = String.format("%s %s", newWord,words[i]);
if(i==words.length-1)
{
resultList.add(newWord);
}
}
else
{
resultList.add(newWord);
newWord = words[i];
}
}
int resultListLength = resultList.size();
for(int i = 0; i < resultListLength; i ++)
{
String finalWord = resultList.get(i);
finalWord = String.format("%s(%s/%s)", finalWord,i+1,resultListLength);
System.out.println(finalWord);
}
}
}
My C implementation.Basically prints it on screen instead of returning.
#include <stdio.h>
// Space needed to store "(XXX/YYY)"
#define POSTFIX 10
void spacefinder(char *str,int size,int st,int *end){
int lastspace;
int i;
i=st;
lastspace=st;
*end=st;
while(str[i]!='\0'){
if(str[i]!=' ')
(*end)++;
else{
// Check if total size is as expected.
if(*end-st <= size - POSTFIX){
lastspace=*end;
(*end)++;
}
else
break;
}
i++;
}
// If no space found or string ends return *end , otherwise return lastspace.
if(lastspace!=st && str[i]!='\0' )
*end=lastspace;
return;
}
// Takes string and split size ( assumes size > 10 )
void splitstring(char *str,int size){
int i=0,j;
int end;
int len;
int count = 0;
char **split;
char c[POSTFIX];
char temp[POSTFIX];
c[0]='(';
len=strlen(str);
//Malloc 2d array
split=(char**)malloc (sizeof(char*));
while(i<len){
count++;
//Keep on increasing using realloc
split=(char**)realloc (split,sizeof(char*)*count);
split[count-1]=(char*)malloc (sizeof(char)*strlen(str));
spacefinder(str,size,i,&end);
//Copy result in split[count-1]
strncpy(split[count-1],str+i,end);
split[count-1][end-i]='\0';
i=end+1;
}
//Steps to append total number of messages "/XXX)" .
temp[0]='/';
itoa(count,temp+1,10);
strcat(temp,")");
//Steps to prepend count of message "(XX" and printing.
for(j=0;j<count;j++){
itoa(j+1,c+1,10);
strcat(c,temp);
strcat(split[j],c);
printf("Split string = %s,len=%d\n",split[j],strlen(split[j]));
}
}
private static List<String> generateSplit(String text, int limit) {
//asserts here
int suffixLength = " (x/x)".length();
List<StringBuilder> answer = new ArrayList<>();
String[] wordsArray = text.split("\\s+");
int loop = 1;
while (true) {
List<String> words = new ArrayList<>(Arrays.asList(wordsArray));
while (!words.isEmpty()) {
//form a line
StringBuilder sb = new StringBuilder();
while (!words.isEmpty() && sb.length() + suffixLength + words.get(0).length() + 1 <= limit) {
sb.append(words.remove(0)).append(' ');
}
answer.add(sb.deleteCharAt(sb.length()-1));
}
if (answer.size() >= Math.pow(10, loop)) {
loop++;
suffixLength += 2;
} else {
break;
}
}
for (int i = 0; i < answer.size(); i++) {
answer.get(i).append(" (").append(i + 1).append("/").append(answer.size()).append(')');
}
List<String> result = new ArrayList<>(answer.size());
for (StringBuilder sb : answer) {
result.add(sb.toString());
}
return result;
}
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string>
divide_str(const string& in,
size_t chunk)
{
vector<string> out;
if (in.empty()) {
return out;
}
unsigned start = 0;
while (start < in.length()) {
unsigned end = min(start + chunk, in.length()) - 1;
bool skip = false;
if (end == in.length() - 1) {
skip = true;
} else if (end < in.length() && in[end + 1] == ' ') {
skip = true;
}
unsigned next_start = end + 1;
if (!skip) {
while (start < end && in[end] != ' ') {
--end;
}
next_start = end + 1;
while (start < end && in[end] == ' ') {
--end;
}
}
out.push_back(in.substr(start, end-start+1));
start = next_start;
}
return out;
}
int main()
{
string str = "Hello World! How are things with you? Not bad!";
vector<string> out = divide_str(str, 12);
for (int i = 0; i < out.size(); i++) {
cout << "(" << i + 1<< "/" << out.size() << ")" << out[i] << endl;
}
return 0;
}
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string>
divide_str(const string& in,
size_t chunk)
{
vector<string> out;
if (in.empty()) {
return out;
}
unsigned start = 0;
while (start < in.length()) {
unsigned end = min(start + chunk, in.length()) - 1;
bool skip = false;
if (end == in.length() - 1) {
skip = true;
} else if (end < in.length() && in[end + 1] == ' ') {
skip = true;
}
unsigned next_start = end + 1;
if (!skip) {
while (start < end && in[end] != ' ') {
--end;
}
next_start = end + 1;
while (start < end && in[end] == ' ') {
--end;
}
}
out.push_back(in.substr(start, end-start+1));
start = next_start;
}
return out;
}
int main()
{
string str = "Hello World! How are things with you? Not bad!";
vector<string> out = divide_str(str, 12);
for (int i = 0; i < out.size(); i++) {
cout << "(" << i + 1<< "/" << out.size() << ")" << out[i] << endl;
}
return 0;
}
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<string>
divide_str(const string& in,
size_t chunk)
{
vector<string> out;
if (in.empty()) {
return out;
}
unsigned start = 0;
while (start < in.length()) {
unsigned end = min(start + chunk, in.length()) - 1;
bool skip = false;
if (end == in.length() - 1) {
skip = true;
} else if (end < in.length() && in[end + 1] == ' ') {
skip = true;
}
unsigned next_start = end + 1;
if (!skip) {
while (start < end && in[end] != ' ') {
--end;
}
next_start = end + 1;
while (start < end && in[end] == ' ') {
--end;
}
}
out.push_back(in.substr(start, end-start+1));
start = next_start;
}
return out;
}
int main()
{
string str = "Hello World! How are things with you? Not bad!";
vector<string> out = divide_str(str, 12);
for (int i = 0; i < out.size(); i++) {
cout << "(" << i + 1<< "/" << out.size() << ")" << out[i] << endl;
}
return 0;
}
public void print(string input, int limit)
{
int start = 0, end = 0;
while(true)
{
if (end >= input.Length)
{
Console.WriteLine(input.Substring(start, input.Length - start));
return;
}
if (end - start + 1 > limit)
{
if(input[end] != ' ')
{
while (input[--end] != ' ')
{
}
}
Console.WriteLine(input.Substring(start, end - start));
start = ++end;
}
else
{
end++;
}
}
}
public static List<String> splitText(String s,int limit)
{
List<String> sentences=new ArrayList<String>();
List<String> result=new ArrayList<String>();
if(s==null || s.isEmpty()) return sentences;
limit=limit-"(x/x)".length();
String[] words=s.split("\\s+");
for(int i=0;i<words.length;i++)
{
StringBuilder sb=new StringBuilder();
sb.append(words[i]);
while(i+1<words.length && sb.length()+words[i+1].length()+1<=limit)
{
sb.append(" "+words[i+1]);
i++;
}
sentences.add(sb.toString());
}
int size=sentences.size();
for(int j=0;j<sentences.size();j++)
{
result.add(sentences.get(j)+"("+(j+1)+"/"+size+")");
}
return result;
}
public static List<String> splitText(String s,int limit)
{
List<String> sentences=new ArrayList<String>();
List<String> result=new ArrayList<String>();
if(s==null || s.isEmpty()) return sentences;
limit=limit-"(x/x)".length();
String[] words=s.split("\\s+");
for(int i=0;i<words.length;i++)
{
StringBuilder sb=new StringBuilder();
sb.append(words[i]);
while(i+1<words.length && sb.length()+words[i+1].length()+1<=limit)
{
sb.append(" "+words[i+1]);
i++;
}
sentences.add(sb.toString());
}
int size=sentences.size();
for(int j=0;j<sentences.size();j++)
{
result.add(sentences.get(j)+"("+(j+1)+"/"+size+")");
}
return result;
}
public static List<String> splitText(String s,int limit)
{
List<String> sentences=new ArrayList<String>();
List<String> result=new ArrayList<String>();
if(s==null || s.isEmpty()) return sentences;
limit=limit-"(x/x)".length();
String[] words=s.split("\\s+");
for(int i=0;i<words.length;i++)
{
StringBuilder sb=new StringBuilder();
sb.append(words[i]);
while(i+1<words.length && sb.length()+words[i+1].length()+1<=limit)
{
sb.append(" "+words[i+1]);
i++;
}
sentences.add(sb.toString());
}
int size=sentences.size();
for(int j=0;j<sentences.size();j++)
{
result.add(sentences.get(j)+"("+(j+1)+"/"+size+")");
}
return result;
}
Javascript implementation. Not happy about the two loops though. :/
function splitMsg(msg, limit) {
var chunks = [];
var split = msg.split(' ');
var thisChunk = split[0];
for (var i=1; i < split.length; i++) {
var nextLength = thisChunk.length + split[i].length + 1;
if (nextLength > (limit-5)) {
chunks.push(thisChunk);
thisChunk = split[i];
} else {
thisChunk += " " + split[i];
}
if (i == split.length-1) chunks.push(thisChunk);
}
return chunks.map(function(chunk, i) {
return chunk + "("+(i+1)+"/"+chunks.length+")";
});
}
import math
def split_helper(words, limit):
extra_suffix_length = 6
possible_length = [9, 99, 999, 9999]
for pl in possible_length:
final_sms = []
sms_part = ""
total_part = 0
extra_suffix_length = extra_suffix_length + int(math.log(pl, 10))
for i, word in enumerate(words):
with_word_part = ""
without_word_part = sms_part
if i==0:
with_word_part = word
else:
with_word_part = sms_part + " " + word
if total_part > 0:
total_part_checker_float_value = math.log(total_part, 10)
if total_part_checker_float_value.is_integer():
extra_suffix_length = extra_suffix_length + int(total_part_checker_float_value)
with_word_part_length = len(with_word_part) + extra_suffix_length
without_word_part_length = len(without_word_part) + extra_suffix_length
if with_word_part_length <= limit:
sms_part = with_word_part
else:
total_part = total_part + 1
final_sms.append(without_word_part)
sms_part = word
total_part = total_part + 1
final_sms.append(sms_part)
if total_part <= pl:
#Set part Suffix
ekdam_final_sms = []
for i, part in enumerate(final_sms):
part = part + " " + "({part_no}/{total_part})"
part = part.format(part_no=str(i+1), total_part=total_part)
ekdam_final_sms.append((part, len(part)))
return ekdam_final_sms
def split_sms(sms, limit):
words = sms.split(" ")
print split_helper(words, limit)
sms = "Hi Sivasrinivas, your Uber is arriving now!"
limit = 25
split_sms(sms, limit)
import math
input_string = 'Hi Sivasrinivas, your Uber is arriving now!'
input_words = input_string.split(' ')
character_limit = 25
lines = ['']
line_count = 0
length = len(input_words)
PossibleFinalLengths = []
for i in range(1,int(math.log(length,10)+1)+1):
PossibleFinalLengths.append(int(math.pow(10,i))-1)
for j in PossibleFinalLengths:
lines = ['']
line_count = 0
for i in input_words:
if line_count <= j:
if len(lines[line_count]) + 1 + len(i) <= (character_limit - (6 + int(math.log(j,10)) +int(math.log(line_count+0.1,10)))) :
if lines[line_count] != '':
lines[line_count] = lines[line_count]+ " " + i
else:
lines[line_count] = lines[line_count] + i
else:
line_count = line_count+1
lines.append('')
lines[line_count] = lines[line_count] + i
else:
break
for i in range(0,line_count+1):
lines[i] = lines[i] +" ("+str(i+1)+"/"+str(line_count+1)+")"
print(lines[i]+ " ---------->>>>>size of each message:"+ str(len(lines[i])))
import math
input_string = 'Hi Sivasrinivas, your Uber is arriving now!'
input_words = input_string.split(' ')
character_limit = 25
lines = ['']
line_count = 0
length = len(input_words)
PossibleFinalLengths = []
for i in range(1,int(math.log(length,10)+1)+1):
PossibleFinalLengths.append(int(math.pow(10,i))-1)
for j in PossibleFinalLengths:
lines = ['']
line_count = 0
for i in input_words:
if line_count <= j:
if len(lines[line_count]) + 1 + len(i) <= (character_limit - (6 + int(math.log(j,10)) +int(math.log(line_count+0.1,10)))) :
if lines[line_count] != '':
lines[line_count] = lines[line_count]+ " " + i
else:
lines[line_count] = lines[line_count] + i
else:
line_count = line_count+1
lines.append('')
lines[line_count] = lines[line_count] + i
else:
break
for i in range(0,line_count+1):
lines[i] = lines[i] +" ("+str(i+1)+"/"+str(line_count+1)+")"
print(lines[i]+ " ---------->>>>>size of each message:"+ str(len(lines[i])))
this is simple with following steps
1. lets begin with position i=0
2. jump to i+25
3. from position i+25 go back unless you get a whitespace... lets say you got whitespace at i+23.
4. send sms from i to i+23 and then set i = i+24 and repeat from step 2
5. follow these steps unless you are out of boudary in step 2.
this is simple with following steps
1. lets begin with position i=0
2. jump to i+25
3. from position i+25 go back unless you get a whitespace... lets say you got whitespace at i+23.
You're forgetting you need to leave space for the (1/3) as well as accounting for the current split count.
c++, implementation
- kyduke November 14, 2015