String Problems for revision
1. Possible Portmanteau
Given three distinct words, determine if the third word is potentially a portmanteau of the first two.
A portmanteau (https://en.wikipedia.org/wiki/Portmanteau) is a word that is made by taking the start of one word and the end of another and mashing them together. Brunch is a great example, combining the first 2 letters of "breakfast" with the last 4 of "lunch".
Compound words aren't considered portmanteaus, so "football" is not a portmanteau of "foot" and "ball". At least one of the two words needs to be truncated.
linear solution

2. Abbr
In the tech world it is becoming common to see abbreviations where a sequence of letters in a string are replaced with a number that represents the length of that sequence. For example, the word "internationalization" is often abbreviated as i18n. The 18 letters in between the 'i' and 'n' are replaced with the count.
A valid abbreviation of this type follows these rules:
- The starting and ending letters remain.
- Replacements must be separated by at least one letter to avoid ambiguity. 18 means eighteen letters were replaced, not 1 letter followed by 8 letters.
- Spaces and hyphens are ignored and not counted in replacements.
Example(s)
Valid abbreviations
internationalization -> i18n
andreessen horowitz -> a16z (the space is ignored)
the replacements -> the r9ts
Invalid abbreviations
formation -> f8n (wrong number of letters replaced)
the replacements -> the r18ts (the e could be replaced by a 1, followed by the next 8 letters, but this leads to ambiguity. Are 9 letters replaced or 18?)
internationalization -> 19n (doesn't start with a letter match)
Linear time and space solution
function validA10n(original, a10n) {
// Remove spaces and hyphens from the original string for accurate letter counting
let cleanedOriginal = "";
for (let char of original) {
if (char !== ' ' && char !== '-') {
cleanedOriginal += char;
}
}
// If the abbreviation is just the original word, return true
if (original === a10n) return true;
// Check if the first and last letters match
if (a10n[0] !== cleanedOriginal[0] || a10n[a10n.length - 1] !== cleanedOriginal[cleanedOriginal.length - 1]) {
return false;
}
// Extract the parts of the abbreviation
let letters = [];
let numbers = [];
let numStr = "";
for (let i = 1; i < a10n.length - 1; i++) {
if (a10n[i] >= '0' && a10n[i] <= '9') {
numStr += a10n[i];
} else {
if (numStr) {
numbers.push(parseInt(numStr, 10));
numStr = "";
}
letters.push(a10n[i]);
}
}
// If there was a number left at the end
if (numStr) {
numbers.push(parseInt(numStr, 10));
}
// There should be exactly one numeric part
if (numbers.length !== 1) {
return false;
}
let replacedLength = numbers[0];
let expectedReplacedLength = cleanedOriginal.length - 2 - letters.length;
return replacedLength === expectedReplacedLength;
}
// Test cases
console.log(validA10n("internationalization", "i18n")); // true
console.log(validA10n("andreessen horowitz", "a16z")); // true
console.log(validA10n("the replacements", "the r9ts")); // true
console.log(validA10n("formation", "f8n")); // false (wrong number)
console.log(validA10n("the replacements", "the r18ts")); // false (ambiguous replacement)
console.log(validA10n("internationalization", "19n")); // false (does not start with 'i')
console.log(validA10n("the quick brown fox", "t17x")); // true
console.log(validA10n("the quick brown fox", "t5q10x")); // true
console.log(validA10n("the quick brown fox", "t3e14x")); // false (ambiguous)