I'm in a very fuzzy area with my JavaScript learning. I know most of the basics and can get something simple running, but haven't figured out what to focus on most next. Frameworks? ES2016? Node? The further away I get from the fundamentals, the harder it is to decide what path to take.
As I keep deciding, I've found one resource to keep my writing sharp - CodeWars!
It's let me use this mildly click-bait headline (I sort of apologize) and keep building my basic JS skills. It centers around a basic premise: get lots of different code dilemmas to solve, and compare your answers with others. It's also been great for polishing my writing style and problem-solving.
An Example JavaScript Battle
One of the tougher CodeWars challenges I've solved so far is this:
Bob is preparing to pass IQ test. The most frequent task in this test is to find out which one of the given numbers differs from the others. Bob observed that one number usually differs from the others in evenness. Help Bob — to check his answers, he needs a program that among the given numbers finds one that is different in evenness, and return a position of this number. (Keep in mind that your task is to help Bob solve a real IQ test, which means indexes of the elements start from 1 ,not 0.)
You're given several tests to check it works, but I added some extras to be safe.
Test.assertEquals(iqTest("2 4 7 8 10"), 3);
Test.assertEquals(iqTest("3 5 7 10 11"), 4);
Test.assertEquals(iqTest("1 2 4"), 1);
Test.assertEquals(iqTest("2 1 3"), 1);
Test.assertEquals(iqTest("2 4 8 1"), 4);
Test.assertEquals(iqTest("1 3 5 2"), 4);
Step One: Find the Needed Tasks
For problems like there, I like breaking the final task into simpler ones, solving for those, and using those small solutions together. There were two simple tasks:
- Check if a number was odd or even.
- Find out if an array of numbers has only one odd or even number.
Step Two: Solve the Needed Tasks
I wrote one function for each task. The first one, checking if a number was odd or even, was easy.
const checkStatus = num => (parseInt(num) % 2) ? 'odd' : 'even';
The second was slightly tougher. It uses the above function to make it more readable, but I'll likely refactor it later.
const findUniqueStatus = array => {
let numEvens = 0;
array.forEach(function(value){
if (checkStatus(value) == 'even') { numEvens++; }
});
return (numEvens === 1) ? 'even' : 'odd'
}
Viola! Both tasks are solved. Now to just put them together.
Step Three: Make the Final Function
Now I take both functions, put them in a single one, and use them to solve the IQ test.
function iqTest(numbers){
const numArr = numbers.split(' ');
const checkStatus = num => (parseInt(num) % 2) ? 'odd' : 'even';
const findUniqueStatus = array => {
let numEvens = 0;
array.forEach(function(value){
if (checkStatus(value) == 'even') { numEvens++; }
});
return (numEvens === 1) ? 'even' : 'odd'
}
let statuses = numArr.map(checkStatus),
uniqueStatus = findUniqueStatus(numArr);
return statuses.indexOf(uniqueStatus) + 1;
}
The final result is longer but fairly easy to get. Reading it takes you through these basic steps:
-
numArr
is an array of numbers you get the unique status from. -
checkStatus
tells if a number is odd or even. -
findUniqueStatus
gets the unique status from an array. -
statuses
are the even/odd statuses from the initial array. -
uniqueStatus
is the unique status from the initial array. - The function returns the location of the unique status in the non-numerical array
- Result: You're told the index of the unique value from the original array.
From a purely practical standpoint, this solution could be more efficient. Someone solved it in only four lines.
function iqTest(numbers){
var nums = numbers.split(" ").map(x => x % 2);
var sum = nums.reduce((a,b) => a + b);
var target = sum > 1 ? 0 : 1;
return nums.indexOf(target) + 1;
}
But I'll answer that with one of my favorite coding quotes:
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." ~Martin Fowler
So I look forward to more coding challenges! They're great staying on track as I keep finding my way in the JavaScript wilderness.