Back to basics

After building out application after application over the last few months, I, personally, have forgotten a lot of the tricks and trade that I had learned when starting out coding. For example the methods that used to be so engrained in my head I no longer used on a day to day basis. But with so many online resources, documentation AND my own notes I am able to give myself a refresher.

But just reading documentations and notes is not enough but thankfully there are a lot of websites out there that one can sign up and practice with plenty of coding challenges and/or tutorials. Below is a list of just a few of these types of resources:
- https://www.hackerrank.com
- https://leetcode.com/
- https://www.codewars.com
- https://www.codecademy.com

I will practice with some problems below and show some of the solutions that I came up with and explain my thought process,


Practice #1

The function #accum takes in a string and outputs the following:

accum("abcd")    # "A-Bb-Ccc-Dddd" 
accum("RqaEzty") # "R-Qq-Aaa-Eeee-Zzzzz-Tttttt-Yyyyyyy" accum("cwAt") # "C-Ww-Aaa-Tttt"

Solution #1 w/Ruby

def accum(s)     
  new_string = ""  

s.each_char.with_index do |char, idx|
segment = (char * (idx + 1)).capitalize

if idx == s.length - 1
new_string << "#{segment}"
else
new_string << "#{segment}-"
end
end

new_string
end

Step-by-step:
- Declare new_string to store the answer and output later. It will be of String type
- #each_char splits the string up into separate characters. #with_index is a chain-able method that provides us with the index of each element. Using both methods I can pass in char (each character) and idx (index of character).
- I declare a variable segment and set it equal a string created by multiplying the character (idx + 1) times. The #capitalize method will only capitalize the first letter and make all others lowercase.
- The conditional comes in to decide whether or not to add a dash (“-”) to the particular segment or not AND to push it into the new_string variable. If the index is the last element of the inputted string then that means I do not need to add a dash. Otherwise I will have to append a dash to the segment.
- Return the new_string

Solution #2 w/Ruby

def accum(s)
 answer = []
  s.split("").each_with_index do |letter, index|
segment = letter.upcase
index.times { segment << letter.downcase }
answer << segment
end
  answer.join("-")
end

Step-by-step:
- Declare answer to store the results and output later. It will be stored as an array.
- Using #split will divide the string into an array of separate characters. Since s is now an array I can utilize the #each_with_index method to iterate through each character and index, I can pass letter and index, respectively.
- Through each iteration I set up a segment variable that will be initialized with the letter passed in #uppercase. Segment is going to be a string.
- Then using the index I can use the #times iterator to push the letter #downcase-d into the segment string. With Ruby I can concatenate strings by using the #push (<<) method. 
- After the segment is finalized I can now push the segment into the answer. This keeps running until I reach the end of the original string.
- I finally return the answer variable joined with a dash.

Solution #3 w/JavaScript

function accum(s) {
var answer = []
  s.split("").forEach( (letter, idx) => {
    var segment = ""
segment += letter.toUpperCase()
    while (idx > 0 ){
segment += letter.toLowerCase()
idx -= 1
}
    answer.push(segment)
})
 return answer.join("-")
}

Step-by-step (similar to solution #2):
- Declare variable answer to store the results and output later. It will be stored as an array.
- Similar to Ruby, JavaScript has a #split function that works on strings to split up the characters. Then I want to iterate through each character using the #forEach function. I can pass in the letter and the index, letter and idx respectively.
- Every loop I declare a segment variable to store the string
- The first character to concatenate into segment is the letter capitalized, using toUpperCase(). Unlike Ruby, I cannot push substrings into strings so I need to concatenate using +=.
- Then I have an iterator, if idx is greater than zero I will concatenate the letter into segment idx-times.
- Once the loop is done, if it is done at all, I use push() to push the segment into the answer array.
- With JavaScript I need to explicitly use the return keyword to give the answer, joined with dashes.


Practice #2

The goal of this exercise is to convert a string to a new string where each character in the new string is ‘(‘ if that character appears only once in the original string, or ‘)’ if that character appears more than once in the original string. Ignore capitalization when determining if a character is a duplicate.
"din" # "((("
"recede" # "()()()"
"Success" # ")())())"
"(( @" # "))(("

Solution #1 w/Ruby

def duplicate_encode(word)
  answer = ""
count = Hash.new(0)
word.each_char { |letter| count[letter.downcase] += 1}
  word.each_char { |letter| count[letter.downcase] == 1 ? answer <<   
"(" : answer << ")" }
  answer
end

Step-by-step:
- Declare an answer to store the results and output later. 
- Declare a hash count and default the values with zero. This will store the number of times a character appears in the word.
- First iteration will go through each letter of the word, #downcase it, set it as a key in the count hash and add one to the number of times it appeared.
- Second iteration will go through the word again. This time it will #downcase the letter and check in the count hash how many times it appeared. If it appeared once then I will push “(“ into the answer string, otherwise it will push “)”. I use a single line if-else statement since there is only one action needed.
- In the end I implicitly return the answer string.

Solution #2 w/Ruby

def duplicate_encode(word)
word.each_char.map { |letter|
word.downcase.count(letter.downcase) == 1 ? "(" :
")"
}.join
end

Step-by-step:
- This is all written as one line
- To eliminate the need for storing an answer I can use the #map method to return a new array. I split up the word by character and map through it passing in a letter.
- With each letter I will use the #count method to see how many times it appears in the word. Since it should be case-insensitive I need to #downcase the whole word before using #count
- Then I need to also #downcase the letter that was passed in. If it appears once then I will produce “(“ in the new array from #map, otherwise I will produce “)” in the new array.
- In the end I will #join the newly mapped array

Solution #3 w/JavaScript

function duplicateEncode(word){
  var count = new Object
  for (i = 0; i < word.length; i++ ){
var letter = word[i].toLowerCase()
if (count[letter]){
count[letter]++
} else {
count[letter] = 1
}
}
  return word.split("").map( (char) => {
if (count[char.toLowerCase()] === 1){
return "("
} else {
return ")"
}
}).join("")
}

Step-by-step (similar to solution #1):
- Declare a count variable that is an Object
- Go through the whole word once using the for-loop.
- For each character at the i-th index toLowerCase() it and set it as the variable letter.
- If the count object has the letter as the key then I will increment it by one, otherwise set a key of letter in count and set the value to one.
- Javascript contains a map() function and I will have to explicitly return the results.
- For each char, if the count[char] is equal to one then I will return into this newly mapped array a “(“, otherwise a “)”. 
- In the end I need to join() the mapped array with “”.

Like what you read? Give Kevin Wang a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.