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.

# 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");
}
};
```

# 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);
```

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 nondesired 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** 🖖

## Discussion (18)

I think think there's an even easier solution:

I think this is more appropriate:

function shapeArea(n) {

return (1 + (n-1)*n) *2 - 1

}

Why do you think that formula ?

Did you solve it?

Hey buddy, can you explain your solution?

Yeah, that's exactly the beauty that I talk about code fights. You can learn from other solution.

I found this solution and just replaced the variables

function shapeArea(n) {

return 1 + 2 * n * (n-1)

//1 + 2 * 4 * (3) = 3*4=12*2=24+1=25

//1 + 2 * 3 * (2) = 2*3=6*2=12+1=13

//1 + 2 * 2 * (1) = 1*2=2*2=4+1=5

//1 + 2 * 1 * (0) = 0*1*=0*2=0+1=1

}

Hi! Would it be possible for someone to explain what's happening in the code? I'm a beginner to both code and maths. Any resources and tutorials would be appreciated too :)

There is no tutorial about this specific ploblem. You need learn other concepts like recursion and loops.

This function

`shapeArea`

is not important. It's used to measure the amount of time.Relevant things on this exercise is

`x.loopShapeArea`

,`x.recursionShapeArea`

and`x.mathShapeArea`

. Three of them solves the problem, but math is more efficient than others.But where did you get the 4 from & multiplying it ?

For example when I can recite something for 60 times in a min so if i recite for 100 mins i just do 60 * 100 to find out how many times I recite a line.

What was ur reasoning behind using the number 4 ? I am not clear on how I would go on solving this on my own. @

I'm using a technic learned in a subject Numerical Methods. You need reproduce step by steep and try to find something familiar between each interaction.

A square have 4 sides, that's why you need multiply the value by four.

But each side merge a point with other in the other side (red circle), you can't count both. That's why yo need subtract 4, one for each corner.

That's how I found this formula:

`n * 4 - 4`

On first and second iteration is difficult to see it... but next iterations can give you an idea about the solution.

Hope it helps.

the simpler way I think is:

Just rotate the grid view by 45º and check the patterns

return n*n + (n-1)*(n-1);

It's more like:

function shapeArea(n) {

var res = 1;

for(let i = 1; i < n; i++){

res = res + (i*4)

}

return res;

}

`return n * ((n - 1) * 2) + 1;`

n*(n*2*-1)-int((n*2-1/2)

this is the shortest valid solution :

int output = 1;

for (int i = 1; i <= n; i++) {

if (i != 1) {

output = output + 4 * (i - 1);

}

}