CoDEVIANT #1 (3/21/19)

Adrian Rosales
12 min readMar 22, 2019

So I get pissy and emotional about coding sometimes. It’s the truth. It’s a personality flaw, maybe it has something to do with being a Leo, or just being really good at everything else I’ve done except coding ((unfortunately none of those things I’m good at pay well at all)). I’ve always hated doing things that I wasn’t exceedingly good or talented at right off the bat. It’s something I’m coming to terms with. Yeah, I’ll get salty with a tricky algorithm, getting my ass handed to me in a fighting game, or whatever sort of skill and patience-centric activity I find myself starting to like and then finding, quickly, that I am way out of my league in.

Here’s my goal: I’m trying to find a way to balance my work-life as a professional opera singer AND a web developer, specifically a front-end/UX developer of the junior variety because I’m:

  • A: Not smart
  • B: Being an opera singer is a kind of a full time deal as well.
  • C: This is just a lick to me, cuh; if I learned I had the power to turn rain into titanium or gold, I’d be outta here. Sorry, not sorry.

I don’t know if I’m going to be able to pull it off when all is said and done, truth be told…this whole operatic-coder thing. People that I know who are developer’s developers come into coding as if it were a calling.

Not me when it comes to coding

To me, it’s an intricate, super-sized, part-time hustle of a beast that lays golden eggs surrounded in cobwebs of frustration and anger which compels me to throw things (rarely/occasionally, it has been a long time, frankly). But when something I make actually works…I can’t help but smile. And dare I say it…it feels good.

Me when things do work

So in a way, I do love coding…it’s just a weird, potentially unhealthy love not unlike Don Jose & Carmen, or Tyrone Biggums & crack. I l̶i̶k̶e̶ need money…so there’s my entry point into this cacophony of there always better ways of doing a thing and smug internet r̵a̵n̵d̵o̵s̵ geniuses claiming my approach is “naive” 😑…Hearts & Minds, people…hearts & minds.

Because I do believe in putting that hustle in to get better at something you kinda suck at, I’ve started this journal where I’m going to find a coding challenge, solve it (or try to)…explain how I did it in every painstaking, talking to a mouth-breather (if necessary) levels of detail. Then I’m going to find the most advanced solution for it, and try to break down (and in the process learn) how it works. Hopefully through this process you and I will come away learning a thing or two (or more) and I’ll get less good at throwing household items across rooms, fields, parking lots, etc.

We don’t have to be like this…we really don’t!

Sound good? I’m going to be doing about 2–3 things every day…at least that is the aim. Also, I’m a broke af opera-singer, developer, comedian…so if you wouldn’t mind throwing some dough at me through my Patreon or hiring me for some projects, I would really appreciate it. Even if I help only one person who goes on to actually make something of themselves in this coding game, it’s worth it to me.

Find The Vowels — a challenge from CodeWars

https://www.codewars.com/kata/5680781b6b7c2be860000036/train/javascript

Instructions:

We want to know the index of the vowels in a given word, for example, there are two vowels in the word super (the second and fourth letters).

So given a string “super”, we should return a list of [2, 4].

Some examples:

Mmmm => []

Super => [2,4]

Apple => [1,5]

YoMama -> [1,2,4,6]

*NOTE: Vowels in this context refers to English Language Vowels — a e i o u y *

NOTE: this is indexed from [1..n] (not zero indexed!)

So my first thought is to do the following:

  1. We need to make a collection of things to look out for. Our vowels! a, e, i, o, u, y.
  2. We need a new array that starts out as empty to hold our answer.
  3. We need to turn the strings we receive as arguments to the function into arrays.
  4. Then we need to find where the matches are between the elements in our vowelArray and our strings-converted-into-arraysArrays.
  5. When there are matches, push them into an answerArray.
  6. Return the answer array. Profit.

So inside the brackets of the function, I create an array called vowels.

let vowels = [‘a’,’A’,’e’,’E’,’i’,’I’,’o’,’O’,’u’,’U’,’y’, ‘Y’];

*These are the things we are going be looking for in our word argument that gets passed into the function.

Then I made an array called answer that is empty.

let answer = [];

Then I create an array from the word argument by using the string method of ‘split’ with an argument of empty quotes so that something like ‘apple’ will become [‘a’,’p’,’p’,’l’,’e’].

let wordArray = word.split(‘’);

Now I am thinking that for each letter in the wordArray array, I would like to play duck duck goose and check on each member [iterate], so that each letter is available in scope to a sub layer function I’m going to employ in a bit.

wordArray.forEach((letter)=>{//fun stuff coming soon!}

Now inside this new function inside our main function I am going to insert yet another function.

Adrian, what are you talking about? I know…I know.

This newest function will iterate over the members of the vowels array. We will use the forEach method we used above and in the anonymous function telling the computer what to do with each member we’ll call the argument ‘target’.

wordArray.forEach((letter)=>{
vowels.forEach((target) => {
//fun stuff on the way
}
}

Now, I first tried to use, inside the brackets of the vowels.forEach function, the array method of .indexOf(x) to push values into the answer array that we will eventually want to return if the letter & target matched.

wordArray.forEach((letter)=>{
vowels.forEach((target) => {
if(letter == target) {
answer.push(wordArray.indexOf(letter) + 1);
}
}
}

When we put it all together:

function vowelIndices(word){let vowels = [‘a’,’e’,’i’,’o’,’u’,’y’];let answer = [];let wordArray = word.split(‘’);console.log(wordArray);        wordArray.forEach((letter) => {          vowels.forEach((target) => {             if(letter == target) {             answer.push(wordArray.indexOf(letter) + 1);            }          })       })return answer;}

So this should work, right? If I feed it things like “apple”, “orange”, “crip”, we are going to be in the clear.

BUT…you’d be wrong…and I was wrong…and there was much gnashing of teeth and a small amount of soft, indoor-level wailing. The reason is that the array method of indexOf will return the index in the array of what the argument was (in our case letter)…but only the first occurrence of it. So if you pass in “supercalifragilisticexpialidocious”…you’re going to end up with a bunch of repeated numbers.

Instead of ‘[2, 4, 7, 9, 12, 14, 16, 19, 21, 24, 25, 27, 29, 31, 32, 33]’

You’ll get: ‘[2, 4, 7, 9, 7, 9, 9, 9, 4, 9, 7, 9, 29, 9, 29, 2]’

Awesome, right? (No, it’s actually not).

So, I dug around trying to find some clever ways of tricking the array method or doing something to make sure we could get each unique instance of the letter index. But I couldn’t figure it out…so I tried a different approach.

Under the empty answer array that we defined, I created two new variables hard coded at zero: 0.

number & goodNumber.

let number = 0;let goodNumber = 0;

Inside the wordArray.forEach((letter)) function, I had number add to itself by one.

Inside the vowels.forEach((target)) function, I had the goodNumber equal number . Then I pushed that value into the answer array that we will return like so:

answer.push(goodNumber);

See what I did there? I had a counter running with the processing of each letter in the wordArray. Then when there were matches, I had goodNumber equal whatever number happened to be at that moment, then I pushed it into the answer array and moved on with life.

*Note: The criteria for the answer doesn’t want zero-indexed values for the positions of the vowels in the array. Typically when you get [‘b’,’u’,’g’], it would be correct to refer to bug as array[0]…but for whatever reason, they wanted the answer to be 1-indexed, so I didn’t need to push goodNumber — 1 into the answer array.

**Extra Note: I forgot to make the strings lowercased by default, so I very naively, painstakingly entered capital and lowercase vowels into the vowels array

function vowelIndices(word){let vowels = [‘a’,’A’,’e’,’E’,’i’,’I’,’o’,’O’,’u’,’U’,’y’, ‘Y’];let answer = [];let number=0;let goodNumber=0;let wordArray = word.split(‘’);console.log(wordArray);wordArray.forEach((letter) => {    number ++;    vowels.forEach((target) => {         if(letter == target) {         goodNumber = number;         answer.push(goodNumber );         }     })})return answer;}

And now for a cool solution…

So upon submitting my cool little answer, I spotted the “best practice” solution…all sleek, sexy and thin. Behold (courtesy of Kyle S: https://www.codewars.com/users/Kyle%20S).

function vowelIndices(word) {var arr = [];for(var i = 0; i < word.length; i++) {   if(/[aeioyu]/i.test(word[i])) {  arr.push(i+1);   }}return arr;}

Wow…wtf…let’s see how it works, shall we?

So I understand that we are creating an empty array called arr and that we will eventually return it for our answer…that much is kinda silly obvious. He uses a classic for-loop, where we start with an arbitrary variable i as 0, and continue doing the code block as long as i is less than the length of the word, and after each looping of the code block we increment i by 1.

So inside, we have an if statement and we seem to be using regex to match a set of vowels

What is regex? It stands for Regular-Expression. Basically put, it’s a special search string for describing a search pattern.

/ / -> slashes indicate the beginning and the end of a regex expression.

[aeioyu] -> the character set is defined with square brackets we typically associate with creating arrays in javascript. In this context the letters inside are what we are trying to match with.

i -> after the closing slash we see an i and this means “ignore case”…whether it is CAPITALIZED or lower-case, it will match. cool.

.test -> is a RegEx method that compares a regex expression against a string. In this case, we are testing if any of the values in the character set equal to word[i].

WTF is word[ i ]?

Ok, so I learned another new thing today. Apparently, you can utilize ‘character access’, and retrieve the position of a given letter by placing an array looking square bracket flush against a string you’re working with and enter a number.

return ‘pig’[0]; //returns ‘p’

So basically we are using regex to set up seeking for the vowels, in any case and test it against each character in the word argument via character access. Then if they match, we push that number represented by i in the array and add 1 to it, because our answers aren’t supposed to be zero indexed.

Mind = blown. 🤯

Well, I learned about the importance of RegEx in that skirmish. I feel good about coming up with a solution in the first case, but the second one is superior because it has less lines of code (it’s less dad-bodyish) and we are creating and manipulating far fewer variables, which ((if that happens to be your coding style)) will result in a bunch of lag and added processing time if you work that way across an entire application or website.

Sorted? Yes? No? How?

Complete the method which accepts an array of integers, and returns one of the following:

“yes, ascending” — if the numbers in the array are sorted in an ascending order

“yes, descending” — if the numbers in the array are sorted in a descending order

“no” — otherwise

You can assume the array will always be valid, and there will always be one correct answer.

So my thoughts are:

  1. Set up a chan of if else statements that look at the current number and compare it to the next number in the sequence
  2. If the next number in the sequence is larger, return ‘yes, ascending’
  3. If the next number in the sequence is smaller, return ‘yes, descending’
  4. If not, then return ‘no’.

So I went long and set a for loop to have a variable i start at zero, and continue the for loop as long as i was less than the length of the array, then I have the variable i increase by one for each go around.

Inside the for loop I just described, I set the variable of currentNumber to equal the value being iterated over.

for(let i = 0; i < array.length; i++){currentNumber = array[i];}

Then I set up that if/else statement chain.

if(currentNumber < array[i + 1] ) {return ‘yes, ascending’;} else if (currentNumber > array[i+1]){return ‘yes, descending’;} else {return ‘no’;}

So when it’s all put together, it looks like this:

function isSortedAndHow(array) {let currentNumber;for(let i = 0; i < array.length; i++){  currentNumber = array[i];  if(currentNumber < array[i+1]) {  return ‘yes, ascending’  } else if(currentNumber > array[i+1]) {  return ‘yes, descending’  } else {  return ‘no’;  } }}

And I run it….and it doesn’t work. Well, it almost does, but the thing is that it tests the first two elements of an array and assumes that the pattern holds true for the sorting style based on the relationship between them.

Like [5, 10, 15, 20] or [10, 8, 2, 1] would work fine…but [5, 10, -30, 0] would throw a false positive. Quite frankly, I know that I need to be able to compare for each one, but the code inception is kinda blowing my mind a little bit to put it all together right now and I also have a bunch of other things to do right now…so I’m going to avoid the part where I get upset and beat myself up and just take a look at the ‘best practices’ winner for solutions and try to learn from that. I gave it a good try and I’m okay with that.

Can’t win ’em all.

Best Practices Solution by myjinxin2015 (https://www.codewars.com/users/myjinxin2015)

function isSortedAndHow(arr) {return arr.every((x,i)=>i==0||arr[i]>=arr[i-1])?’yes, ascending’:arr.every((x,i)=>i==0||arr[i]<=arr[i-1])?’yes, descending’:’no’}

So small, and sleek. Let’s unravel this SOB.

So we are using an array method called every on the array we call arr. Inside the argument for every we have two variables x and i.

I walked into the Mozilla Developer Docs area about the .every method because I couldn’t understand what those stood for.

The every method tests whether all the elements in the array, arr in our case, pass the test implemented by the provided function. In our case the provided function is the arrow-syntax function that holds x and i. What we now want to know is what role x and i play in our function.

Here is the nice syntax block that Mozilla provides us:

arr.every( callback[, thisArg])

The callback is the function used to test each element in the array we are using the every method on.

Our callback can take 3 arguments, the first of which is mandatory.

  1. Element = the element of the array currently being processed in the array
  2. Index = the index (or address) of the element being processed in the array
  3. Array = the array that every was called upon.

You can also include a value to use as this in a callback which is what [, thisArg] does…but we aren’t dealing with that today. Instead we only are dealing with numbers 1 & 2.

In our callback function, x acts as the element being tested, and i acts as the index for the element being tested in the array.

So in the first line of our best practices solution, when we do:

i==0 || arr[i] >= arr[i — 1]

We are saying that if the index happens to be 0, or if the arr[i] (which is x at the moment) is more than or equal to the arr[i — 1] (the one before it). So if X is more than or equal to the one before it, then we would call it ASCENDING

The opposite is true in the second line where we say that if i (the index of the value being evaluated) is 0 or if arr[i] which stands in for x is less than or equal to the one before it in the array (arr[i-1]), then we would call it DESCENDING.

So now we know how the analysis part for testing each sucker in the array works…but what’s with the question marks and the colons? These are parts of what are called ternary operators. Now in JavaScript, the language we are playing in. The syntax works like this:

aBitOfKnowledgeToEvaluate ? “If it is true” : “If it is false”

Think of it as a shortened if statement.

After the question mark, the first option is for when the aBitOfKnowledgeToEvaluate part happens to be true -> you get the first response. If the aBitOfKnowledgeToEvaluate evaluates as false, then you get the answer or the result behind the colon.

But you can chain these ternary operator sequences like so:

aBitOfKnowledgeToEvaluate ? “If it’s true”:Somethingelse ? “if the next thing is true”:”it was false”;

With that in mind it’s actually more accurate that the answer be presented as one long line, but it wouldn’t be very readable.

function isSortedAndHow(arr) {return arr.every((x,i)=>i==0||arr[i]>=arr[i-1])?’yes, ascending’:arr.every((x,i)=>i==0||arr[i]<=arr[i-1])?’yes, descending’:’no’}

So now we understand the above code. Hopefully in the future you and I will avoid trying to futz around with clumsy for-loops and all other kinds of frustrating foolishness. Then we can finish our work earlier (hopefully), and t̵h̵e̵n̵ ̵s̵i̵p̵ ̵c̵o̵l̵d̵ ̵b̵r̵e̵w̵s̵,̵ ̵b̵u̵y̵ ̵e̵x̵p̵e̵n̵s̵i̵v̵e̵ ̵s̵a̵n̵d̵w̵i̵c̵h̵e̵s̵,̵ ̵l̵i̵s̵t̵e̵n̵ ̵t̵o̵ ̵p̵o̵d̵c̵a̵s̵t̵s̵ ̵a̵b̵o̵u̵t̵ ̵c̵o̵d̵i̵n̵g̵,̵ ̵a̵n̵d̵ play Super Smash Bros. Ultimate. I play a mean Mario and Snake.

My friend-code is 1011–6133–1752, fight me.

--

--