DEV Community

Nat's Tech Notes
Nat's Tech Notes

Posted on

Day 3/30 Days of CodeWars: JavaScript Edition

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 the factor parameter without returning a decimal number, it should return true.
  • 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
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

Solution

function checkForFactor (base, factor) {
    if (Number.isInteger(base / factor)) {
        return true;
    } else {
        return false;
    }
}
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

Solution

function checkForFactor (base, factor) {
    return Number.isInteger(base / factor);
}
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

Solution

function checkForFactor (base, factor) {
    return base % factor === 0;
}
Enter fullscreen mode Exit fullscreen mode

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!!__  "
Enter fullscreen mode Exit fullscreen mode

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"
("%^&*("), "%%^^&&**(("
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

Solution

function doubleChar(str) {
    let doubleString = '';
    for (let i = 0; i < str.length; i++) {
      doubleString += str[i] + str[i]
    }
    return doubleString;
}
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

Solution

function doubleChar(str) {
    return str.split('')
              .map(char => char.repeat(2))
              .join('');
}
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

Solution

function doubleChar(str) {
    return str.replace(/(.)/g, '$1$1');
}
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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('');
}
Enter fullscreen mode Exit fullscreen mode

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, '');
}
Enter fullscreen mode Exit fullscreen mode

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.


Connect with me on ...
Twitter
GitHub

Top comments (0)