Skip to content

Instantly share code, notes, and snippets.

@hokevins
Last active March 27, 2023 14:15
Show Gist options
  • Save hokevins/9c28e3c480b59009ba614a940a7694b4 to your computer and use it in GitHub Desktop.
Save hokevins/9c28e3c480b59009ba614a940a7694b4 to your computer and use it in GitHub Desktop.
cassidoo's Interview question of the week from Cassidy Williams' newsletter
// 2023-03-27
// Given a string in dice notation, return a random integer you can get by rolling those dice.
const rollDice = input => {
const getRandomInt = max => {
return Math.floor(Math.random() * max) + 1;
};
let sum = 0;
let rolls = input.split('+');
for (let roll of rolls) {
const [numRolls, max] = roll.split('d');
for (let i = 0; i < numRolls; i++) {
sum += getRandomInt(max);
}
}
return sum;
};
/*
Python implementation:
import random
def rollDice(input):
def getRandomInt(max):
'''Helper function to roll a single die'''
return random.randint(1, max)
sum = 0
rolls = input.split('+')
for roll in rolls:
[numRolls, max] = roll.split('d')
for numRoll in range(int(numRolls)):
sum += getRandomInt(int(max))
return sum
print(rollDice('4d4')) # Four 4-sided dice e.g. 13
print(rollDice('3d20')) # Three 20-sided dice e.g. 28
print(rollDice('1d8+2d10')) # One 8-sided dice, and two 10-sided dice e.g. 21
*/
console.log(rollDice('4d4')) // Four 4-sided dice e.g. 13
console.log(rollDice('3d20')) // Three 20-sided dice e.g. 28
console.log(rollDice('1d8+2d10')) // One 8-sided dice, and two 10-sided dice e.g. 21
// 2023-03-13
// Write a function that can do the 4 basic operations (add, subtract, multiply and divide) on two fractions. Return the most simplified form of the result. You can assume a non-zero denominator in the input, and don’t use any built-in implementations in your language of choice, if you can!
const fractionMath = (operand1, operator, operand2) => {
const parseFraction = (fraction) => {
// parse and return numerator and denominator
return fraction.split('/').map(Number);
};
const reduceFraction = (fraction) => {
// divide both the numerator and denominator by the Greatest Common Factor i.e. 6/4 becomes 3/2
let [numerator, denominator] = parseFraction(fraction);
let gcd = findGCD(numerator, denominator);
return denominator/gcd === 1 ? (numerator/gcd).toString() : numerator/gcd + '/' + denominator/gcd;
};
const findGCD = (num1, num2) => {
// return Greatest Common Factor
let gcd;
for (let i = 1; i <= num1 && i <= num2; i++) {
if (num1 % i === 0 && num2 % i === 0) gcd = i;
}
return gcd;
};
const findLCD = (num1, num2) => {
// return Lowest Common Denominator
let gcd = findGCD(num1, num2);
return (num1 * num2) / gcd;
};
const normalizeFractions = (fraction1, fraction2) => {
// transform 2 fractions into having the same denominators
let [numerator1, denominator1] = parseFraction(fraction1);
let [numerator2, denominator2] = parseFraction(fraction2);
let lcd = findLCD(denominator1, denominator2);
let factor1 = lcd / denominator1;
let factor2 = lcd / denominator2;
return [(numerator1 * factor1) + '/' + (denominator1 * factor1), (numerator2 * factor2) + '/' + (denominator2 * factor2)];
};
let result;
const [fraction1, fraction2] = normalizeFractions(operand1, operand2);
const [numerator1, denominator1] = parseFraction(fraction1);
const [numerator2, denominator2] = parseFraction(fraction2);
switch (operator) {
case 'add':
result = (numerator1 + numerator2) + '/' + denominator1;
break;
case 'subtract':
result = (numerator1 - numerator2) + '/' + denominator1;
break;
case 'multiply':
result = (numerator1 * numerator2) + '/' + (denominator1 * denominator2);
break;
case 'divide':
result = (numerator1 * denominator2) + '/' + (denominator1 * numerator2);
break;
}
return reduceFraction(result);
};
console.log(fractionMath("3/4", "add", "3/4")) // "3/2"
console.log(fractionMath("1/8", "multiply", "2/2")) // "1/8"
console.log(fractionMath("2/5", "subtract", "1/10")) // "3/10"
console.log(fractionMath("2/5", "divide", "1/10")) // "4"
// 2023-03-06
// If you mix up the order of letters in a word, many people can slitl raed and urenadnstd tehm. Write a function that takes an input sentence, and mixes up the insides of words (anything longer than 3 letters).
// jumble word if word.length > 3
// only jumble inside letters
// preserve punctuations and number words
// preserve capitalization
const scramble = (sentence) => {
const jumbleWord = (word) => {
if (word.length <= 3) return word;
const fisherYatesShuffle = (array) => {
// in-place Fisher–Yates (aka Knuth) shuffle algorithm
let len = array.length;
while (len) {
// pick remaining element
let tempIndex = Math.floor(Math.random() * len--);
// then swap with current element
[array[len], array[tempIndex]] = [array[tempIndex], array[len]];
}
return array;
};
let firstChar = word[0];
let lastChar = word[word.length - 1];
let shuffledMiddle = fisherYatesShuffle(word.slice(1, -1).split('')).join('');
return firstChar + shuffledMiddle + lastChar;
};
const isUpperAlpha = str => str.search(/^[A-Z]+$/) !== -1;
const isLowerAlpha = str => str.search(/^[a-z]+$/) !== -1;
const isNumeric = str => str.search(/^[0-9]+$/) !== -1;
let newSentence = '';
let word = '';
for (let i = 0; i < sentence.length; i++) {
let currChar = sentence[i];
if (isUpperAlpha(currChar) || isNumeric(currChar)) {
newSentence += currChar;
} else if (isLowerAlpha(currChar)) {
word += currChar;
} else {
newSentence += jumbleWord(word);
word = '';
newSentence += currChar;
}
};
if (word.length) newSentence += jumbleWord(word);
return newSentence;
};
console.log(scramble('A quick brown fox jumped over the lazy dog.')) // 'A qciuk bwron fox jmepud oevr the lzay dog.'
console.log(scramble('The world is a beautiful place!')) // 'The wlord is a butfuiael pacle!'
console.log(scramble('a pick 100 a pock 50')) // 'a pcik 100 a pcok 50'
console.log(scramble('foo bar bazzzz')) // 'foo bar bzazzz'
// 2023-02-27
// Given a list of numbers, return all groups of repeating consecutive numbers.
const repeatedGroups = (nums) => {
let output = [];
let currChar;
let currArr = [];
for (let num of nums) {
if (currChar === undefined) {
currChar = num;
currArr.push(currChar);
} else if (currChar === num) {
currArr.push(currChar);
} else {
if (currArr.length > 1) output.push(currArr.slice());
currArr.length = 0;
currChar = num;
currArr.push(currChar);
}
}
if (currArr.length > 1) output.push(currArr);
return output;
};
console.log(repeatedGroups([1, 2, 2, 4, 5])) // [[2, 2]]
console.log(repeatedGroups([1, 1, 0, 0, 8, 4, 4, 4, 3, 2, 1, 9, 9])) // [[1, 1], [0, 0], [4, 4, 4], [9, 9]]
console.log(repeatedGroups([0, 6, 2, 2, 5, 3, 1, 2, 3, 3, 1, 1, 1, 0, 0, 0, 0])) // [[2, 2], [3, 3], [1, 1, 1], [0, 0, 0, 0]]
console.log(repeatedGroups([1, 2, 3, 4])) // []
console.log(repeatedGroups([2, 2])) // [[2, 2]]
console.log(repeatedGroups([])) // []
// 2023-02-20
// Given a string of parenthesis, return the number of parenthesis you need to add to the string in order for it to be balanced.
const numBalanced = (str) => {
let stack = [];
for (let char of str) {
if (char === '(') stack.push(char);
else {
let peek = stack.pop();
if (peek === '(') continue;
else if (peek !== undefined) {
stack.push(peek);
}
stack.push(char);
}
}
return stack.length;
};
console.log(numBalanced(`()`)) // 0
console.log(numBalanced(`(()`)) // 1
console.log(numBalanced(`))()))))()`)) // 6
console.log(numBalanced(`)))))`)) // 5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment