The challenge to make a shape area calculation in CodeSignal

Camilo Martinez - Sep 21 '18 - - Dev Community

Languages: [🇪🇸] Español - [🇺🇸] English


Since college, I was not encouraged to do programming challenges, until I got the invitation to CodeSignal a page where you can "play" against several friends or companies about solving algorithms.

I found on the second introduction level an exercise to make a shape area calculation that calls all my attention and before starting to develop it I thought of at least three ways to solve it: loops, recursion and mathematically … too late, now I'm infected with development fever.

The Problem

Below we will define an n-interesting polygon. Your task is to find the area of a polygon for a given n.

A 1-interesting polygon is just a square with a side of length 1. An n-interesting polygon is obtained by taking the n - 1-interesting polygon and appending 1-interesting polygons to its rim, side by side. You can see the 1-, 2-, 3- and 4-interesting polygons in the picture below.

Shape Area
Image taken from CodeSignal

Sample

For n = 2, the output should be: shapeArea(n) = 5.
For n = 3, the output should be: shapeArea(n) = 13.

My Solution

I decided to give myself the task of solving it in the 3 methods with node.js. I solved loops and recursion the same day, but the mathematical solution took me more than expected because I had to review my notes about Numerical Methods viewed years ago in college.

const x = {};
x.loopShapeArea = (n) => {
  let area = 1;
  for (let i = 1; i <= n; i++) {
    area += i * 4 - 4;
  }
  return area;
};

x.recursionShapeArea = (n) => {
  if (n === 1) {
    return 1;
  } else {
    return n * 4 - 4 + x.recursionShapeArea(n - 1);
  }
};

x.mathShapeArea = (n) => {
  return Math.pow(n, 2) + Math.pow(n - 1, 2);
};

const shapeArea = (n) => {
  let solution = {};
  if (0 < n && n <= Math.pow(n, 4)) {
    let obj = {
      0: "loopShapeArea",
      1: "recursionShapeArea",
      2: "mathShapeArea"
    };
    for (let item in obj) {
      let fx = obj[item];
      solution[fx] = {};
      solution[fx].result = {};
      let hrstart = process.hrtime();
      for (let i = 1; i <= n; i++) {
        let result = x[fx](i);
        solution[fx].result[i] = result;
      }
      let hrend = process.hrtime(hrstart);
      solution[fx].execution = {};
      solution[fx].execution.s = hrend[0];
      solution[fx].execution.ms = hrend[1] / 1000000;
    }
    return solution;
  } else {
    return Error("Not a valid number");
  }
};
Enter fullscreen mode Exit fullscreen mode

Result

This exercise has a timeout condition of 4000ms, so it's good to add a way to measure the runtime. From the beginning, I thought that the most optimal solution was going to be mathematics. What do you think? Which one is faster?

let n = 9; //Change this value
const result = shapeArea(n);
for (let item in result) {
  console.log(`${item} -> Execution time (hr): ${result[item].execution.s}s ${result[item].execution.ms}ms.`
  );
}
console.log(result);
Enter fullscreen mode Exit fullscreen mode

Why I love CodeSignal? because sometimes you figured a complicated and elaborated answer and when you can see other solutions found a ridiculous and simple way to solve it. Dam it … why did not I think of that before?

Join us on CodeSignal and enjoy making all that we love… code!

Bonus Track

The first time that I made this code, inject non-desired mistake adding console.log between hrstart and hrstart and this print time was charged to the solution. When I saw the results seem to me estrange that recursion was the winner over math solution.

But once I removed console.log from there saw the true result. So, avoid the additional operation or screen interaction if you want to have a real metric of time spent.


That’s All Folks!
Happy Coding 🖖

beer

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player