Engaging in some JavaScript Warfare

Max Antonucci - Jul 22 '17 - - Dev Community

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

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:

  1. Check if a number was odd or even.
  2. 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';
Enter fullscreen mode Exit fullscreen mode

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

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

The final result is longer but fairly easy to get. Reading it takes you through these basic steps:

  1. numArr is an array of numbers you get the unique status from.
  2. checkStatus tells if a number is odd or even.
  3. findUniqueStatus gets the unique status from an array.
  4. statuses are the even/odd statuses from the initial array.
  5. uniqueStatus is the unique status from the initial array.
  6. The function returns the location of the unique status in the non-numerical array
  7. 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;
}
Enter fullscreen mode Exit fullscreen mode

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.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .