For this challenge on HackerRank:
A valley is a sequence of consecutive steps below sea level, starting with a step down from sea level and ending with a step up to sea level.
Given Gary's sequence of up and down steps during his last hike, find and print the number of valleys he walked through.
For example, if Gary's path is s=[DDUUUUDD], he first enters a valley 2 units deep. Then he climbs out and up into a mountain 2 units high. Finally, he returns to sea level and ends the hike.
I reached a solution, but I'm sure it can be optimized:
function countingValleys(n, s) {
let heightTracker = [];
let height = 0;
for (let i = 0; i < s.length; i++) {
if (s[i] === "D") {
height--;
heightTracker.push(height);
}
if (s[i] === "U") {
height++;
heightTracker.push(height);
}
}
let planeTracker = [];
for (let j = 0; j < heightTracker.length; j++) {
if (heightTracker[j] < 0) {
planeTracker.push("valley");
}
if (heightTracker[j] > 0) {
planeTracker.push("mountain");
}
if (heightTracker[j] === 0) {
planeTracker.push("flat");
}
}
let newArray = [];
for (let k = 0; k < planeTracker.length; k++) {
if (planeTracker[k] === planeTracker[k - 1]) {
continue;
}
if (planeTracker[k] !== planeTracker[k - 1]) {
newArray.push(planeTracker[k]);
}
}
let valleyCount = 0;
for (let l = 0; l < newArray.length; l++) {
if (newArray[l] === "valley") {
valleyCount++;
}
}
return valleyCount;
}
My logic was to keep track of all negative and positive values in s
.
- If
heightTracker[j]
is negative, push "valley" intoplaneTracker
- If
heightTracker[j]
is positive, push "mountain" intoplaneTracker
- Otherwise, push "flat" into
planeTracker
So at that point, I'm left with:
[ 'valley', 'valley', 'valley', 'flat', 'valley', 'valley', 'valley', 'valley', 'valley', 'flat', 'mountain', 'flat' ]
And I'm wondering, is there a way to filter out any elements that are the same as the element before them? The goal was to generate the array:
[ 'valley', 'flat', 'valley', 'flat', 'mountain', 'flat']
and then count the number of times the word "valley" appears in that array. As you can see, I did this with a for-loop. But I'm wondering what other suggestions you'd have - maybe the .filter()
method?
2 Answers 2
You're vastly overcomplicating the solution by introducing three arrays heightTracker
, planeTracker
, and newArray
. None of those is needed: just track the elevation
(which is a better name than height
), and go by the definition:
A valley is a sequence of consecutive steps below sea level, starting with a step down from sea level and ending with a step up to sea level.
So, the number of valleys traversed is the number of times Gary's elevation changes from -1 to 0.
function countingValleys(n, s) {
let elevation = 0;
let traversedValleys = 0;
for (let i = 0; i < n; i++) {
if (s[i] === "D") {
--elevation;
} else if (s[i] === "U") {
if (++elevation === 0) traversedValleys++;
}
}
return traversedValleys;
}
-
\$\begingroup\$ Interesting, what is the difference between
--elevation
andelevation--
or++elevation
andelevation++
? \$\endgroup\$HappyHands31– HappyHands312019年07月12日 01:40:25 +00:00Commented Jul 12, 2019 at 1:40 -
1\$\begingroup\$ See Increment operator.
++elevation === 0
means to incrementelevation
before comparing with 0. \$\endgroup\$200_success– 200_success2019年07月12日 01:44:54 +00:00Commented Jul 12, 2019 at 1:44
I found that instead of using the for-loop, I can use filter()
like this:
planeTracker = planeTracker.filter((element, index, arr) => element !== arr[index + 1]);
To get rid of the elements that are the same as the previous element.
-
\$\begingroup\$ You shouldn't need
planeTracker
in the first place. But this is also poor style, since it ventures one element past the end of the array. \$\endgroup\$200_success– 200_success2019年07月12日 01:47:23 +00:00Commented Jul 12, 2019 at 1:47 -
\$\begingroup\$ What if I switched it to
arr[index - 1]
- still bad practice? Ventures one element before the start of the array, correct? \$\endgroup\$HappyHands31– HappyHands312019年07月12日 02:00:08 +00:00Commented Jul 12, 2019 at 2:00 -
\$\begingroup\$ Accessing before the beginning of the array feels even ickier. \$\endgroup\$200_success– 200_success2019年07月12日 03:05:00 +00:00Commented Jul 12, 2019 at 3:05
Explore related questions
See similar questions with these tags.