Make a Person

From the FreeCodeCamp intermediate algorithms here:

Fill in the object constructor with the following methods below:

getFirstName()
getLastName()
getFullName()
setFirstName(first)
setLastName(last)
setFullName(firstAndLast)

FreeCodeCamp – Make a Person

As with all code there are probably multiple ways to complete this challenge. My feeling is that this solution is quite straightforward, but that perhaps could be just from my own perspective. Somebody else might find another method is more simple and easier to understand for them.

I will quickly run through the methods (mentioned in the challenge) and how I implemented each of them.

getFirstName()

I chose to store the full user input in a variable which I called ‘fullName’. So for example, if the user input was “Bob Smith”, then this string becomes the ‘fullName’ variable.

To return just the first name of this I used fullName.split(' ')[0] to create an array, which puts each word into an array entry, and then used square bracket notation to access the first entry.

In our “Bob Smith” example.

The string 'Bob Smith', becomes an array: ['Bob', 'Smith'], and then 'Bob' as the zero-th element is returned.

getLastName()

This is almost exactly the same as above, except I needed to access and return the second element of the array. Like so: fullName.split(' ')[1]

setFirstName(first) & setLastName(last)

For these two I needed to re-assign part of the ‘fullName’ variable which I had created earlier.

To do this I used a similar method to above, but instead of returning part of the variable I concatenated part of the variable with the new input from the function, and assigned this to the variable name. Like so (for setFirstName()):

fullName = input + ' ' + fullName.split(' ')[1];

setFullName()

And finally I’m not afraid to admit that this baffled me for a few seconds… but to set the full name all I needed to do was reassign the variable to the new input from the function. Really it is the same as above, but just without having to split up the string, as this function expects the full name as an input. Like so:

fullName = input;

And that’s it. Full code below. How did you do this? What do you think of my solutions?

My solution:

var Person = function(firstAndLast) {
  // Complete the method below and implement the others similarly

  let fullName = firstAndLast

  this.getFullName = function() {
    return fullName;
  };
  this.getFirstName = function() {
    return fullName.split(' ')[0];
  };
  this.getLastName = function() {
    return fullName.split(' ')[1];
  };
  this.setFirstName = function(input) {
    fullName = input + ' ' + fullName.split(' ')[1];
  }
  this.setLastName = function(input) {
    fullName = fullName.split(' ')[0] + ' ' + input;
  }
  this.setFullName = function(input) {
    fullName = input;
  }
};

var bob = new Person('Bob Ross');
bob.getFullName();

Arguments Optional

From the FreeCodeCamp intermediate algorithms here:

Create a function that sums two arguments together. If only one argument is provided, then return a function that expects one argument and returns the sum.

For example, addTogether(2, 3) should return 5, and addTogether(2) should return a function.

Calling this returned function with a single argument will then return the sum:

var sumTwoAnd = addTogether(2);

sumTwoAnd(3) returns 5.

If either argument isn’t a valid number, return undefined.

FreeCodeCamp – Arguments Optional

Forgive me for not writing out my thought process! I got excited for getting so close to the end of the Intermediate algorithms and just moved on! My code is below though!

My solution:

function addTogether() {
  let x = arguments[0];
  let y = arguments[1];

  if (typeof x !== 'number') {
    return undefined;
  }
  
  if (typeof x === 'number' && typeof y === 'number') {
    // console.log('yess')
    return x + y;
  } else if (typeof y === 'undefined') {
    return function() {
      if (typeof arguments[0] === 'number') {
        return x + arguments[0];
      } else {
        return undefined;
      }
    }
  }
}

addTogether(2, 3);

Everything Be True

From the FreeCodeCamp intermediate algorithms here:

Check if the predicate (second argument) is truthy on all elements of a collection (first argument).

In other words, you are given an array collection of objects. The predicate pre will be an object property and you need to return true if its value is truthy. Otherwise, return false.

In JavaScript, truthy values are values that translate to true when evaluated in a Boolean context.

Remember, you can access object properties through either dot notation or [] notation.

FreeCodeCamp – Everything Be True

For this challenge I decided to evaluate each item in the given object against the given predicate, and count the amount of times this check returned as true.

To do this, I began a for loop, and then used a conditional check to add one to the count variable, like so:

  for (let i = 0; i < amount; i++) {
    if (collection[i][pre]) {
      count++;
    }
  }

If this counted amount was equal to the amount of items in the object then the function could go ahead and return true. If the amounts didn’t match it could return false. So here I just needed a conditional return statement, like so:

  if (amount === count) {
    return true;
  } else {
    return false;
  }

My solution:

function truthCheck(collection, pre) {
  // Is everyone being true?
  let amount = collection.length;
  let count = 0;

  for (let i = 0; i < amount; i++) {
    if (collection[i][pre]) {
      count++;
    }
  }

  if (amount === count) {
    // console.log(true)
    return true;
  } else {
    // console.log(false)
    return false;
  }
}

truthCheck([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex");

Binary Agents

From the FreeCodeCamp intermediate algorithms here:

Return an English translated sentence of the passed binary string.

The binary string will be space separated.

FreeCodeCamp – Binary Agents

For this challenge I began by splitting the binary string into an array of the given 8 bit blocks. This would make it a lot easier to work with.

Then, I declared the arrays which I thought that I’d need to translate binary into English! So I declared a ‘decimalArr’, which I planned to add each block into once I’d translated it from binary to decimal, and then also a ‘letterArr’, which I would then fill with the letters which I had translated from decimal into letters. To do this last part I used the ASCII codes for each.

I found that in order to translate binary to decimal I needed to take each bit from the byte block and multiply it by a descending power of two – beginning from 7 and going down to 0. And then to add the decimal digits we have at the end together. Or to spell it out a bit more clearly, if we have the byte: ‘01000001’, we would:

  • Take the first 0 and multiply it by 2 to the power of 7 – 0 * 2^7 = 0
  • Take the second digit, which is 1 and multiply it by 2 to the power of 6 – 1 * 2^6 = 64
  • And continue this way – 0 * 2^5 = 0
  • 0 * 2^4 = 0
  • 0 * 2^3 = 0
  • 0 * 2^2 = 0
  • 0 * 2^1 = 0
  • 1 * 2^0 = 1
  • And finally to add 64 and 1 together = 65.

Then once we have this number, it can be translated into ASCII with a conversion chart. Or thanks to JavaScript just with a String method. I did this by reducing the array down to the final value, and then by adding each decimal item into the decimal array.

From there I mapped the decimal array to a new array by making each element a String (and using the .fromCharCode() method to do so), and then returned the array joined into the final string.

My solution:

function binaryAgent(str) {
      let binaryArr = str.split(' ');
      let decimalArr = [];
      let letterArr = [];
      for (let i = 0; i < binaryArr.length; i++) {
        let str = binaryArr[i];
        let power = 7;
        let tempArr = [];
        for (let j = 0; j < str.length; j++) {
          let dec = str[j] * (Math.pow(2, power));
          tempArr.push(dec);
          power--;
        }
        decimalArr.push(tempArr.reduce((a, b) => a+b));
      }
      letterArr = decimalArr.map(x => String.fromCharCode(x));
      return letterArr.join('');
    }
    
    binaryAgent("01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111");

Steamroller

From the FreeCodeCamp intermediate algorithms here:

Flatten a nested array.

You must account for varying levels of nesting.

FreeCodeCamp – Steamroller

A quick post today about flattening nested arrays down to one array.

However a quick google of ‘flatten nested arrays in javascript’ lead me here.

… which essentially takes care of this algorithm for us.

My solution:

function steamrollArray(arr) {
  // I'm a steamroller, baby
  return arr.flat(Infinity);
}

steamrollArray([1, [2], [3, [[4]]]]);

Interesting stack overflow answer about accessing different levels of arrays here.

Drop It

From the FreeCodeCamp intermediate algorithms here:

Given the array arr, iterate through and remove each element starting from the first element (the 0 index) until the function func returns true when the iterated element is passed through it.

Then return the rest of the array once the condition is satisfied, otherwise, arr should be returned as an empty array.

FreeCodeCamp – Drop It

This challenge seems so simple. But as per usual with simple looking challenges there are a few different places where you can really trip up. All you need to do in this one is go through the array, check if each item is false according to the given function and then remove the item if it is false – once you get to the first true item (according to the given function) break the loop and return the rest of the array. Easy.

I started writing a for loop and then thought: Hang on! I’ve been learning about mapping arrays, reducing arrays and filtering them, and sometimes this just needs one line – maybe I can do this in one line of code! I knew it wouldn’t be reduce because this returns only one value, but filter seems like it will work. So I scrapped the for loop and wrote this line:

console.log(arr.filter(func));

That should do right? Nope. The key thing to remember in this challenge is that it actually asks you to iterate through and then stop once you get to a true value. The filter function mentioned will check every value and only return the values which evaluate to true. This means anything after the first true element that is false will be lost too. For example in the array [0, 1, 0, 1] and with the function: ‘return n === 1’, using the filter mentioned above will only return [1, 1], but we actually need it to return [1, 0, 1].

So… back to the for loop it is then. And after a quick google to find the best way to remove an item from an array, and after throwing .pop(), .splice() and .slice() away (they are useful in the correct context, but here we just need to remove the item which we are currently inspecting), .shift() comes out as the winner here!

Easy – so we’ll check the item is false, remove it if so, and then move onto the next item. If it is not false, we’ll check if it’s true and then break from the loop if so and return the array.

Great – it works… but not for all of the tests! What is this….? The test it is failing for is this one:

dropElements([1, 2, 3, 4], function(n) {return n > 5;}) should return [].

I popped in some ‘console.log(arr)”s (everywhere!), and found that the loop was running twice and then stopping despite not having reached a true value, and so the returned array was [3, 4] and not the empty array expected. How could this be!? After some testing I could see it had to do with the way I had written my for loop. I’d gone for the standard for (let i = 0; i < arr.length; i++). But within the for loop we are purposefully resizing the array, and so we can’t rely on arr.length to be correct. In fact in the test given above the loop functions correctly twice (2 times), and then stops – because the new length of the array is 2. And so the loop has done what’s expected of it already – looped through 2 times.

This is an easy fix – we need the loop to go through right to the end, or to break once it finds a true value. So we just need to fix the amount of loops based on the array’s original length by declaring a variable outside of the for loop.

My solution:

function dropElements(arr, func) {
  // Drop them elements.
  // create varible for length of original array
  let loop = arr.length;
  // start loop
  for (let i = 0; i < loop; i++) {
    // if false remove, if true break
    if (!func(arr[0])) {
      console.log('remove item', arr);
      arr.shift(i);
    } else if (func(arr[0])) {
      break;
    }
  }
  // return array
  return arr;
  // console.log(arr.filter(func));
}

dropElements([1, 2, 3, 4], function(n) {return n > 5; });

Smallest Common Multiple

From the FreeCodeCamp intermediate algorithms here:

Find the smallest common multiple of the provided parameters that can be evenly divided by both, as well as by all sequential numbers in the range between these parameters.

The range will be an array of two numbers that will not necessarily be in numerical order.

For example, if given 1 and 3, find the smallest common multiple of both 1 and 3 that is also evenly divisible by all numbers between 1 and 3. The answer here would be 6.

FreeCodeCamp – Smallest Common Multiple

Tricky. From the challenge description I could tell there would need to be a two-pronged attack with this one. I knew I would need to write a function to find the lowest common multiple of the two given numbers, but then I was initially not sure of how I would then check each of the numbers in the range…. As I said yesterday – maths is not my strongest subject!

Anyway, I thought I would plough ahead and then deal with the issue later. So that’s what I did. At first I sorted the array so that it would be easy to grab the smallest and largest values. I needed a little bit of google for this, as I knew there is a sort Array method, but I knew that if you called it without a function it sometimes does funny things – logical, but still funny.

So a quick google told me that you need to specify which of the values would be lowest by providing the function with a value of less than zero. This sounds like it doesn’t make sense but, as with all programming, it makes perfect sense. Let’s use an array of 1 and 5 as an example.

let arr = [1, 5];

arr.sort((a,b) => a - b);

So, in this example we can substitute a and b directly for 1 and 5. 1 – 5 is -4. If we swapped these around and arr = [5, 1], the sort function would do this: 5 – 1 = 4.

This tells the function that each item is in the incorrect place. It is effectively saying a needs to be less than b. If the array was [5, 1, 3, 7, 4] – then the function would sort it in sequence.

  • 5 – 1 = 4 (these need to be swapped)
    • 1 – 5 = -4 (good swap)
  • 5 – 3 = 2 (these need to be swapped)
    • 3 – 5 = – 2 (good swap)
  • 5 – 7 = -2 (these do not need to be swapped)
  • 7 – 4 = 3 (these need to be swapped)
    • 4 – 7 = -3 (good swap)
    • At this point the array is [1, 3, 5, 4, 7] (not completely sorted).
  • 5 – 4 = 1 (need to be swapped)
    • 4 – 5 = -1 (good)
  • Final sorted array = [1, 3, 4, 5, 7]

If that makes sense…? That’s how my mind worked it out anyway – I’m not sure if that’s the exact order it would be done in, or if a sort like this is good or bad in terms of time complexity. Harvard University’s CS50 course was really interesting and helps newbs like me to understand things like this a little better.

Sorry – that was quite a long winded way to explain a sort function, but going through it like that helped me to understand it anyway!

Anyway – so that’s the first line of code reviewed! 😂😲

You can see in my solution I commented today’s code because I knew I’d need to refer to them to make it easier to see what’s going on.

Populating the range array is fairly standard – I’ve taken the two numbers and with a for loop pushed each number from the min up to and including the max (it’s important to include the max to get the correct output for this challenge). So in our example of arr = [1, 5], our shiny new ‘range’ array = [1, 2, 3, 4, 5].

And then, with some help from this FreeCodeCamp forum answer (thanks!) I worked out that finding the lowest common multiple (lcm) of every number in the range could be done by finding the first two’s lcm, and then that number and the next in the ranges’s (that forum answer explains it well using sum of 1, 2 and 3 as a good example). We need to get one number from a group of numbers, and so we need to ‘reduce’ the numbers down to that final output – can you guess which method we’ll need to use!? But of course I need a function (which will be to obtain the lcm) to go into the reduce method, otherwise it is useless.

The lcm function at the bottom of the code block is fairly simple. The pseudocode would be something like:

let originalMax = // some value
let min = // some value
let max = originalMax;
while (max % min !==  0) {
	max = max + originalMax;
} 
return max;

Or, in words:

While the max number divided by the minimum number does not divide without a remainder, add the original max amount to the max and then try again. Once the (new) maximum and the minimum divide without a remainder the new maximum is the lowest common multiple.

So with 1 and 5. 5 divided by 1 is 5 and there are no remainders so 5 is the lcm.

With 2 and 5. 5 divided by 2 is 2.5 – or 2 with a remainder of 1. So we would add 5 to 5 and try again. 10 divided by 2 is 5. No remainder. And so 10 is the lcm.

And there you have it.

I’m sure that’s mostly all gibberish to anyone who will read this. But that’s my thought process anyway… 😂 How would you approach this problem?

My solution:

function smallestCommons(arr) {
      // sort arr from smallest to largest
      arr.sort((a, b) => a - b);
    
      // declare variables and give values
      let min, max, range = [];
      min = arr[0];
      max = arr[1];
      // populate range array
      for (let i = min; i <= max; i++) {
        range.push(i);
      }
      
      // return a reduction of the range - reduced to lcm with lcm function
      return range.reduce(lcm);
    
      // function to find lowest common multiple (lcm)
      function lcm(min, max) {
        let i = max;
        while (i % min !== 0) {
          i+=max;
        }
        return i;
      }
    }
    
    smallestCommons([1, 5]);

Sum All Primes

From the FreeCodeCamp intermediate algorithms here:

A prime number is a whole number greater than 1 with exactly two divisors: 1 and itself. For example, 2 is a prime number because it is only divisible by 1 and 2. In contrast, 4 is not prime since it is divisible by 1, 2 and 4.

Rewrite sumPrimes so it returns the sum of all prime numbers that are less than or equal to num.

FreeCodeCamp – Sum all Primes

Although I’m not great at maths, I am aware of prime numbers… And so I didn’t think this would be quite so hard as it actually turned out to be!

My approach (I’m sure there are others, many better I’ve no doubt) involved writing a function which would check whether or not a number was prime. Then using a for loop to go through the numbers from 0 to ‘num’ (the given number from the function argument), checking each one for primality, and then adding those that are prime to an array. Once I had this array all I’d need to do is run a .reduce() method with a function that would add each array entry to the next. A bit like I had done in the previous challenge.

Simple right?

Not as simple as you might imagine. Writing a prime function is a bit difficult.

I read through a few examples online, and found this one the most helpful in the end. If I’m honest, some of them I struggled to understand and couldn’t really work out.

In the end I decided the best thing to do would be to eliminate the base cases of ‘num’ being either less than 2, or 2, and also if ‘num’ is divisible by 2 (and isn’t 2). Essentially the function needs to reply true for 2, but false for 0 or 1.

I used an if statement to catch anything less than or equal to 2 (and returned it true if num == 2, but false if else. And then a simple if (num % 2 == 0) check too.

Then, using the logic from the post mentioned above, I assumed that ‘num’ would be a prime and then tried to prove that it’s not as a check. To do this we can check the primality of num by using a for loop which starts at 2, and goes up to the square root of ‘num’. Prime numbers obviously don’t have a rational square root and so the check given (using a modulus to check if the remainder of the division is equal to zero) will always be false for a prime number, and true for a non-prime number.

So anyway, once the math-sy bit was out the way I could just go from 0 up to ‘num’ using a for loop, checking for primes, and add any primes into an array. I did this, and wrote a quick return statement using primes.reduce((a,b) => a+b). This would ensure that each entry (a) in the primes array was added to the next (b), which would result in one figure – all of the primes added together.

I hit the ‘Run the tests’ button with absolute confidence!

😒 But no – a failed test, how could this be!?

So the test for ’10’ was returning fine, but the test for ‘977’ was not working! 🤔

That’s a large number I thought, I’ll never be able to work this out I thought! I’m doomed… 😢🤷‍♂️

But actually, I calmed down and took a breath, and looked at my code once more. At this point I tried a test of my own – I knew that the number 11 was a prime so I console.log()-ed the function with an 11. But the output was still ’17’, the same as my result for 10.

That’s it – that’s the issue.

10 is not a prime number, 11 is. So my code must not be pushing the final prime number in the sequence (from 0 to ‘num’) onto the array. If the given ‘num’ is a prime number then my reduce statement isn’t adding that final value on, because it’s not in the array.

I checked and ‘977’ is a prime number, and the final check result was off by, you guessed it, 977!

So my for loop for pushing the primes onto the array needed to read for (let i = 0; i <= num; i++) instead of i < num!

My solution:

function sumPrimes(num) {
  let primes = [];
  for (let i = 0; i <= num; i++) {
    if (isPrime(i) == true) {
      primes.push(i);
    }
  }
  return primes.reduce((a,b) => a+b);
  //console.log(primes)
  //console.log(isPrime())
  function isPrime(num) {
    // Base cases:
    if (num <= 2) return (num == 2);
    if (num % 2 == 0) return false;
    // Logic:
    let prime = true;
    for (let i = 2; i <= Math.sqrt(num); i++) {
      if (num % i == 0) {prime = false}
    }
    return prime;
  }
}

sumPrimes(10); // '17'
sumPrimes(977); // '73156', not '72179'!

Sum All Odd Fibonacci Numbers

From the FreeCodeCamp intermediate algorithms here:

Given a positive integer num, return the sum of all odd Fibonacci numbers that are less than or equal to num.

The first two numbers in the Fibonacci sequence are 1 and 1. Every additional number in the sequence is the sum of the two previous numbers. The first six numbers of the Fibonacci sequence are 1, 1, 2, 3, 5 and 8.

For example, sumFibs(10) should return 10 because all odd Fibonacci numbers less than or equal to 10 are 1, 1, 3, and 5.

FreeCodeCamp – Sum all Odd Fibonacci Numbers

Looking back at my notes from this challenge I have only written the following sentences:

I’m finally beginning to understand the:

.map, .filter and .reduce

methods! Amazing. Great posts about them here.

Me!

Haha – something must have clicked whilst I was working out the code for this challenge. Let’s have a look.

The first thing that leaps out is that I’ve gone functional! I’ve written a function to find out the Fibonacci sequence up to a number – which is obviously helpful because the object of the challenge is sum all of the odd numbers less than or equal to the given number, from the sequence. Initially we need to know all of the numbers in the sequence up to the given number and then we can filter out the odd ones and return the sum of them.

The fib function I have written might not stand up with the best around but it’ll do for this…

  • Declare an array, and pre-populate it with the first two values of the fib sequence: [1, 1]
  • Begin a for loop – which starts at 2, and goes up to the given number (it must include the given number)
  • And add onto the array the preceding two elements of the array added together – arr.push(arr[j - 1] + arr[j - 2]); where j is the incremental loop value which began at 2.
  • That’s it.

Now to get into the second function which takes care of the deliverable we need for the challenge.

So although there are a few lines of code, thanks to the .filter, and .reduce methods, this could be written in one line. It’s return statement which does all the work by stringing together:

  1. A function call – to fib() which is explained above. This is to get the full sequence of Fibonacci numbers, which will include both odd and even numbers.
  2. The .filter() method – this uses a function to filter out the even numbers, and so only returns the odd numbers.
  3. The .reduce() method – this takes the odd numbers returned from step 2, and reduces them into one final return value. It does this by adding them together.

Let’s look at number 2 and 3 a little bit closer (as we already did with number 1 above).

2 – the .filter() method looks at every value in the given array, and checks it via a function. If the result of running the value through the function is true it will return the value at the end along with any other true values. Any false values it will ‘filter’ out, and they won’t be returned.

3 – the .reduce() method takes a number of values and ‘reduces’ them down to one final value which it returns. To do this it takes a function which it applies to the values. In this case it takes the first value in the array, and adds it to the second – then it takes that value and adds it to the next, and so on, until only one value remains.

My solution:

function sumFibs(num) {
  return fib(num).filter(val => {
    return (val % 2 !== 0) && (val <= num);
  }).reduce((x, y) => {
    return x + y;
  });

  function fib(i) {
    let arr = [1, 1];
    for (let j = 2; j < i + 1; j++) {
      arr.push(arr[j - 1] + arr[j - 2]);
    }
    return arr;
  }
}

sumFibs(10);

Convert HTML Entities

From the FreeCodeCamp intermediate algorithms here:

Convert the characters &<>" (double quote), and ' (apostrophe), in a string to their corresponding HTML entities.

FreeCodeCamp – Convert HTML Elements

For this task there will certainly be other ways to complete it. However although the code may look slightly long, it did not take a long time to write out. The logic is quite simple.

I began by splitting the given string into an array, and then looped through the characters. I also declared a new return array which I would be adding specific items into depending on the following checks.

Then, for each item in the array, I checked if they were one of the characters we are looking for. If they were I would add the corresponding HTML entity onto the return array. And if they were not one of the characters I would add the character, as it was, on to the return array.

The given string is ‘Dolce & Gabbana’.

The for loop would check ‘D’ first and decide it’s not one of the characters we are looking for and so would add ‘D’ onto the return array. It would then check ‘o’ and do the same, and so on. Until it reached ‘&’, where it would be flagged by one of the if statements and instead of adding ‘&’ to the return array it would add ‘&amp;’ to it. Then once it had reached the end, the function can return the array but with a .join('') method attached which will transform it into a string instead of an array.

My solution:

function convertHTML(str) {
  // &colon;&rpar;
  let array = str.split('');
  let returnArray = [];
  for (let i = 0; i < array.length; i++) {
    if (array[i] === '&') {
      returnArray.push('&');
    } else if (array[i] === '<') {
      returnArray.push('<');
    } else if (array[i] === '>') {
      returnArray.push('>');
    } else if (array[i] === '"') {
      returnArray.push('"');
    } else if (array[i] === '\'') {
      returnArray.push(''');
    } else {
      returnArray.push(array[i]);
    }
  }
  return returnArray.join('');
}

convertHTML("Dolce & Gabbana");

I would be interested to see other methods to do this – I think you could also use a switch statement which might be more concise (but not by too much). I also think it would be possible to use the .map() method with a function that maps the specific characters to their new HTML counterparts – I imagine this will be even more concise, but arguably would be less readable (perhaps especially so to those newer to coding / js).

Design a site like this with WordPress.com
Get started