Day 3/30 Days of CodeWars: JavaScript Edition
Nat's Tech Notes
Posted on June 6, 2022
CodeWars challenges solved
1) Grasshopper - Check for factor (8 kyu)
2) Double Char (8 kyu)
3) Remove exclamation marks (8 kyu)
Kata 1: Grasshopper - Check for factor
Instructions
This function should test if the factor
is a factor of base
. Return true
if it is a factor or false
if it is not.
Factors are numbers you can multiply together to get another number.
2 and 3 are factors of 6 because: 2 * 3 = 6
- You can find a factor by dividing numbers. If the remainder is 0 then the number is a factor.
- You can use the mod operator (%) in most languages to check for a remainder
For example 2 is not a factor of 7 because: 7 % 2 = 1
Note: base
is a non-negative number, factor
is a positive number.
Breaking down the problem with P.R.E.P.
Parameters
The function expects two parameters: two numbers, one of which is the base
number and one that might or might not be the factor
number.
Returns
The function should return a Boolean
value: true
or false
.
- If the
base
parameter can be divided by thefactor
parameter without returning a decimal number, it should returntrue
. - Otherwise, it should return
false
.
Examples
The following test cases are provided by CodeWars.
(10,2), true
(63,7), true
(2450,5), true
(24612,3), true
(9,2), false
(653,7), false
(2453,5), false
(24617,3), false
The numbers between the parenthesis are the base and factor arguments passed to the function, followed by the value that should be returned from the function.
Pseudo code
See pseudo code section for each solution
Solution 1: Checking if quotient is an integer
Pseudo code
1) Check if dividing base by factor returns an integer.
2) If it does, return true.
3) Else, return false.
Solution
function checkForFactor (base, factor) {
if (Number.isInteger(base / factor)) {
return true;
} else {
return false;
}
}
Notes:
1) The modulo/remainder (%) operator mentioned in the instructions can be a bit hard to understand for beginners. So instead of checking for the remainder of the division, we check if the quotient - a.k.a. the result of the division - is an integer using the Number.isInteger()
method.
2) As shown in the next solution, using if/else statements like this is actually unnecessary since the condition itself already evaluates to true
or false
. However, it's not uncommon for beginners to write it out like this, since it's easy to read and understand the code.
Solution 2: Short-hand of solution 1
Pseudo code
1) Check the quotient of base divided by the factor.
2) Evaluate if the quotient is an integer.
3) Return the result of that evaluation.
Solution
function checkForFactor (base, factor) {
return Number.isInteger(base / factor);
}
Notes:
As mentioned in solution 1, there is actually no need to use if/else statements just to return true
or false
values. The condition specified inside the if statement itself evaluates to true
or false
so when we return the condition itself, we actually return the result of evaluating that condition.
Solution 3: Conditional return with modulo operator
Pseudo code
1) Check the remainder of base divided by the factor.
2) Evaluate if the remainder is (strictly) equal to 0.
3) Return the result of that evaluation.
Solution
function checkForFactor (base, factor) {
return base % factor === 0;
}
Notes:
1) The modulo or remainder operator returns the remainder of the first number divided by the second number. For example in 23 % 3
, 23
cannot be evenly divided by 3
, but 21
can (3 * 7
) and 23 - 21 = 2
.
2) If the remainder is 0, that means the base
can evenly be divided by the factor
, meaning the factor
parameter is an actual factor
(and should therefor return true
).
Kata 2: Double Char
Instructions
Given a string, you have to return a string in which each character (case-sensitive) is repeated once.
Examples (Input -> Output):
* "String" -> "SSttrriinngg"
* "Hello World" -> "HHeelllloo WWoorrlldd"
* "1234!_ " -> "11223344!!__ "
Good Luck!
Breaking down the problem with P.R.E.P.
Parameters
The function expects one parameter: a string.
Returns
The function should return one value: a string where each character in the string appears twice in a row.
Examples
The following test cases are provided by CodeWars.
("abcd"), "aabbccdd"
("Adidas"), "AAddiiddaass"
("1337"), "11333377"
("illuminati"), "iilllluummiinnaattii"
("123456"), "112233445566"
("%^&*("), "%%^^&&**(("
The string passed to the function as an argument is found between the parenthesis, followed by the string that should be returned from the function.
Pseudo code
See pseudo code section for each solution
Solution 1: Using a for loop
Pseudo code
1) Create a variable initialized as an empty string.
2) Loop over all the characters in the string.
3) Add the character to the string variable twice.
4) Return the string variable.
Solution
function doubleChar(str) {
let doubleString = '';
for (let i = 0; i < str.length; i++) {
doubleString += str[i] + str[i]
}
return doubleString;
}
Notes:
1) Strings, just like arrays, start at index 0 so to avoid off-by-one errors, we also start the loop at index 0.
2) Each iteration of the loop, the doubleString
variable is set to the current value of doubleString
and the character currently being iterated over in the loop is added to that twice. This is done with the help of the addition assignment operator (+=).
3) This solution is somewhat similar Day 1, kata 1, solution 1.
Solution 2: String to array back to string
Pseudo code
1) Turn string into array.
2) Loop over array.
3) Create new array with each character appearing twice.
4) Turn array back into string.
Solution
function doubleChar(str) {
return str.split('')
.map(char => char.repeat(2))
.join('');
}
Notes:
1) The .split()
string method splits a string into substrings and returns an array of those substrings. It takes a parameter that specifies how the string should be split. In our case the empty string parameter indicates it should split each character into its own substring.
2) The .map()
array method executes a function on each element in the array and returns a new array with the results of calling that function on each element.
3) The .repeat()
string method takes a number as its parameter, concatenates the string the method was called on the amount of times specified in that parameter and then returns that as a new string.
4) The .join()
array method is pretty much the opposite of the .split()
string method and - as the name suggest - joins elements of an array into a new string. It takes a parameter specifying how the array elements should be joined, in our case the empty string signifying each character should be joined without any white-space or other characters in between.
Solution 3: Using regular expressions
Pseudo code
1) Replace each character by the character twice.
2) Return the result of replacing all characters.
Solution
function doubleChar(str) {
return str.replace(/(.)/g, '$1$1');
}
Notes:
1) The .replace()
string method replaces the characters, text or patterns specified in the first parameter by the text, characters or patterns in the second parameter.
2) Regular expressions are used in strings to find, match or replace certain patterns inside the string. They always consist of / /
with the pattern specified in between.
3) Capture groups are used here to not just find the matching pattern, but remember it. A pattern in a capture group is surrounded by ()
and can also be accessed using the $
symbol, followed by the number of the capture group - in this case 1 since there is only 1 capture group in the regex.
4) The .
inside the capture group is known as a wildcard character and can match any character except for line terminators such as \n
which indicates a new line.
5) The /g
flag stands for global, If this flag wasn't used, the regex would only match to the first character and replace it, but not replace any subsequent characters. The global flag ensures it matches with ALL characters it can match to, in this case any characters in the string.
Kata 3: Remove exclamation marks
Instructions
Write function RemoveExclamationMarks which removes all exclamation marks from a given string.
Breaking down the problem with P.R.E.P.
Parameters
The function expects one parameter: a string.
Returns
The function should return one value: a string containing no exclamation marks.
Examples
The following test cases are provided by CodeWars.
("Hello World!"), "Hello World"
The string between the parenthesis is the argument passed to the function, followed by the string that should be returned from the function.
Pseudo code
No pseudo code for this kata
This coding challenge is fairly similar to the previous kata with some minor differences, so the solutions will be fairly similar, with some minor changes (hence why there won't be any pseudo code either). I'll be focusing mostly on the changes between these two kata.
Solution 1: Using a for loop
function removeExclamationMarks(s) {
let newString = '';
for (let i = 0; i < s.length; i++) {
if (s[i] !== '!') {
newString += s[i]
}
}
return newString;
}
Notes:
Instead of adding each character twice to our newString
variable like in kata 2 solution 1, we check if the character in the current iteration is an exclamation mark. If it's not, we add the character to the newString
variable. If it is, it wil essentially skip this iteration and continue to the next one.
Solution 2: String to array back to string
function removeExclamationMarks (s) {
return s.split('').filter(char => char !== '!').join('');
}
Notes:
Instead of using the .map()
array method like in kata 2 solution 2, we are using the .filter()
array method. It takes a callback function which specifies how the array should be filtered - in this case any character that is not an exclamation mark. It returns a new array with all elements that fulfill the condition specified inside the callback function.
Solution 3: Using regular expressions
function removeExclamationMarks(s) {
return s.replace(/!/g, '');
}
Notes:
This is basically a simplified version of kata 2 solution 3 and it replaces any exclamation marks with an empty string, meaning exclamations marks just end up being "cut out" of the string.
What solution did you implement?
What solution did you find the most elegant?
What solution did you have trouble understanding?
Let me know, I'd love to hear from you!
I hope you found this article helpful.
Posted on June 6, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.