Joseph Mawa

Posted on

JavaScriptmas interview type coding challenges

Cover image by Pexels from Pixabay

Introduction

These are my solutions to a set of programming challenges by scrimba dubbed JavaScriptmas which ran from December 01, 2020 to December 24, 2020.

These challenges are mostly beginner programming problems. You might encounter one or two in a technical interview for an entry level job. If you are a beginner in JavaScript, it might help consolidate your JavaScript knowledge. I have documented my solutions here. The same solutions can also be found on Scrimba by following the link below each challenge description. You are free to play with the code.

If you are interested, I have also compiled these challenges in a GitHub repository which you can find at the link below.You are free to fork it under your own account and modify the solutions.

Javascriptmas

This is a set of programming challenges from scrimba.com dubbed 24 days of JavaScriptmas. It runs from December 01, 2020 - December 24, 2020. Each day a JavaScript challenge is posted and participants are free to attempt and share their solution on twitter. If you want to contribute to this set of solutions, read the contribution instructions.

Challenges

Candies

Solution 1
``` function candies(children, candy) {
return Math.floor(candy / children) * children;
}```
Solution 2
``` function candies(children, candy) {
return candy - (candy % children);
}```

Deposit profit

Solution
```function depositProfit(deposit, rate, threshold) {
const years = Math.log(threshold / deposit) / Math.log(1 + rate / 100);
return Number.isInteger(years) ? years +```

If you have a better solution or notice an inefficient or incorrect solution, feel free to open a pull request after reading the contribution guidelines or leave your solution in the comments section below. You never know someone might find it useful. I have written unit tests in jest which you can find at the GitHub repository.

Challenges

Candies

`n` children have got `m` pieces of candy. They went to eat as much candy as they can, but each child must eat exactly the same amount of candy as any other child. Determine how many pieces of candy will be eaten by all the children together. Individual pieces of candy cannot be split.

Example
For `n = 3` and `m = 10`, the output should be `candies(n, m) = 9`. Each child will eat 3 pieces. So the answer is 9.

``````/**
* @params  integer
* @params  integer
* @returns integer
*/

function candies(children, candy) {

}
``````

Solution on Scrimba

Solution 1
``````function candies(children, candy) {
return Math.floor(candy / children) * children;
}
``````

Solution 2
``````function candies(children, candy) {
return candy - (candy % children);
}
``````

Deposit profit

You have deposited a specific amount of dollars into your bank account. Each year your balance increases at the same growth rate. Find out how long it would take for your balance to pass a specific threshold with the assumption that you don't make any additional deposits.

Example

For `deposit = 100`, `rate = 20` and `threshold = 170`, the output should be `depositProfit(deposit, rate, threshold) = 3`. Each year the amount of money on your account increases by 20%. It means that throughout the years your balance would be)

• year 0: 100
• year 1: 120
• year 2: 144
• year 3: 172.8

Thus, it will take 3 years for your balance to pass the threshold, which is the answer.

``````/**
*@params  number
*@params  number
*@params  number
*@returns number
*/
function depositProfit(deposit, rate, threshold) {

}
``````

Solution on Scrimba

Solution
``````function depositProfit(deposit, rate, threshold) {
const years = Math.log(threshold / deposit) / Math.log(1 + rate / 100);
return Number.isInteger(years) ? years + 1 : Math.ceil(years);
}
``````

Chunky Monkey

Write a function that splits an array (first argument) into groups the length of size (second argument) and returns them as a two-dimensional array.

Example

• `chunkyMonkey(["a", "b", "c", "d"], 2)` should return `[["a", "b"], ["c", "d"]]`
• `chunkyMonkey([0, 1, 2, 3, 4, 5], 4)` should return `[[0, 1, 2, 3], [4, 5]]`
``````/**
*@params   any[]
*@params   integer
*@returns  Array<Array<any>>
*/
function chunkyMonkey(values, size) {

}
``````

Solution on Scrimba

Solution
``````function chunkyMonkey(values, size) {
const chunkedArray = [];
const arrayLength = values.length;
for (let i = 0; i < arrayLength; i += size) {
chunkedArray.push(values.slice(i, i + size));
}
return chunkedArray;
}
``````

Century from year

Given a year, return the century it is in. The first century spans from the year 1 up to and including the year 100. The second century from the year 101 up to and including the year 200.

Example

• For `year = 1905`, the output should be `centuryFromYear(year) = 20`.
• For `year = 1700`, the output should be `centuryFromYear(year) = 17`.
``````/**
*@params  integer
*@returns integer
*/

function centuryFromYear(num) {

}
``````

Solution on Scrimba

Solution
``````function centuryFromYear(num) {
return num % 100 ? Math.ceil(num / 100) : num / 100;
}
``````

Reverse string

Reverse the provided string.You may need to turn the string into an array before you can reverse it. Your result must be a string.

Examples

• `reverseAString("hello")` returns `"olleh"`
• `reverseAString("Howdy")` returns `"ydwoH"`
``````/**
*@params  string
*@returns string
*/

function reverseAString(str) {

}
``````

Solution on Scrimba

Solution 1
``````function reverseAString(str) {
return str.split('').reverse().join('');
}
``````

Solution 2
``````function reverseAString(str) {
let reversedString = ''; const { length } = str;
for (let i = 0; i < length; i += 1) {
reversedString = str[i] + reversedString;
}
return reversedString;
}
``````

Sort by length

Given an array of strings, sort them in the order of increasing lengths. If two strings have the same length, their relative order must be the same as in the initial array.

Example

``````/**
*@params  [string]
*@returns [string]
*/
function sortByLength(strs) {

}
``````

Solution on Scrimba

Solution
``````function sortByLength(strs) {
return strs.sort((a, b) => a.length - b.length);
}
``````

Count vowel consonants

You are given a string `str` that consists of only lowercase English letters. If vowels ('a', 'e', 'i', 'o', 'u') are given a value of 1 and consonants are given a value of 2,return the sum of all of the letters in the input string.

Example

• For `str = "abcde"` the output should be `countVowelConsonant(str) = 8`.
``````/**
*@params  string
*@returns integer
*/

function countVowelConsonant(str) {

}
``````

Solution on Scrimba

Solution
``````function countVowelConsonant(str) {
return str.split('').reduce((count, char) => ('aeiou'.indexOf(char) === -1 ? count + 2 : count + 1), 0);
}
``````

The rolling dice

In this challenge a casino has asked you to make an online dice that works just like it would in real life. Using the dice face that represents ‘one’ which has been made for you, make the faces for ‘two’, ‘three’, ‘four’, ‘five’ and ‘six’. Now when the users clicks the dice on the screen the dice is expected to show one of the faces randomly.

Note
You can check the scrimba playground below for the HTML, CSS and JavaScript files.

Solution on Scrimba

Sum odd fibonacci numbers

Given a positive integer `num`, return the sum of all odd Fibonacci numbers that are less than or equal to `num`. The first two numbers in the Fibonacci sequence are 1 and 1. Every additional number in the sequence is the sum of the two previous numbers. The first six numbers of the Fibonacci sequence are 1, 1, 2, 3, 5, 8. For example `sumOddFibonacciNumbers(10)` should return 10 because all odd Fibonacci numbers less than or equal to 10 are 1, 1, 3, 5.

Examples

• `sumOddFibonacciNumbers(10)` should return `10`
• `sumOddFibonacciNumbers(1000)` should return `1785`
• `sumOddFibonacciNumbers(4000000)` should return `4613732`
``````/**
*@params  integer
*@returns integer
*/
function sumOddFibonacciNumbers(num){

}
``````

Solution on Scrimba

Solution
``````function sumOddFibonacciNumbers(num) {
if (num < 2) return 2;
const cache = [1, 1];
let sumOfOddFibNums = 2;
while (cache[0] + cache[1] <= num) {
const nextFibNum = cache[0] + cache[1];
if (nextFibNum % 2) {
sumOfOddFibNums += nextFibNum;
}
cache[0] = cache[1];
cache[1] = nextFibNum;
}
return sumOfOddFibNums;
}
``````

Given an array of integers, find the pair of adjacent elements that has the largest product and return the product.

Examples

• For `inputArray = [3, 6, -2, -5, 7, 3]` `adjacentElementsProduct(inputArray)` should return 21 because 7 and 3 produce the largest product
``````/**
*@params  number[]
*@returns integer
*/

}
``````

Solution on Scrimba

Solution
``````function adjacentElementsProduct(nums) {
if (nums.length < 2) return nums[0];
let product = nums[0] * nums[1];
const lastIndex = nums.length - 1;

for (let i = 1; i < lastIndex; i += 1) {
if (nums[i] * nums[i + 1] > product) {
product = nums[i] * nums[i + 1];
}
}
return product;
}
``````

Avoid obstacles

You are given an array of integers representing coordinates of obstacles situated on a straight line. Assume that you are jumping from the point with coordinate 0 to the right. You are allowed only to make jumps of the same length represented by some integer. Find the minimal length of the jump enough to avoid all obstacles.

Examples

• For `inputArray = [5, 3, 6, 7, 9]` `avoidObstacles(inputArray)` should return 4.
``````/**
*@params  number[]
*@returns integer
*/

function avoidObstacles(nums) {

}
``````

Solution on Scrimba

Solution
``````function avoidObstacles(nums) {
if (!Array.isArray(nums) || !nums.length) {
throw new Error('Requires integer array');
}

const largestObstacle = Math.max(...nums);

/*
OR:
const largestObstacle = nums.reduce((prev, curr) => {
return curr > prev ? curr : prev;
});
*/

for (let jump = 2; jump <= largestObstacle; jump += 1) {
if (nums.every((obstacle) => obstacle % jump !== 0)) {
return jump;
}
}
return largestObstacle + 1;
}
``````

Valid time

Check if the given string is a correct time representation of the 24-hour clock.

Examples

• For `time = "13:58"`, `validTime(time)` should return `true`.
• For `time = "25:51"`, `validTime(time)` should return `false`.
• For `time = "02:76"`, `validTime(time)` should return `false`.
``````/**
*@params  string
*@returns boolean
*/

function validTime(str){

}
``````

Solution on Scrimba

Solution
``````function validTime(str) {
if (typeof str !== 'string' || !str.includes(':')) {
return false;
}
let [hour, minutes] = str.trim().split(':');
hour = hour.trim();
minutes = minutes.trim();
if (/\D/.test(hour) || /\D/.test(minutes)) {
return false;
}
hour = parseInt(hour, 10);
minutes = parseInt(minutes, 10);
return hour >= 0 && hour < 24 && minutes >= 0 && minutes < 60;
}
``````

Extract each kth

Given an array of integers, remove each kth element from it.

Example

• For `inputArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]` and `k = 3` the output of `extractEachKth(inputArray, k)` should be `[1, 2, 4, 5, 7, 8, 10]`.
``````/**
*@params  number[]
*@params  integer
*@returns number[]
*/

function extractEachKth(nums, index){

}
``````

Solution on Scrimba

Solution
``````function extractEachKth(nums, index) {
return nums.filter((__, i) => (i + 1) % index !== 0);
}
``````

Given an array of integers, find the maximal absolute difference between any two of its adjacent elements.

Examples

• For `inputArray = [2, 4, 1, 0]` `arrayMaximalAdjacentDifference(inputArray)` should return 3
• For `inputArray = [2, 9, 1, 0]` `arrayMaximalAdjacentDifference(inputArray)` should return 8
``````/**
*@params number[]
*@returns number
*/

}

``````

Solution on Scrimba

Solution
``````function arrayMaximalAdjacentDifference(nums) {
if (!Array.isArray(nums) || !nums.length) {
throw new Error('Invalid argument');
}

if (nums.length < 2) return nums[0];

let maxAbsoluteDiff = Math.abs(nums[0] - nums[1]);
const lastIndex = nums.length - 1;

for (let i = 1; i < lastIndex; i += 1) {
const diff = Math.abs(nums[i] - nums[i + 1]);
if (maxAbsoluteDiff < diff) {
maxAbsoluteDiff = diff;
}
}

return maxAbsoluteDiff;
}
``````

JavaScript carousel

In this challenge, one is required to make carousel work using JavaScript. The HTML, CSS and JavaScript files can be found in the Scrimba playground by following the link below.

Solution on Scrimba

Solution
``````const previousButton = document.querySelector('.previous');
const nextButton = document.querySelector('.next');
const allImages = document.querySelectorAll('img.card');
const gallery = document.querySelector('.gallery');
const imageCount = allImages.length;

let visibleImageId = 0;

function togglePreviousButtonBlur(action = 'INCREASE_OPACITY') {
if (action === 'LOWER_OPACITY') {
previousButton.style.opacity = 0.3;
return;
}
previousButton.style.opacity = 1;
}

function toggleNextButtonBlur(action = 'INCREASE_OPACITY') {
if (action === 'LOWER_OPACITY') {
nextButton.style.opacity = 0.3;
return;
}
nextButton.style.opacity = 1;
}

function translateGallery(visibleImageId) {
const currentVisibleImage = document.querySelector('.current');

currentVisibleImage.classList.remove('current');
gallery.style.transform = `translateX(\${visibleImageId * -220}px)`;
}

function previousButtonClickHandler() {
if (visibleImageId === 0) return;

translateGallery(--visibleImageId);

if (visibleImageId === 0) {
togglePreviousButtonBlur('LOWER_OPACITY');
return;
}
togglePreviousButtonBlur();
toggleNextButtonBlur();
}

function nextButtonClickHandler() {
if (visibleImageId === imageCount - 1) return;

translateGallery(++visibleImageId);

if (visibleImageId === imageCount - 1) {
toggleNextButtonBlur('LOWER_OPACITY');
return;
}
toggleNextButtonBlur();
togglePreviousButtonBlur();
}

``````

Insert dashes

Transform a given sentence into a new one with dashes between each two consecutive letters.

Example

• For `inputStr = "aba caba"`, `insertDashes(inputStr)` should return `"a-b-a c-a-b-a"`.
``````/**
*@params  string
*@returns string
*/

function insertDashes(str){

}
``````

Solution on Scrimba

Solution
``````function insertDashes(str) {
return str
.split(' ')
.map((word) => word.split('').join('-'))
.join(' ');
}
``````

Different symbols naive

Given a string, find the number of different characters in it.

Example

• For `inputStr = "cabca"`, `differentSymbolsNaive(inputStr)` should return 3 because there are three different characters a, b and c.
``````/**
*@params  string
*@returns number
*/

function differentSymbolsNaive(str){

}
``````

Solution on Scrimba

Solution 1
``````function differentSymbolsNaive(str) {
if (typeof str !== 'string') {
throw new Error('Invalid input');
}
let uniqueChars = '';
const { length } = str;
for (let i = 0; i < length; i += 1) {
if (!uniqueChars.includes(str[i])) {
uniqueChars += str[i];
}
}
return uniqueChars.length;
}

``````

Solution 2
``````function differentSymbolsNaive(str) {
if (typeof str !== 'string') {
throw new Error('Invalid input');
}
return new Set(str).size;
}
``````

Solution 3
``````function differentSymbolsNaive(str) {
if (typeof str !== 'string') {
throw new Error('Invalid input');
}
const uniqueChars = {};
return str.split('').reduce((charCount, char) => {
if (uniqueChars[char]) {
return charCount;
}
uniqueChars[char] = char;
return charCount + 1;
}, 0);
}
``````

Array previous less

Given an array of integers, for each position `i`, search among the previous positions for the last (from the left) position that contains a smaller value. Store that value at position `i` in the answer. If no such value can be found, store -1 instead.

Examples

• For `inputArray = [3, 5, 2, 4, 5]`, `arrayPreviousLess(inputArray)` should return `[-1, 3, -1, 2, 4]`.
``````/**
*@params  number[]
*@returns number[]
*/

function arrayPreviousLess(nums) {

}
``````

Solution on Scrimba

Solution 1
``````function arrayPreviousLess(nums) {
if (!Array.isArray(nums)) {
throw new Error('Invalid input');
}
const { length } = nums;
const arrayClone = [...nums];

// eslint-disable-next-line no-restricted-syntax
outerLoop: for (let i = 0; i < length; i += 1) {
if (typeof nums[i] !== 'number') {
throw new Error('Invalid input');
}
for (let j = i - 1; j >= 0; j -= 1) {
if (nums[i] > nums[j]) {
arrayClone[i] = nums[j];
// eslint-disable-next-line no-continue
continue outerLoop;
}
}
arrayClone[i] = -1;
}
return arrayClone;
}

``````

Solution 2
``````function arrayPreviousLess(nums) {
if (!Array.isArray(nums)) {
throw new Error('Invalid input');
}
const arrayClone = [...nums];
nums.forEach((element, index) => {
if (typeof element !== 'number') {
throw new Error('Invalid input');
}
for (let i = index - 1; i >= 0; i -= 1) {
if (element > nums[i]) {
arrayClone[index] = nums[i];
return;
}
}
arrayClone[index] = -1;
});
return arrayClone;
}

``````

Alphabet subsequence

Check whether the given string is a subsequence of the plaintext alphabet

Examples

• For `inputStr = "effg"`, `alphabetSubsequence(inputStr)` should return `false`
• For `inputStr = "cdce"`, `alphabetSubsequence(inputStr)` should return `false`
• For `inputStr = "ace"`, `alphabetSubsequence(inputStr)` should return `true`
• For `inputStr = "bxz"`, `alphabetSubsequence(inputStr)` should return `true`
``````/**
*@param   string
*@returns boolean
*/

function alphabetSubsequence(str){

}
``````

Solution on Scrimba

Solution
``````function alphabetSubsequence(str) {
if (typeof str !== 'string' || !str.length) {
throw new Error('Invalid input');
}
const lowerCaseStr = str.toLowerCase();
const lastIndex = str.length - 1;
for (let i = 0; i < lastIndex; i += 1) {
const thisCharCode = lowerCaseStr.charCodeAt(i);
const nextCharCode = lowerCaseStr.charCodeAt(i + 1);
if (nextCharCode <= thisCharCode) {
return false;
}
if (thisCharCode < 97 || thisCharCode > 122) {
return false;
}
}
const lastCharCode = lowerCaseStr[lastIndex];
return !(lastCharCode < 97 || lastCharCode > 122);
}
``````

Domain type

GoDaddy makes a lot of different top-level domains available to its customers. A top-level domain is one that goes directly after the last dot (`.`) in the domain name, for example `.com` in `example.com`. To help the users choose from available domains, GoDaddy is introducing a new feature that shows the type of the chosen top-level domain. You have to implement this feature. To begin with, you want to write a function that labels the domains as "commercial", "organization", "network" or "information" for .com, .org, .net or .info respectively. For the given list of domains, return the list of their labels.

Example

• For `domains = ["en.wiki.org", "codefights.com", "happy.net", "code.info"]`, `domainType(domains)` should return `["organization", "commercial", "network", "information"]`.
``````/**
*@params   Array<string>
*@returns  Array<string>
*/

function domainType(domains){

}
``````

Solution on Scrimba

Solution
``````function domainType(domains) {
return domains.map((domain) => {
const domainNameComponents = domain.split('.');
const topLevelDomain = domainNameComponents[domainNameComponents.length - 1];
switch (topLevelDomain) {
case 'com':
return 'commercial';
case 'org':
return 'organization';
case 'net':
return 'network';
case 'info':
return 'information';
default:
}
});
}
``````

Sum of 2

You have two integer arrays `a` and `b`, and an integer target value `v`. Determine whether there is a pair of numbers, one number taken from `a` and another from `b` that can be added together to get a sum of `v`. Return `true` if such a pair exists, otherwise return `false`.

Examples

• For `a = [1, 2, 3]`, `b = [10, 20, 30, 40]` and `v = 42`, `sumOfTwo(a, b, v)` should return `true`.
``````/**
*@params  number[]
*@params  number[]
*@params  number
*@returns boolean
*/

function sumOfTwo(nums1, nums2, value){

}
``````

Solution on Scrimba

Solution
``````function sumOfTwo(nums1, nums2, value) {
for (let i = 0; i < nums1.length; i += 1) {
for (let j = 0; j < nums2.length; j += 1) {
if (nums1[i] + nums2[j] === value) {
return true;
}
}
}
return false;
}
``````

Extract matrix column

Given a rectangular matrix and an integer column, return an array containing the elements of the columnth column of the given matrix. The leftmost column is the 0th column.

Example

• For `inputMatrix = [[1, 1, 1, 2], [0, 5, 0, 4], [2, 1, 3, 6]]` and `column = 2`, `extractMatrixColumn(inputMatrix, column)` should return `[1, 0, 3]`.
``````/**
*@params  Array<Array<number>>
*@returns number[]
*/
function extractMatrixColumn(matrix, column) {

}
``````

Solution on Scrimba

Solution
``````function extractMatrixColumn(matrix, column) {
return matrix.map((row) => row[column]);
}
``````

Tweet Input Component

In this challenge, you are expected to make a Social Media Character Counter! You need to display the available characters LEFT. Using the Keydown event should help you here. When the characters reach 20 and below, we want them to turn red. So we will use Javascript to add that styling to it. If the characters drop below 0, we want the button to be disabled BUT if there are only 0 characters left, we should still be able to tweet.

You can find the HTML, CSS and JavaScript files at the link below.

Solution on Scrimba

Make a counter that increments every 75 milliseconds in the `spin()` function and display whether the player wins or losses in the `stop()` function.

Note
Check the HTML, CSS and JavaScript files on Scrimba by following the link below.

Solution on Scrimba

You can also fork the GitHub repository for the challenges in the link below.

nibble0101 / javascriptmas

Beginner-friendly coding challenges in JavaScript.

If you found these challenges useful, feel free to tweet or share them on any other platform. Others might find them useful too.