There are a couple algorithms that are consistently asked about in the FCC forums because people are having trouble coming up with a solution. ‘No Repeats Please’ is definitely one of them…

In my opinion, the best place to start any of the algorithm scripting challenges is making sure you completely understand the problem.

Here is the challenge as stated by FCC:

Return the number of total permutations of the provided string that don’t have repeated consecutive letters. Assume that all characters in the provided string are each unique.

For example, `aab` should return 2 because it has 6 total permutations (`aab`, `aab`, `aba`, `aba`, `baa`, `baa`), but only 2 of them (`aba`and `aba`) don’t have the same letter (in this case `a`) repeating.

Ok, not exactly the clearest of problems…  In my opinion, there are two concepts in this algorithm that add to the difficulty.

First, we’re going to have to understand what permutations are and how to find all of them for a given string.  Once we have that, we’ll need to write a regular expression (regex) that looks for repeated letters in each permutation.

Let’s get a better understanding of each of these concepts before we attempt to solve the algorithm challenge.

What are permutations?

The wikipedia page on permutations is a pretty good start if you haven’t been exposed to permutations previously.  It states:

In mathematics, the notion of permutation relates to the act of arranging all the members of a set into some sequence or order, or if the set is already ordered, rearranging (reordering) its elements, a process called permuting.  These differ from combinations, which are selections of some members of a set where order is disregarded.

The key takeaway from this should be that a permutation involves all the members of the set and the order matters.

Part of the given problem states that we should ‘assume that all characters in the provided string are unique’.  This means that for the given example, ‘aab’, the first two letters should be considered unique even though they are both the letter ‘a’.  Therefore, the two permutations without repeats, ‘aba’ and ‘aba’, are considered unique and we must count each of them in the solution.

A quick side note… If you’re looking for further clarification as to the difference between a permutation and a combination, this website does a good job comparing the two…

How can we find all permutations of a string?

Permutations are prevalent throughout many areas of mathematics and computer science.  It should, therefore, be no surprise that there is a well known algorithm, called Heap’s Algorithm, that will find all the permutations for a set of objects.

Keep in mind, there are n! number of permutations for a set of n objects.  So for a string of four letters there are (4 x 3 x 2 x 1) or 24 unique permutations.

Consequently, Heap’s algorithm works on the order of O(n!), the slowest order of functions.  Therefore, as the set gets larger, increases of even one number will cause the algorithm to slow drastically.  To put that into perspective, a set with 15 elements, will have over 1.3 Trillion permutations.

Ok, enough about the theory of permutations, how do we implement Heap’s algorithm?

Heap’s Algorithm

At this point, I’ll only post the pseudocode for Heap’s Algorithm found in Wikipedia, in case there is anyone reading this who is trying to solve ‘No Repeats Please’ and wants to attempt to implement in JavaScript on their own.

Given this isn’t a post specifically about Heap’s Algorithm, I’m not going to go into depth about how it works.  Suffice to say that it systematically switches one pair of elements in each step, eventually yielding every possible permutation.

I encourage you to walk through the algorithm until you understand the workings ‘under the hood’.  The image to the right shows the order of the elements after each iteration of Heap’s Algorithm for a set of 4 elements.

Here is the psuedocode for the recursive version of Heap’s algorithm.  If you prefer to implement non-recursively, there is a version on the algorithm’s  Wikipedia page.

Let’s move on to regular expressions before we put everything together in the final algorithm.

Regular Expressions (RegExp)

In JavaScript, regular expressions are objects used to describe patterns of characters in text.  They’re extremely useful when solving certain problems IF you know how to use them.  That’s a big if, because they are very unintuitive to use and a weakness of many beginner programmers.

w3schools shows the syntax of regular expressions as `/pattern/modifiers;` .  Rather than diving down the rabbit hole of regular expressions, I’ll point out some great resources to learn regex, then write and explain the one we’ll need to solve this challenge.

MDN is a good intro and explains most of what you’ll need for this challenge.  For further learning, Eloquent JavaScript has an entire chapter on regular expressions.  This site will let you practice writing them, and if you’re feeling really ambitious, although I haven’t read it, Mastering Regular Expressions was highly recommended by multiple people on the FCC forums.

A Regex for Repeating Letters

Let’s build a regex that will recognize repeating characters.   We’ll start with `/[a-zA-Z]/`, which will match any and every letter in the string.

Patterns in parentheses are remembered and can be referenced in order (i.e. the pattern in the first set of () can later be referenced as `\1` , the second as `\2`  and so on). Therefore, adding parenthesis like so, `/([a-zA-Z])/`, causes the letter that is matched to be remembered.

Next, adding `\1` after `([a-zA-Z])` will cause the regex to look for a repeat of whatever the `([a-zA-Z])` matched (i.e. a pair of the same letter), which is what we need!

Therefore, our regex for finding a repeating letter is going to look like this `/([a-zA-Z])\1/`  .

Crystal clear right!!

An Additional Note on Regular Expressions

It’s important to note regular expressions are objects in JavaScript and inherit the methods associated with the RegExp prototype.

To solve ‘No Repeats Please’, we’ll be using the RegExp.test() method.  When the test method is passed a string, it will return a Boolean telling you if that string contained the pattern.  So `/([a-zA-Z])\1/.test(str)` will return `true` if there are repeating letters in `str`.

Structuring the Algorithm

Now that we have a better idea of the problem, we can start thinking about how to solve it…  There are a couple ways we can structure this algorithm.

One, we could use Heap’s algorithm to iterate through all permutations of the given string, pushing each onto an array.  Then, having an array with all permutations, we could check each element of the array for repeats.

Or two, we could use Heap’s algorithm to iterate through all permutations, each time checking for repeats and if not found, increment a counter.

I chose to write it the second way with efficiency in mind.  Given the function is on the order of O(n!), we don’t want to iterate through all permutations to create the array, then iterate through again checking for repeats.

This won’t make much of a difference for strings of length 5 or 6, but it will make a huge difference on longer strings.  In fact, to demonstrate this, I tested the function written both ways.

When running the function the first way (iterating twice), a string of 10 characters took 3523ms vs 2287ms for a function written the second way.  When I increased the string to 11 characters it took the second function 26,802ms while the first function failed due to lack of memory.

Now that we have a structure in mind for the algorithm, let’s finally go ahead and write it!

My Solution to ‘No Repeats Please’

If you want to take a stab a writing the solution on your own, now’s the time…  I’m going to post the solution that I came up with below.  Again, there are multiple ways to solve this algorithm challenge, this is just the one that I came up with.

If you were having trouble with ‘No Repeats Please’, hopefully breaking it down like this helped.  This is definitely one of the hardest of the FCC algorithm challenges.

I hope you found this post useful…  If so, feel free to leave a comment and let me know. Thanks for reading, that’s all for now…

-Jeremy

## FCC Advanced Algorithm Scripting Challenge – ‘Symmetric Difference’

Let’s tackle another Free Code Camp advanced algorithm – ‘Symmetric Difference’.  The challenge here is to ‘create a function that takes two or more arrays and returns an array of the symmetric difference (`△` or `⊕`) of the provided arrays.’

The symmetric difference of two sets of elements is the set that occurs in either one of the two sets, but not both (i.e. the symmetric difference of [1,2,3,4] and [3,4,5,6] is [1,2,5,6]).  For more reading on symmetric difference, check out this wiki page.

Free Code camp gives us the following as a starting point:

This is another case where we have to write a function for which we need to handle an unknown number of arguments.  To accomplish this, we’ll be using the arguments object.  I’ve covered the arguments object in a previous post, ‘Seek and Destroy’.  If you are unfamiliar with or would like a refresher of the arguments object, please check it out.

One of the helpful hints FCC provides us with is a link to the Array.prototype.reduce() method.  The arr.reduce method is a great way to cycle through and apply a function to each element of an array.

The arr.reduce method takes 2 arguments, a callback function (which will be applied to each element of the array) and an initial value (the element to provide as the first argument to the first callback function call – see here for more).

If you’re new to JavaScript, or somewhat unclear of what a callback function is, JavaScriptIsSexy.com has an excellent post on callbacks.

The callback takes a possibility of 4 arguments – previousValue, currentValue, currentIndex and array.  This is important, as it means when we write our callback function, we will have access to these 4 values within the function (for further clarity on exactly what the four values are, check out the MDN link mentioned previously).

I think we should break down this challenge into two main problems.  We need to:

• Write a function that returns an array of the symmetric difference (⊕) between two given arrays
• Use this function to handle an unknown number of arguments. For example:
• find (arg1 ⊕ arg2)
• if there’s an agr3, find arg3 ⊕ (arg1 ⊕ arg2)
• continue for argX

At this point, I’m going to start discussing my solution to the problem.  If you’re working through FCC, I’d suggest attempting a solution on your own given what we’ve discussed above. Otherwise, proceed on…

Let’s start by writing the function we’ll use to calculate the symmetric difference between two arrays.

In other words, we need to write a function that receives two arrays as arguments, then returns an array of the numbers that are in one of the argument arrays, but not both.

One way to do this is to

• create a new empty array (curDiff) to store the symmetric diff
• use arr.reduce() to cycle through each array (need to compare each array against the other, not just one against the other)
• in the callback function of arr.reduce
• check if an element is in the other array or in the curDiff array (to prevent duplicates in curDiff)
• if not – push element to curDiff
• hint – arr.indexOf() will return -1 if the given element is not found
• return curDiff

Here’s the JavaScript code:

We now have a function (findSymDiff()) that we can use within our main function to get the symmetric difference between two arrays.  We now have to set up the logic to handle an unknown number of parameters received by our main function.

Our logic (using the arguments object) can look something like this:

• create new array (symDiff) to store the array returned by findSymDiff()
• compare arguments[0] to arguments[1] using findSymDiff()
• cycle through argument[]
• compare symDiff to arguments[x]

To accomplish this, we can set up a simple for loop.

If we set

we can call

in our for loop starting at i=1 and loop while i<arguments.length.

Then all we have to do is return symDiff!

Here’s how everything looks when we put it together:

This solution passes all of the FCC test cases.

Thanks for reading, feel free to leave comments or additional solutions below.  And if you’re working through Free Code Camp, hopefully this helped straighten out the code.

-Jeremy

## FCC Advanced Algorithm Scripting Challenge – ‘Map the Debris’

Today we’ll work through our first Free Code Camp advanced algorithm challenge called ‘Map the Debris‘, which will give us some exposure to working with objects.

This challenge asks us to ‘Return a new array that transforms the element’s average altitude into their orbital periods’

It further tells us that the array will contain objects in the following format:

Finally, it gives us the following as a starting point:

I think, given the limited amount that we’ve spent on objects here at crookedCode, we should start with a brief overview.

I’m not going to reinvent the wheel and write thousands of words on JavaScript objects when so many others have covered it much better than I ever could.

I will, however, point you to, and urge you to read, chapter 4 and chapter 6 of Eloquent JavaScript.  This will take some time, especially if you work through the examples (which I highly recommend) but you’ll have a much greater understanding of objects once you’re done.

Here, I’ll cover objects in enough detail to get us through this FCC algorithm.  If you’ve read the chapters mentioned above, this should all be review.

In JavaScript, objects are basically a collection of properties that can be wrapped together and stored in one variable. Properties consist of {key: value} pairs.

I think the best way to demonstrate this concept is through an example.  I don’t know why, but let’s say I wanted to create myself as an object…  It might look something like this:

This example shows 4 sets of key: value pairs, the first of which is – firstName: ‘Jeremy’ – with firstName being the ‘key’ and ‘Jeremy’ the ‘value’.  All 4 of these properties are now stored under the variable – me.

I can access and manipulate the properties through dot notation (bracket notation can also be used, but we’re going to stick with dot notation throughout this exercise).

In the example below I will access my age and change it to 21 (I know, I know, wishful thinking….).

As you can see when I logged the ‘me’ object to the console, the age has now been changed from 41 to 21.

We’ve seen object properties above as strings or numbers, but they can really be any data type, including other objects or functions.  When a property in an object is a function, it is said to be a ‘method’ of that function.  I’ll demonstrate how we can add new properties to objects below by giving ‘me’ a hair color property and a method.

Ok, suffice to say, this is only scratching the surface with objects in JavaScript, but I think we can move on to solving ‘Map the Debris’.

Before going any further I feel I should say there are many ways to solve this problem…  Some of them, I’m sure, are much more ‘slick’ than mine. This is the solution, however, that I wrote and am providing here as a working solution in an attempt to help anyone who is struggling or looking for a different perspective.

Solving ‘Map the Debris’

We know from the problem description that we will be getting an array of objects as an argument, and that each object in this array will have name and avgAlt properties.

We need to take each of the avgAlt properties, calculate the orbital periods (based on the equation given to us on the Wikipedia page referenced above), and return an array of objects that contain name and orbitalPeriod properties.

First things first, how do we calculate an orbital period?  Below is the formula given on Wikipedia.

This equation might look a little intimidating if it’s been a while since your last math class, but we have all the elements we need.  We just have to rewrite the equation in JavaScript and fill in the correct values.

Fortunately, there’s a Math object in JavaScript that has all the methods associated with it that we’ll need (i.e. pi=Math.PI, squareroot=Math.sqrt(), exponents=Math.pow(base,exponent).  We’ll also use Math.round() to round our answer to the nearest whole number as required by the challenge.

My logic for setting up the solution was as follows:

• Write a function that solved the orbital period given the avgAlt (let’s call the function findOrbPeriod)
• Then write a loop to cycle through the array of objects that
• adds an orbitalPeriod property with a value calculated using the findOrbPeriod function.
• deletes the avgAlt property for each object in the array.
• Return the array.

If you’re working through Free Code Camp, I would suggest taking what we just talked about and try to solve the equation on your own.

Otherwise, proceed on…

Let’s start by writing the function that will solve the orbital period.

As you can see, we use the avgAlt plus the earth’s radius for ‘axis’ in the equation.  The second line in the function is the orbital period equation listed above, only written using the JavaScript Math object.  Finally, we return the orbital period so we can use this function to populate the new orbitalPeriod property of each object.

Now we can tie everything together by cycling through the array of objects (arr) and calling the function we just wrote (findOrbPeriod()) for each object.

As you can see, the for loop adds an orbitalPeriod property to and removes the avgAlt property from each object in arr.  Then all we have to do is return arr.

There we go!!  We made it through our first  FCC advanced algorithm.  Hopefully this helped straighten out the code for you, feel free to leave any questions or comments below.  Until next time…

-Jeremy

## FCC Intermediate Algorithm Scripting Challenge – ‘DNA Pairing’

Today, we’ll cover freeCodeCamp’s Intermediate Scripting Challenge ‘DNA Pairing‘.  The challenge here is to write a function that accepts a string of characters and returns a 2D array of matched base pairs.

If you’re not caught up with your molecular biology, here’s a quick lesson…

Molecular Bio 101 (mostly not needed to solve algorithm)

DNA is the double stranded nucleic acid that carries your genetic information.  Each single strand is composed of units called nucleotides, of which, there are four – cytosine (C), guanine (G), adenine (A) and thymine (T).  In double stranded DNA, these nucleotides bond in specific base pairs, A with T and C with G.

DNA stores all kinds of biological information and make up our chromosomes, which, in turn, make you who you are…  Enough bio, let’s get back to solving the algorithm….

Bio Class Dismissed…

As we get into the intermediate and advanced algorithm challenges, each challenge will have multiple (even many) approaches to a solution.  My plan with Crooked Code is to explain the solution that I used, then search for solutions used by others in order to illustrate the various ways an algorithm can be written.

This is what freeCodeCamp gives us as a starting point for ‘DNA Pairing’:

The instructions provided for this challenge tell us that we’ll be getting a string as an argument and we must return a 2D array that matches up each element (letter) with it’s base pair counterpart.

Let’s get started working on a solution…

I started by ‘splitting’ the string argument into an array using string.split() method.  I covered string.split() in depth here.   I also created some variables that we’ll use later in the function.  My ‘pairElement’ function now looks like:

We now must scroll through ‘singleArr’ and pair up each element with it’s matching pair.  We can use a for loop to scroll through the array, but how can we match up the pairs?

A bunch of if/else statements would work but a switch statement is a better option here.  A switch statement will evaluate a given expression, then transfer control to the case that matches the outcome of the expression.

I’ve included the syntax of a switch statement written by mozilla in order to make the explanation easier.

In our case, the expression will be just a letter, as will each case value.  We can then write a statement to be executed for each individual case.

To sum up the logic for our algorithm…

• split the given string into an array
• loop through array and match each element with it’s pair
• ‘push’ each new pair into 2D array
• return 2D array

At this point, we’ve covered everything needed to solve the ‘pairElement’ function.  If you’re working through the freeCodeCamp curriculum you may want to go try to solve it on your own, otherwise, read on…

Here’s the solution to the ‘DNA Pairing’ challenge that I came up with:

The freeCodeCamp wiki page (written by @Rafase282 and @sabahang) provides 2 solutions to this algorithm challenge.  The first, ‘basic’, solution is very similar to mine, using a switch statement, so I won’t include it for the sake of redundancy.

The second, ‘intermediate’, solution uses an object, and we haven’t really covered objects in much detail here at Crooked Code.  I’ll include the code below so we can see a second, very different solution, but won’t provide an explanation, as objects are far too big of a topic to cover at the end of this post.

You can see an explanation to this solution at the wiki page.

That’s it for now, hopefully this helped straighten out the code…

-Jeremy

## FCC Intermediate Algorithm Scripting Challenge – ‘Boo who’

This post will cover freeCodeCamp’s intermediate algorithm scripting challenge ‘Boo who’.

‘Boo who’ challenges us to write a function that checks if a given argument is classified as a boolean primitive.  If so, return true, if it’s anything else, return false.

The solution, once written, is quite simple but there are a few key concepts we have to understand before we can get there.

Here’s what FCC gives us as a starting point:

Now, we have to figure out…  What the hell is a boolean primitive?

First, let’s consider what boolean means?  Boolean is a word used in both math and computer science.  In computer science, it generally refers to a data type or a variable that can have only one of two values, usually true or false.

Boolean variables are useful in controlling the logic of an algorithm and are generally used in conditional statements such:

Second, what does primitive mean?  Mozilla, as always, gives a pretty good description of a primitive.  Basically, Mozilla tells us a primitive value ‘is data that is not an object and has no methods.’

Tangent on Primitive Types vs. Reference Type

According to the latest ECMAScript standard, JavaScript has 7 data types. 6 primitive types which are string, number, boolean, null, undefined and symbol and one reference type – object.

The difference between the two types becomes confusing when you consider that JavaScript provides constructor functions that allow you to wrap boolean, number and string values as objects, which changes them from primitive to reference type.

Consider the following:

Problems start to arise if you try to use a string object like a string primitive.  Keep in mind that a string object is still an object, and behaves like one.

For instance:

Given that JavaScript will allow you to use the methods associated with an object prototype on the primitive values (example below), it is best to use primitive types whenever possible.

FYI, Effective JavaScript by David Herman has a good section on why primitive types should be preferred to using object wrappers and I derived some of my examples above from those found in his book.

Ok, enough about Primitive Types, hopefully this has been more than enough info to solve ‘Boo who’.

End of Tangent

Check out the Mozilla link above for further explanation of primitive values (or this one for info on the Boolean object), but for our purposes in solving ‘Boo who’ we now know that the only boolean primitives are true and false.

So, now we have to fill in the booWho function above, checking if bool equals true or false.  In doing so, we’ll use the strict equality operator (===) vs. the loose equality operator (==), as the latter will convert the two values to a common type before checking equality, which is not what we want.

At this point, we’ve gone over all the tools you’ll need to write the booWho function, so if you’re working through the freeCodeCamp curriculum you may want to go try to solve it on your own, otherwise, read on…

Here’s the solution to ‘Boo who’ that I came up with:

As you probably know, || is the logical operator ‘or’ in JavaScript, so this function will return true if bool equals true or false.

The freeCodeCamp wiki provides an even shorter solution using the ‘typeof’ operator, written by Rafase282.

Both solutions solve the ‘Boo who’ algorithm challenge and pass all the test cases at freeCodeCamp.

That’s it for now, hopefully this helped straighten out the code…

-Jeremy

## FCC ‘Seek and Destroy’

This post will work through ‘Seek and Destroy’, one of freeCodeCamp‘s basic algorithm scripting challenges.  This challenge will help us introduce the Arguments object and callback functions.

The Seek and Destroy challenge states that ‘provided with an initial array (the first argument in the destroyer function), followed by one or more arguments’ we need to write a function that will remove the values of all the arguments given after the initial array, from the initial array.

Sounds confusing, I know…  Let’s visualize it to clear things up.

One of the major problems we have lies with ‘followed by one or more arguments’…  If we don’t know how many arguments there will be, how do we write a function to handle them?

The answer to that comes in the form of the Arguments object.  JavaScript provides a local variable ‘arguments’ that acts like an array with an element for each argument passed to the function.  You access the arguments just like you would an element of any other array like so:

The arguments object makes solving this algorithm challenge much easier.  Looking forward at ways to solve this problem, we need to a) access the arguments we need to delete from the initial array and b) somehow remove those arguments from the array.

Storing arguments for easy access

The first thing we’ll do is create a new array and store all the arguments (other than the initial array) in it.

As you can see, arguments can be treated like any other array…  Here, we used the length property and looped through arguments (starting at element 1 so as to avoid the initial array, which will be passed in as the first argument, or arguments[0]).  Setting it up this way will handle any number of arguments passed to the destroyer function.

The push() method in JavaScript is used to ‘push’ new elements on to the end of the calling array.

Tools we’ll need to remove arguments from the array

In order to remove the arguments from the initial array, we will use the filter() method.  The filter method introduces a concept we haven’t talked about here at CrookedCode: the callback function.

A Quick note on functions in JavaScript

The power of functions, and what they allow you to do, are core to successful JavaScript programming.  Functions can be passed to and returned from other functions.  They can also be stored as variables.

A function that accepts another function as an argument is called a higher-order function, whereas, the function that is passed as the argument is called a callback function.  The Eloquent JavaScript chapter on functions is a great tutorial on the use of functions in JavaScript.

Eloquent JavaScript also devotes an entire chapter to higher-order functions.  I highly recommend reading and working through the examples in both of these chapters.  If you’re looking for something a little quicker, JavaScriptissexy.com has an excellent article on understanding callbacks and higher order functions.

The filter() method accepts a callback function and performs that callback on every element in the calling array.  If the callback returns true for a given element, that element is kept.  If the callback returns false, obviously, that element is not kept.

As stated above, filter() calls the callback function on every element of the calling array, but it does not mutate that array.  Therefore, you must save the kept elements as a new array.

The one final tool we’ll need before we try to solve this algorithm is the array.indexOf() method.  indexOf() will return the first index at which a given value is found.  If the given value is not found, indexOf() returns -1.

Putting it all together…. (finally)

We’ve already created argArr[] to hold the values that we need to delete from the initial array.  We now need to write a callback function for filter() that will return true if we want the element to stay and false if we want to delete that element.

We know that indexOf() will return -1 if a given value is not found.  We also know that we want to keep elements of the initial array that aren’t found in argArr[].  So, for each element of the initial array, lets call argArr.indexOf(), and return true for values of -1.  Therefore, we’ll be returning true for (and keeping) values that aren’t in argArr[].

Like so:

Wow…  This post covered a bunch of stuff we haven’t previously gone over here at CrookedCode, hopefully this helped straighten out the code for you.  See you next time…

-Jeremy

## FCC ‘Slasher Flick’

Today we’re going to work on freeCodeCamp‘s Basic Algorithm Scripting challenge – ‘Slasher Flick’.  This will be a pretty short post as we’re really not going to cover anything new,  I just wanted to go through this algorithm to show how short and concise a solution to a problem can be.

The ‘Slasher Flick’ challenge is to ‘return the remaining elements of an array after chopping off n elements from the head’.

This is the starting point FCC gives us:

As you can see, we need to write the body of the function ‘slasher’, which accepts an array ‘arr’ and a number ‘howMany’.  slasher should then return ‘arr’ with ‘howMany’ elements removed from the head, or beginning, of the array.

We can actually accomplish this challenge with just 1 line of code.  To do so, we’ll use the array.slice() method, which we first used in the ‘Title Case a Sentence’.

If you remember from that previous post, array.slice() is a method that returns a new array (which is what we need this function to return).  It takes 2 arguments.  The 1st argument is the index of where the returned array will begin, which is conveniently given to us as the argument ‘howMany’.  The 2nd argument for array.slice() is the index of the final element to include in the returned array, and is optional.  Since we’ll be returning the entire array after cutting off ‘howMany’ elements, we’ll only use 1 argument.  If you wanted to include ‘arr.length’ as the second argument to make it more clear, that would work too.

Now, given we have everything we need to return the wanted array, here’s the solution:

This function now returns the given array with ‘howMany’ elements removed from the head.

Obviously this algorithm is pretty simple, it’s part of the ‘Basic Algorithm Scripting’ after all, but I wanted to cover it to show that sometimes the solution can be pretty straightforward and simple…  No need to overthink it.

Hopefully this helped straighten out the code for you.

-Jeremy