I need to make a function so that it will return the starting and ending index of the widest pasture as well as the width.
It needs to return an array in this particular order.
[length, starting_index, ending_index]
As an example, for "_-___-__-____-______-_"
, the return value should be [6, 14, 19]
.
If there are multiple pastures that have the same length, return the position of the pasture towards the end of the array.
As an example, for "_-___-__-___-"
, the return value should be [3, 9, 11]
.
If the widest pasture length is 0, such as "---"
, return 0 for all the values [0, 0, 0]
.
var widestPasture = function (landscape) {
// Implement your code below
let array = landscape.split("-");
let greatest;
let tillGreatest = 0;
let endIndex;
let answer = [];
for (let i = 0; i < array.length; i++) {
if (array[i + 1] !== undefined) {
greatest = array[i].length;
}
}
for (let i = 0; i < array.length; i++) {
if (array[i].length < greatest) {
tillGreatest += array[i].length;
}
}
let startIndex = tillGreatest += 1;
tillGreatest += 2;
endIndex = tillGreatest + greatest -1;
answer = [greatest, tillGreatest, endIndex];
return answer;
};
console.log(widestPasture("_-___-__-____-______-_"));
// -> [6, 14, 19]
console.log(widestPasture("_-___-__-___-"));
// -> [3, 9, 11]
The issue I’m running into is figuring out how to output the [3, 9, 11]
. Currently the second output is [3, 6, 8]
. It feels like the solution is something simple right in my face but I can’t grasp it and all my other attempts have resulted is breaking the currently working code.
Is my only option rewriting from the beginning?
5
Answers
The first problem is that the variable
greatest
is set to one-but-last partition without comparing which partition is the longest. Even if the first partition would be the longest,greatest
will still be overwritten with the length of a next array — even when it is shorter.Secondly, the
tillGreatest
variable gets the sum of the lengths of arrays that are shorter than the greatest. But this will also include lengths of arrays that come after the greatest.Another issue is that you lose track of the starting indices because of the split. You try to overcome this with
+= 1
and+= 2
, but this is not generic enough. Honestly, the split into partitions made this harder than necessary.I would suggest not to do the split, but just iterate each character of the
landscape
string and keep track of the starting index of the current series of_
, and derive its length. Then you can update the answer array whenever you get a length that is greater than what was registered before.Here is how that looks:
I was going to type Trincots explanation regarding the
greatest
variable, so I won’t repeat that here, and their solution is great. Here’s an alternative solution so you can see different ways of getting to itA feasible approach utilizes
matchAll
which is going to match this simple regex …/_+/g
… a sequence of underscore characters (globally).The result array contains matching items where each item features the match itself (the underscore sequence) and e.g. the
index
property which indicates the match’s starting position.sort
ing the array of matching items, by each item’s match length in an ascending order, will feature the OP’s matching result of interest as the sorted array’s last item. From this very item one can create/assemble the result array which the OP is looking for.You can find a simple solution below which loops through the input characters, finds the pastures and whenever it finds a better pasture than the best so far it will become the new best so far. You can find detailed explanation between the lines.
This is how the solution looks alike without the comments
Just to explore various ways to accomplish the same functionality, we can use Regular Expressions and matchAll method of Strings.
/_+/g
is a Regular Expression defined in JavaScript. To define a Regular Expression in JavaScript we begin and end with / (slash) character. Then we write the rules between these shales. Here, I wrote_+
to match occurences with at least one or more underscores. After the ending slash we can type some additional characters to define flags of our Regular Expression; by typingg
after the expression, we define a global expression. Global flag allows to match all occurences for the given string, otherwise we would only match the first occurence. To usematchAll
method, we need to have a global Regular Expression. Below code uses these features:Side note: To test regular expressions easily and explore more about them, you can visit RegExr. It has a nice, clean and very helpful UI. If you ever need to work with Regular Expressions, this website is a must-have tool.