CoDEVIANT #19 — If there’s a problem yo I’ll solve it
Check out the hook while my DJ revolves it!

Adrian Rosales
5 min readOct 7, 2020

--

If other devs are rappers, I’m Vanilla Ice.

…but regardless, I can at least spit some bars and get a single out there. I’m trying to be good. I’m trying to be better. I put my time in, I gets down.

Today’s problem is kinda cool because I learned a new $5 Word: Monotonic.

In the context of an array, it means that the elements are successively either non-increasing or non-decreasing. For the layman (like me): basically, it’s all going up or it’s all going down.

Problem: We want to write a function that takes an array of integers and returns a boolean representing whether the array is monotonic.

Tip: Non increasing elements aren’t exclusively decreasing. They can also be the same as the last one. Vice-versa too.

Adrian’s solution:

function isMonotonic(array) {
let monoArr = []
array.forEach((el, i) => {
if(el > array[i + 1] ) {
monoArr.push('negative')
} else if(el < array[i + 1]) {
monoArr.push('positive')
}
})

monoArr = [... new Set(monoArr)]

if(monoArr.length == 1 || monoArr.length == 0) {
return true
} else {
return false
}
}

First, I create a variable that is an empty array, monoArr.

let monoArr = []

Then I use the forEach method on the array we get provided. For the method’s callback, I use el to signify the element being iterated over and i for the index of the element itself. Inside the block, I say that if el is more than the next el (signified with array[i + 1]) then we push ‘negative’ into the monoArr array. If, however, el is less than the next el (signified with array[i + 1]) then we push ‘positive’ into monoArr.

array.forEach((el, i) => {
if(el > array[i + 1]) {
monoArr.push('negative')
} else if(el < array[i + 1]) {
monoArr.push('positive')
}
})

Next we turn monoArr into a type of an array called a Set. A set takes an array and removes all of the duplicates automatically. It’s really sweet. It takes away any need to come up with a pesky and annoying mini algorithm that we’d have to put inside of this one like Inception.

I got $5 saying that fucker fell over at the end.

So anyways, I make monoArr equal a version of itself that is a set

monoArr = [... new Set(monoArr)]

Then I use an if-statement to get our answer:

  • I say that if monoArr.length equals zero or one, we return true
  • I say that if monoArr.length is anything else, we return false
if(monoArr.length == 1 || monoArr.length == 0) {
return true
} else {
return false
}

The way it works really relies on our use of Set. During the use of the forEach method, we’re just piling on tons of instances of ‘positive’ and ‘negative’ into the monoArr array. When all duplicates are removed, if we are left with only one item, then that means all it ever had were just lots of ‘positive’ or lots of ‘negative’. If we remove all duplicates and we see that we have a length of two, then our array was not monotonic. Simple.

Indubitably…bitch.

So how does a super nerd solve it?

It’s a bird…it’s a plane…it’s a nerd from StackOverflow coming with answers and a side of condescension!
function isMonotonic(array) {
if(array.length <= 2) {
return true
}
let direction = array[1] - array[0]
for(let i = 2; i < array.length; i++){
if(direction === 0) {
direction = array[i] - array[i-1]
continue
}
if(breaksDirection(direction, array[i-1], array[i])){
return false
}
}
}
function breaksDirection(direction, previousInt, currentInt) {
const difference = currentInt - previousInt
if(direction > 0) {
return difference < 0
}
return difference > 0
}

I’mma be real with you. I hate this solution. It’s clumsy, involved, and annoying. But let’s get after it.

  • We say up front that if the length of the array is 2 or less than two, we return true.
if(array.length <= 2) {
return true
}
  • We create a variable direction to equal the 2nd array minus the 1st array
let direction = array[1] - array[0]
  • We create a for-loop and we start our counter variable, i at 2 so as to set our first value that we are comparing at array[i] to be the third element in our zero-indexed array. We keep the loop going so long as i is less than the length of the array and we increment i each rotation.
for(let i = 2; i < array.length; i++ ){
...
}
  • Then we say that if direction equals 0. (i.e. the first two elements of the array are the same), then we set direction to instead equal the current value of the array in the for-loop **array[i]** minus the value before it **array[i -1]**. We also tell the computer to run the continue command. This, within the context of a for-loop, like what we’re in right now, skips the rest of the iteration and starts the next iteration of the for-loop. This is done so we can get to a point where direction does NOT equal zero.
for(let i = 2; i < array.length; i++ ){
if(direction === 0) {
direction = array[i] - array[i - 1]
continue
}

...
}
  • Next, we create another if-statement inside our for-loop to see if a new method we’re about to create returns true and if so, to return false.
for(let i = 2; i < array.length; i++ ){
if(direction === 0) {
direction = array[i] - array[i - 1]
continue
}
if(breaksDirection(direction, array[i-1], array[i])){
return false
}

}
  • Let’s create our helper-method breaksDirection. Basically with the arguments passed in (direction, previousInt, currentInt), we create a variable called difference from subtracting previousInt from currentInt.
function breaksDirection(direction, previousInt, currentInt) {
const difference = currentInt - previousInt
}
  • We then say that if direction (an argument that was passed in) is more than 0, we need to return whether difference (the value we just calculated) is less than 0. If direction is less than 0, we need to return whether difference is more than 0.
function breaksDirection(direction, previousInt, currentInt) {
const difference = currentInt - previousInt
if(direction > 0) {
return difference < 0
}
return difference > 0

}
  • Back to the main function: Should the if-statement’s condition yield false for the rest of the for-loop iterations, then we just return true.
return true
Right?

So basically. We

  • determine right away if the array is too damn small to be anything but monotonic — in which case we return true
  • We set up a variable called direction and hack a for-loop to do some comparison work for us.
  • Once direction is not zero, we pass it to a method along with the previous value from the for-loop and the current value from the for-loop.
  • In this outside method, we say say that if the direction is more than 0 (as in, this is an upwards monotonic array), we ask the method to return whether the difference between the currentInteger and the previousInteger is less than 0, which would prove that our direction changed. And we also do the vice versa to prove that our direction changed (if direction is a negative trend, we return whether difference is larger than 0 to show whether our direction changed).

Okay, paisanos. It’s been real, but I gotta get myself to bed.

Me watching Netflix while ‘sleeping’

--

--