JavaScript Functions For Dummies (Me): Part 3
Finding the Area of a Polygon
Finding the Area of a Polygon Using JavaScript
I had to sit down a few times with this one to figure out. But I’m glad I put the time into it because it was an interesting problem!
The Question (from CodeFights)
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.
- For
n = 2
, the output should beshapeArea(n) = 5
; - For
n = 3
, the output should beshapeArea(n) = 13
.
My Thought Process
1) I tried to figure out the pattern by first counting the actual area of the squares. The area of each, starting from n = 1
was: 1, 5, 13, 25, 41, 61, 85
, etc.
2) I then tried to figure out what the relationship was between the area and n = 1
, n = 2
, n = 3
, etc.
I noticed that the area for n = 2
, for example, was the sum of 1 + 4
, and the area for n = 3
, the sum of 1 + 4 + 8
. So there was something going on with the number 4
that I needed to figure out. But what? *cue Jeopardy music for a loooooong time*
3) After a page (or two-ish) of chicken scratch, I noticed the pattern looked something like this:
// Let the "area" of the polygon equal b and...
// c = 4;// where n = 1
// b = 1
// where n = 2
// b = 1 + c(n-1) ...in other words...
// b = 1 + 4(2-1) ...in other words...
// b = 1 + 4(1)
// b = 5
// where n = 3
// b = 1 + c(n-2) + c(n-1)
// where n = 4
// b = 1 + c(n-3) + c(n-2) + c(n-1)
// on and on...
4) I thought using a loop would make the most sense, since I wasn’t sure how to add an additional c(n-whatever)
to get the area of b
.
It took me awhile, but eventually I came up with the below. The idea was that while i
was less than n
, it would print c * (n-i)
. For example, if n = 3
it would calculate 4 * (3–1)
, then 4 * (3–2)
, which is: 8
and 4
, respectively.
c = 4;function shapeArea(n) {
for (var i = 1; i < n; i++) {
b = c * (n-i);
console.log(b);
}
}
5) From here I knew I needed the sum of 8
and 4
plus 1
, since I had already determined where n = 3
, the area was 13
.
In order to do this, I thought it would make sense to:
- Set another variable equal to an array that contained only the number 1:
d = [1]
- Push the results of the above function into that array using
d.push(b)
- Output the sum of the array. Hooray!
In order to reduce the array, I had to use the .reduce()
method. I took some time to familiarize myself with MDN’s docs on this. But essentially, the syntax for .reduce()
is:
arr.reduce(callback[, initialValue])
The callback takes four arguments, one of which is called accumulator
. In other words, it accumulates the sum of the array it’s being called on.
In order to use this, I created a variable called r
(my “reducer”), and passed in the parameters accumulator
and currentValue
, using the arrow function to set it equal to the accumulator
+ currentValue
.
var r = (accumulator, currentValue) => accumulator + currentValue;
In other words, r
my reducer, runs through the array (d
in my case) one currentValue
at a time, and reduces it to the sum of the array.
(The section titled How reduce() works on MDN is very helpful here. It explains callback
, accumulator
, currentValue
, and currentIndex
pretty well.)
The Solution
function shapeArea(n) {
var r = (accumulator, currentValue) => accumulator + currentValue;
var c = 4;
var d = [1];
for (var i = 1; i < n; i++) {
b = c * (n-i);
d.push(b);
}
return(d.reduce(r));
}
Then I clicked on the other solutions to find that le_crosst did:
function shapeArea(n) {
return n*n + (n-1)*(n-1);
}
Just. Wow! For example, where n = 3
, 3*3 + (3–1)*(3-1) = 13
. Much simpler, and a great way to learn from others!