Coding Journal

Jordan Vidrine

Daily Coding Journal

A Self-taught coder from the Cajun Prairie in rural Louisiana, currently working as a designer for Discourse.

I am always trying to better myself, and do so through learning new skills, trying out new routines, traveling, and pouring energy into hobbies. Since 2014, I have been recording, editing, and producing my own music under the name Skies Speak.

October 18th

Getting back to coding after some much needed time off! Last week I was able to go to a job fair in Lafayette, LA hosted by Perficient, which turned out to be awesome. I was able to meet a couple of developers there and am now really interested in the possibility of working there. They seem like a great company that treats their employees very well.

Anyway, back to coding!

Javascript Algorithms and Data Structures

Last week we were looking at problem solving methods to implement when trying to solve an issue (usually in a coding interview.) The step we left off on was Simplify. When encountering a tough problem, it’s smart to simplify that problem into different parts. Tackle the parts you know you can solve, and come back to the more difficult aspects of the problem once you have some solutions under your belt.

It’s also important to write out your solution in pseudo-code, making sure to talk through the problem out loud with the interviewer. Even on your own, it will help you solve the problem, and help your conmprehension of the issue.

Look Back & Refactor

You can get by with something that just works, BUT it is important to strive for simplicity and improvement. Once you have a solution, its good to go back and look at what could be better about your code.

Some questions to keep in mind

  1. Can you check the result?
  2. Can you derive the result differently?
  3. Can you understand it at a glance?
  4. Can you improve the performance of the solution?
  5. How have other people solved this problem?

The following code is a basic example of what refactoring a solution COULD look like.

// write a function that counts the lowercased alphanumeric characters of a string
// and returns an object with the count of each character

function charCount(str) {
  var obj = {};
  for (let i = 0; i < str.length; i++ ) {
    let char = str[i].toLowerCase()
    if (/[a-z0-9]/.test(char)) {
      if (obj[char] > 0) {
        obj[char]++
      } else {
        obj[char] = 1;
      }
    }
  }
  return obj;
}

// Refactored version
function charCountRefactor(str) {
  let obj = {};
  // easier to read syntax, no need to create i variable
  for (var char of str) {
    // separate this into a new function, more performant than regex
    if (isAlphaNumeric(char)) {
      if (obj[char] > 0) {
        char = char.toLowerCase()
        // if obj[char] is falsey, it equals 1, if not, increment it
        obj[char] = ++obj[char] || 1;
      }
    }
  }
  return obj;
}

function isAlphaNumeric(char){
  var code = char.charCodeAt(0);
  if (!(code > 47 && code < 85) && // numeric (0-9)
      !(code > 64 && code < 91) && // Upper alpha (A-Z)
      !(code > 96 && code < 123)) { // Lower alpha (a-z)
        return false;
      }
      return true;
}

Problem Solving Patterns

There are many common problem solving patters out there. A handful of them are Frequency Counter, Mulptiple Pointers, Sliding Window, Divide and Conquer, Dynamic Programming, Greedy Algorithms, Backtracking + more.

Right now we are going to look at Frequency Counter.

This pattern uses objects or sets to collect values/frequencies of values. (Like the example code earlier to count the frequency of certain characters) This can often avoid the need for nested loops or O(n2) operations with arrays/strings.

Heres an example of two solutions to a problem, one being a regular solution, and one being an implementation of the frequency counter pattern.

Write a function called same which accepts two arrays. The function should return true if every value in the first array has it’s corresponding value squared in the second array. The frequency of values must be the same.

same([1,2,3],[4,1,9]) // true
same([1,2,3],[1,9]) // false
same([1,2,1],[4,4,1]) // false (must have same frequency)

// My solution before we move on

function same(arr1,arr2){
    // loop over the first array
    // for each item in the array, check to see if arr2 has the item's squared value in that array
    // if the squared value exists in arr2, remove that value
    // when the loop is complete, if arr2.lengh !== 0, then return false because it didnt completely match the frequency of squared values as needed
    // how can I check that the frequency of values matches the frequency of the squared values

    let freq = true;
    for (let i = 0; i < arr1.length && freq == true ; i++) {
        let idx = arr2.indexOf(arr1[i]*arr1[i])
        if (idx !== -1) {
            arr2.splice(idx,1)
        } else {
            freq = false;
        }
    }
    return freq;
}

// My solution refactor

function same(arr1,arr2){
  for (let i = 0; i < arr1.length; i++) {
      let idx = arr2.indexOf(arr1[i]*arr1[i])
      if (idx !== -1) {
          arr2.splice(idx,1)
      } else {
          return false;
      }
  }
  return true;
}
}

Just a short day today. That’s it for now!

Back to blog...