toggle menu

My Blogs

MY Profile

Stephen G. Vinuya
Dec 07,2018

Solving Code Wars Problem in Javascript (ES6) [6th Kyu]


In this article we are going to solve 2 Codewars' [6th kyu ] problems using Javascript (ES6) and  discuss approaches how problems can be solved .

Codewars is a great site for improving your problem solving skills and it's also great for discovering different approaches of other developers in solving each problems.

Problems at code wars are label by difficulty as kyu, [1st kyu] being the hardest and [8th kyu] being the easiest.


Let's now start with our first problem.


1. Matrix Addition

Codewars link: https://www.codewars.com/kata/matrix-addition/train/javascript

The problem is :


Write a function that accepts two square matrices (N x N two dimensional arrays), and return the sum of the two. Both matrices being passed into the function will be of size N x N (square), containing only integers.

How to sum two matrices:

Take each cell [n][m] from the first matrix, and add it with the same [n][m] cell from the second matrix. This will be cell [n][m] of the solution matrix.

Visualization:

|1 2 3| |2 2 1| |1+2 2+2 3+1| |3 4 4|
|3 2 1| + |3 2 3| = |3+3 2+2 1+3| = |6 4 4|
|1 1 1| |1 1 3| |1+1 1+1 1+3| |2 2 4|


The solution:

Non ES6 approach: 


function matrixAddition(a, b) {
var m = []; // Matrix var for the sum of a + b
for (var r = 0; r < a.length; r++) {
m.push([]); // adds 1d array into the array to make it 2d
for (var c = 0; c < a[r].length; c++) {
m[r].push(a[r][c] + b[r][c]); // sum of each cell in a and b matrix
}
}

return m;
}


We have created m as the variable that will hold the sum of cells in both a and b in same row and col.

And every row iteration we are adding an empty 1d array to m, so that we can store the sum of same cells for both a and b.


And would you believe the approach above can be reduced into a single line of code?


ES6 Approach: 


const matrixAddition = (a, b) => a.map((a1, r) => a1.map((a2, c) => a2 + b[r][c]));


In this approach we have used arrow function of Javascript, to omit the function() keyword, to make it more shorter.

Also using arrow function would omit the return keyword.

We have used map here to mutate the matrix's value, and we have another inner map since we are dealing with 2d  array here.

Same as our solution above we have  and c which denotes the row and column of the cells we are adding .



2. Find the unique number

Codewars link: https://www.codewars.com/kata/find-the-unique-number-1/train/javascript

The problem is :

There is an array with some numbers. All numbers are equal except for one. Try to find it!

findUniq([ 1, 1, 1, 2, 1, 1 ]) === 2
findUniq([ 0, 0, 0.55, 0, 0 ]) === 0.55

It's guaranteed that array contains more than 3 numbers.

The tests contain some very huge arrays, so think about performance.

This is the first kata in series:



The solution:

Non ES6 approach: 

function findUniq(arr) {
var uniqObj = {}; //Stores all unique elements in array

arr.forEach(function (a) {
if (uniqObj.hasOwnProperty(a)) { //checks if the element in array exist already in the object as key
uniqObj[a] = true; // modify its value to true if exists already, meaning its unique
} else {
uniqObj[a] = false; // otherwise initialize it to false
}
});

var keys = Object.keys(uniqObj); // Gets all the keys in the Object

for (var i = 0; i < keys.length; i++) {
if (!uniqObj[keys[i]]) { // checks if the property value if false, if it is then it is unique
return parseInt(keys[i]); // return the key, parsed into integer
}
}
}


uniqObj is a variable that will hold the unique elements in the array as key.


hasOwnProperty() is an Object method that returns a boolean value if the key already exist in the object or not, if it exists we are setting it to true meaning the it is not unique, otherwise initialize it to false.

 

Object.keys() gets all the keys inside the object needed to iterate into the object values to find false in it, meaning it is a unique number then return the parseInt value of that key.


ES6 Approach: 

const findUniq = (arr) => {
const obj = arr.reduce((acc, a) => {
acc[a] = acc.hasOwnProperty(a);
return acc;
}, {});
return arr.reduce((acc, a) => (!obj[a] ? +a : acc), 0);
}


Uses the same idea as we did above, but instead of declaring a var uniqObj and using forEach to accumulate its value, we used reduce() instead, as well as to finding which key is the only unique number.

Instead of using if in checking to the unique number, we used a ternary operator.

We also change parseInt(strNumber) into +strNumber, which is the shorthand for parsing int.



That ends our article in Solving 6th kyu Codewars problem using ES6.


Check out the 7th kyu version of this article: http://onecompileman.com/blogs/3



Read More
MY Profile

Stephen G. Vinuya
Dec 06,2018

Solving Code Wars Problem in Javascript (ES6) [7th Kyu]



In this article we are going to solve 3 Codewars' [7th kyu ] problems using Javascript (ES6) and  discuss approaches how problems can be solved .

Codewars is a great site for improving your problem solving skills and it's also great for discovering different approaches of other developers in solving each problems.

Problems at code wars are label by difficulty as kyu, [1st kyu] being the hardest and [8th kyu] being the easiest.


Let's now start with our first problem.


1. Sort array by string length

Codewars link:  https://www.codewars.com/kata/sort-array-by-string-length/train/javascript

The problem is :


Write a function that takes an array of strings as an argument and returns a sorted array containing the same strings, ordered from shortest to longest.

For example, if this array were passed as an argument:

["Telescopes", "Glasses", "Eyes", "Monocles"]

Your function would return the following array:

["Eyes", "Glasses", "Monocles", "Telescopes"]
All of the strings in the array passed to your function will be different lengths, so you will not have to decide how to order multiple strings of the same length.

The solution:

Non ES6 approach: 

function sortByLength (array) {
return array.sort(function(a, b) {
return a.length - b.length; // sort it by ascending order based from string's length
});

}


We used Javascript's sort() function here which takes a callback function as an optional parameter for sorting.

Since we are comparing the length of the string as the basis for sorting, we used length property of the string.

a.length - b.length  this will be sorted in ascending order,

if we want it in descending order we just have to reverse the expression b.length - a.length


Would you be believe that our solution above can be reduced into a line of codes?

ES6 approach:


const sortByLength = (array) => array.sort((a, b) => a.length - b.length);


What's new here is ES6's arrow function, click here to learn more about arrow functions.


2. Flatten and sort an array

Codewars link:  https://www.codewars.com/kata/57ee99a16c8df7b02d00045f

The problem is :


Challenge:

Given a two-dimensional array of integers, return the flattened version of the array with all the integers in the sorted (ascending) order.

Example:

Given [[3, 2, 1], [4, 6, 5], [], [9, 7, 8]], your function should return [1, 2, 3, 4, 5, 6, 7, 8, 9].

Addendum:

Please, keep in mind, that JavaScript is by default sorting objects alphabetically. For more information, please consult:

http://stackoverflow.com/questions/6093874/why-doesnt-the-sort-function-of-javascript-work-well


Non ES6 approach: 

function flattenAndSort(array) {
array = array.reduce(function (acc, a) {
return acc.concat(a);
}, []);

return array.sort(function (a, b) {
return a - b;
});
}


We used reduce() array method to transform the 2d array into 1d array. 

acc stands for accumulator in reduce wherein it is initialized as empty array, concat() the array every iteration.

Again we can reduce the solution above into a single line of code.


ES6 Approach:


const flattenAndSort = array => [].concat(...array).sort((a, b) => a - b);


What we have used new here is this operator "...", which is called Spread Operator

Spread Operator, flattens and spreads the array content. To learn more click here 


3. The Office I - Outed

Codewars link:  https://www.codewars.com/kata/the-office-i-outed/train/javascript

The problem is :

Your colleagues have been looking over you shoulder. When you should have been doing your boring real job, you've been using the work computers to smash in endless hours of codewars.

In a team meeting, a terrible, awful person declares to the group that you aren't working. You're in trouble. You quickly have to gauge the feeling in the room to decide whether or not you should gather your things and leave.

Given an object (meet) containing team member names as keys, and their happiness rating out of 10 as the value, you need to assess the overall happiness rating of the group. If <= 5, return 'Get Out Now!'. Else return 'Nice Work Champ!'.

Happiness rating will be total score / number of people in the room.

Note that your boss is in the room (boss), their score is worth double it's face value (but they are still just one person!).


Non ES6 approach:


function outed(meet, boss) {

let avg = Object.keys(meet).reduce(function (acc, k) {

if (k === boss) {
acc += meet[k] * 2;
} else {
acc += meet[k];
}

return acc;
}, 0) / Object.keys(meet).length;


if (avg <= 5) {
return 'Get Out Now!'
} else {
return 'Nice Work Champ!';
}
}


We have used Object.keys() to get meet object keys, which we will need to compare if the person is the boss or not.

If boss multiply it by 2, after accumulating the sum of all team members, divide it by length of keys inside the meet  object to get the average.

After getting the avg check if <= 5 and return the necessary statement.


ES6 Approach:

const outed = (meet, boss) => {

const avg = Object.keys(meet).reduce((acc, k) => (
acc += (k === boss) ? meet[k] * 2 : meet[k]
), 0) / Object.keys(meet).length;

return (avg <= 5) ? 'Get Out Now!' : 'Nice Work Champ!';
}


We still used the arrow function here and some ternary operator to make the condition much more shorter.

That ends our article, there's a lot of possible code improvements when using ES6.




Read More