AppAcademy.io Practice Problem Notes

As I work my way though the AppAcademy.io practice problems, I’m going to keep notes here.

I’m almost certain that there will be mistakes and inaccuracies with these notes.

Please keep in mind that these are notes.

I make them public in the hopes that my insights may provide some value to someone in a similar position to me right now.

Jump to problems notes:

0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20

Notes and Understandings From Individual Problems:

Upon opening the file and beginning the lessons, I’m pretty sure that the gist of this is going to be the same that I document in the notes on the introduction.

There will be a lot of learning code and then repeating it under different circumstances, again and again, until it’s committed to functional memory.

00-reverse.rb

This test is all about taking a string and spelling it backwards.

Sure, you could use < “string”.reverse > and be done with it:

easy reverse string

This doesn’t really help because we develop our skills by finding interesting arrays of ways to do the same thing. Quick note, this was the first time I typed a method into the practice problems and received all true responses without a single drop of input from the outside world. It was cheating… but it is a start. 😀

OK – So as I began this process, I hit a road block. I started thinking outside the box and writing code that may have solved the problem. When I ran that creative code, I got nothing but errors. Not helpful errors which explained where the problem in the code was, but errors that just say vague stuff like this:

Screen Shot 2015-12-15 at 10.31.56 PM

So this means that it’s just not working. I spent a few minutes trying to debug but I got the same errors. With my discouragement, I went to facebook and checked my email. Essentially, I stopped progressing.

How I’ll proceed through the practice problems:

So from now on, I’m just going to remember the solutions to the practice problems.

I’m going to copy the solutions symbol for symbol. Then I’ll run them to ensure I got it right, then delete it all and try to write it from memory. I’ll keep doing this until I can write it three times without making an error. It’ll be a slog.

There are 20 practice problems so I expect this exercise to take about a week or so to complete.

I don’t know exactly how I’ll document it… but I’ll keep notes and thoughts on this page.

Updated Dec 15th, 2015

Practice Problems

The way I’m doing these practice problems is just like I illustrated in the Ruby notes in previous note sheets. First I read the problem and give it as good a shot as I can. Generally, I fail miserably. Not a problem though. I’ll dig into the solutions and doctor up my code until it works. I try to make mental notes and connections as to why each element is needed and why each piece is where it is.

Then I will try again to write the code by memory/intuition. This helps me test my learning pace and it keeps me moving. The worst thing I’ve noticed is when I hit a roadblock and stop working.

I’ve been having a lot of fun with the practice problems. The first three were great for learning… but not so mentionable here because they are so self evident. This one is worth mentioning because the solution is so elegant. Here’s the problem:

Write a method that takes in an integer `num` and returns the sum of all integers between zero and num, up to and including `num`.
Essentially we’re writing a program that does this:
if x = 5

5 + 4 + 3 + 2 + 1 = 15

x needs to be interchangeable.

At first I put a lot of effort into working out the code for (num – 1) + (num – 2) + (num – 3)…. but it wasn’t working well because it’s hard to write the index code necessary to add all the elements without knowing how big the numbers would get. Also, we want the computer to answer the questions if we ask for the answer if the number is 1,000,000 and that becomes a challenge in terms of code size.

The answer is quite elegant though… and I can tell in describing the beauty of this, that I’m turing into a geeky coder. Here’s the answer:

def sum_nums(num)
  result = 0
  i = 0
    while i <= num
      result += i
      puts(i)
      i += 1
    end

  return result
end

January 5, 2015

Note: I just now learned how to save the indentation data via WordPress. Unfortunately, I’m writing this long after I learned about the <pre> code. I’ve don’t all but one of the problems in this a/A problem set so I probably won’t go through and fix all of the problems, but going forward, I’ll post it right. Back to the learning:

So the code works up

0
0 + 1
0 + 1 + 2
0 + 1 + 2 + 3

until it reaches the requested number limit

etc….

cool stuff. Here’s how it looks with the code open and if I slip a puts for the i value in there to see how the computer runs the code:

sum nums

Updated Dec 16, 2015

01-factorial.rb

Write a method that multiplies a number by all the numbers before it.

Example: 7 would be 7 * 6 * 5 * 4 * 3 * 2 * 1

On a calculator it looks like this 7!

One way to do this is to take the number, and create another number by subtracting one from that number. Then multiply the numbers like that over and over again until you’re at zero.

That program looks like this:

def factorial(n)
result = 1
while n > 0
result = result * n
n = n - 1
end
return result
end

Another way to do it is to multiply 1 * 2 * 3 * 4…. up until you hit the number… but I don’t know how to do that right now.

But does Ruby offer a *= to add via multiplication?

I ran this program as a test:

num = 3
print(num *= num)

It printed 9 so it seems to work.

So I wrote this program as a method for defining

def factorial(n)
start_num = 1
result = 1
while start_num < n
result = result * start_num
start_num = start_num + 1
result *= result
end
return result
end

Which printed:

1
1
1
4
144
factorial(0) == 1: true
factorial(1) == 1: true
factorial(2) == 2: false
factorial(3) == 6: false
factorial(4) == 24: false
1 – 1 – 4 – 144

So, this is confusing and I’ve lost focus. I feel like the above answer is valid… and I’m confident there is a way to do this, but I’ve been thinking about this too much and I don’t feel like I’m making lots of progress so I’m going to move on.

Update: I figured it out. Here’s how to get factorial of a number by working up (eg. 1 * 2 * 3 * 4….):
def factorial(num)
idx = 1
result = 1
while num > idx - 1
result *= idx
idx += 1
end
return result
end

Working down:
def factorial(n)
result = 1
while n > 0
result = result * n
n = n - 1
end
return result
end

Differences Between working up and working down:

Counting from 0 up towards the sum or the factorial requires an extra variable to do the counting. This makes it more complex.

Counting back from the selected number is more elegant of a solution, though the degradation of the original variable could be an issue in more complex programs.

02-longest-word.rb

This problem is easier because it doesn’t involve lots of counting or math. We just write a program that moves through a string comparing each word by word length and saving the longest word. Then we print the longest word.
def longest_word(sentence)
idx = 0
longest_word = "Huzzah!"
words = sentence.split(" ")
while words.length > idx
current_word = words[idx]
if longest_word == "Huzzah!"
longest_word = current_word
elsif current_word.length > longest_word.length
longest_word = current_word
end
idx += 1
end
return longest_word
end

This one seems fairly straight forward to me. The learning aspect was in seeing how to do this in an iterative way. While writing the code, we first break down the sentence into words. Then we write a process that will execute for the number of words in the sentence. With each execution, the program selects the current word and compares it with the longest word. The longest word is replaced by the current word when the current word has more letters than the word that was previously assumed to be the longest word. This keeps going until we reach the number of words in the sentence. The program finally returns the longest word and we’ve got a cool program.

03-sum-nums.rb

This one was a bit of a challenge due to it’s similarity to problem 01-factorials.rb. While learning it, I would mix the notation behind these two methodologies because they are similar in their iterative way of seeking solutions.

The sum of the numbers leading up to 4 is 4 + 3 + 2 + 1 = 10
The factorial of the numbers leading up to 4 is 4 * 3 * 2 * 1 = 24

So they are similar, but the way we do it is much different.

Here’s how to get the sum nums:
def sum_nums(num)
result = 0
idx = 0
while idx < num
result += num
num -= 1
end
return result
end

This is how to do it by working from the high number down. So for num = 4 the program adds 4 + 3 + 2 + 1

Alternatively, we could use the same system we learned in factorials and work our way up

def sum_nums(num)
sum = 0
idx = 0
while idx <= num
sum += idx
idx += 1
end
return sum
end

04-time-conversion.rb

This was a problem I was able to solve in a separate ways from what the solutions read without the support. The thing that threw me off was converting the integer feedback to a string. Specifically, listing the seconds when less than ten. I didn’t think to add the string in as zero with the if/else statement. It’s obvious now, but at the time I didn’t think of it.

I used modulo to get a true reading via the code below.

def time_conversion(minutes)
hours = minutes / 60
minutes = minutes % 60
hours_disp = hours.to_s
if minutes < 10
min_disp = "0" + minutes.to_s
else
min_disp = minutes.to_s
end
return hours_disp + ":" + min_dip
end

My own above solution is different from the solution that is provided by a/A. They used a different attack method in which they subtract out minutes and add up the hours based on how many loops can be run through the number of minutes provided.
def time_conversion(minutes)
hours = 0
while minutes >= 60
hours += 1
minutes -=60
end
if minutes < 10 disp_minutes = "0" + minutes.to_s else minutes >= 10
disp_minutes = minutes.to_s
end
return hours.to_s + ":" + disp_minutes
end

I don’t know which system is better. In fact I think they both work well. Perhaps my system would be faster because the code only runs through 2 mathematical processes before converting to strings and feeding the correct answer. It will run the same number of processes in any situation… The code above will have to work harder and harder the larger the minutes.

I’m unsure of the exact science behind all this… but playing these guessing games helps me to cement the code and the syntax into my functional memory.

05-count-vowels.rb

I did this one wrong a bunch of times. My initial reaction was to try to do it with an array that had all the vowel strings inside, but I couldn’t make it work at the time of writing this (I’m confident it’s possible, I just don’t have the proper syntax yet.)

Anyways, I can’t remember the first way I solved the problem. I’ve since committed this way of doing it to memory so I write it up like this now:

def count_vowels(string)
vowel_count = 0
idx = 0
while idx < string.length
if string[idx] == "a" || string[idx] == "e" || string[idx] == "i" || string[idx] == "o" || string[idx] == "u"
vowel_count += 1
end
idx += 1
end
return vowel_count
end

What’s this doing? Essentially, it’s just moving through the string 1 position at a time asking, is this a vowel. When it is, the vowel count goes up one. When it isn’t, the vowel count doesn’t change and we move onto the next position in the string. Easy peasy.

 

06-palindrome.rb

A palindrome is a word which is spelled the same forwards as it is backwards. “Hello” is not a palindrome, “hellolleh” is a palindrome. Got it?

So how do we write a program that can tell us if a string is a palindrome? Well, if the string is the same in reverse as it is forwards, then we have a palindrome.

Here’s how to write that program:
def palindrome?(string)
reverse_string = string.reverse
if reverse_string == string
return true
end
return false
end

This isn’t the way that the solutions from a/A describe how to do this test.

The solution given in the material does it by writing a looping program which runs through each position of the string forward and backwards comparing them.

Here’s an example. For the string “hello” the program takes the first and last letter of the word and asks if they are the same. Is “h” and “o” the same? because they aren’t, the program returns false. For the string “hellolleh” the program would ask if the first and last string are the same. Because they are both “h”, the program continues on to the second position and the second to last position. Because they are both “e”, the program keeps going until the position work all the way to compare the 9th to last and the 9th position. Once we get to the end of the string, the program doesn’t negate the question and the loop ends. Then, because we can’t prove it’s not false, we return true. Here’s how the program works:
def palindrome?(string)
idx = 0
while string.length > idx
if string[idx] != string[(string.length - 1) - idx]
return false
end
idx += 1
end
return true
end

So which of these programs is more efficient? I think it’s obvious that my first impression is the faster, more elegant program. However the skill of comparing string positions in an iterative way is helpful as a learning process.

Also, the (string.length-1) – idx is a bit of code that could be used a lot in the future when you want to work from the end of an array towards the beginning. This could be used to spell something backwards too.

Note: This could be another solution to the 00-reverse.rb program we did first.
def reverse(string)
reverse_string = ""
idx = 0
while idx < string.length
reverse_string += string[(string.length - 1) - idx]
idx += 1
end
return reverse_string
end

This is a cool example of why it’s valuable to learn to do things inefficiently at the beginning. We’re not actually trying to solve these problems as much as we’re trying to develop the critical thinking tools to create new things with existing tools. Counting backwards using this string[(string.length-1) – idx] in a while loop will be useful for the life of a programmer I would guess.

Of course, we could even write another way to do this problem based upon the lessons learned in 00.reverse.rb. The code we used for that could be implemented here to solve the problem too:
def palindrome?(string)
rev_string = ""
idx = 0
while string.length > idx
rev_string += string[(string.length - 1) - idx]
idx += 1
end
if rev_string == string
return true
end
return false
end

In the above example, we’re writing the string backwards and then comparing the reverse to the original. If they are the same, we have a palindrome, if not we don’t. This is the same as my initial solution, but it’s in a longer, more complex program.

 

December 31st, 2015

I’m just running through the problems now, doing them all quickly and in 2-3 different methods of getting the same answers. I noticed the following lesson:
def palindrome?(string)
if string == string.reverse
return true
else
return false
end
end

The above code does NOT work. Why? Because I’m trying to execute a method in a conditional statement. These need to be separated by declaring new variables. Here’s the code for how to do it so it works:

def palindrome?(string)
rev_string = string.reverse
if string == rev_string
return true
else
return false
end
end

This is just a quick lesson that I think will prove endlessly valuable in the future.

 

07-most-letters.rb

In this one we’re given a string and asked to return true if there is an “a” within in the string a “z” within 3 positions of that a.

Here’s the program/method that my brain defaults to when I just write it from scratch:
def nearby_az(string)
idx = 0
while idx < string.length
if string[idx] == "a" && string[idx + 1] == "z" || string[idx + 2] == "z" || string[idx + 3] == "z"
return true
end
idx += 1
end
return false
end

It prints true so it’s a good solution. But after comparing this program to the solution provided, mine is quite different.

Mine just moves through the positions of the string one by one asking if the letter is “a” and it the next three positions are “z”. This works great… but the solution they provide has lessons in thought process that I think will be important to a computer programmer, so I’m going to write them out and define how they work.
def nearby_az(string)
idx1 = 0
while idx1 < string.length
if string[idx1] != "a"
idx1 += 1
next
end
idx2 = idx1 + 1
while (idx2 < string.length) && (idx2 <= idx1 + 3)
if string[idx2] == "z"
return true
end
idx2 += 1
end
idx1 += 1
end
return false
end

This program is different in a few ways:

  • It separates loops in seeking string[idx] == “a” and string[idx] == “z”.
  • Next syntax: If string[idx] != “a” then jump out of the loop and move on. This skips looking for “z” when string[idx] != “a”
  • while (idx2 < string.length) && (idx2 <= idx1 + 3) – > This is a cleaner way of asking the follow up questions. If the string doesn’t go any longer, it’s smarter to not ask if that blank space is “z”.
  • Another note is that we need to list idx += 1 twice in this method because the next breaks us out. If we don’t do it outside of the next sub-loop, then we get an infinite loop.
  • idx2 then loops through the next 3 letters to check to see if they are “z”

This is the kind of problem I have a hard time with because I just barely understand why each part does what. For that reason, I make mistakes when writing the program from memory. Why is this >= rather than just >. When we don’t know the answers to questions like this, writing the program becomes more a function of memory, rather than cause and effect understanding. These two ways of writing are critically different. Memory creates boxes, understanding cause and effect creates tools to do anything.

I’m really close with this problem. I can write it both ways right now, but I still make errors with the second way. I’ll have to come back to it in a little bit.

I’m not sure if I know this, or if I’ve just remembered it now.

Will come back another day and write the code again.

Updated December 27th 2015

08-two-sum.rb

Ok – Here we go on two sums.

This one is immediately challenging because I don’t know how to return arrays off the top of my head right now.

def two_sum(nums)
i1 = 0
while i1 < nums.length
i2 = i1 + 1
while i2 < nums.length
if nums[i1] + nums[i2] == 0
return [i1, i2]
end
i2 += 1
end
i1 += 1
end
return nil
end

I almost was able to write this without the help. My thinking process was the same as described in the solution set, but my ability to code it wasn’t there because I didn’t call to memory the return array segment notation.

The thinking behind this is that we start with a while loop which contains another loop. The first loop starts off saying “are we at the end of the string.” If no, then the second loop kicks in asking “is the first value plus the second value equal to zero?” If the answer is yes we print the answer. If it’s no, we move on to asking if the first value plus the third value is equal to zero. We keep this up until there the question hits the end, then we move the first value.

It’s very similar to the last problem in which we moved across the string. The string was essentially treated as an array.

It think this one is straight forward and it builds on the lessons learned from the last problem.

Again, I can write this code really well and I understand it… but I’m not sure at this moment if I’ve just remembered to the code, or if I have fictional grasp over the lesson.

09-is-power-of-two.rb

I’m quite proud of myself today. I’m finally seeing these problems as interesting puzzles to solve with tools I have. That’s a big improvement over how I felt about this all a week ago. A week ago, I was screwing up on syntax and didn’t even know how to approach these problems. I actually created an answer for this problem without seeking any assistance from outside the question it’s self.

First I’ll provide the answer I developed myself, then I’ll work to understand the solution which was provided and then I’ll summarize both the solutions. First, my code:
def is_power_of_two?(num)
if num == 0
return false
end
idx = 1
while num >= idx
if idx ** 2 == num
return true
end
idx += 1
end
return false
end

Ok, now I’m going to dissect the solution provided:

def is_power_of_two?(num)
if num <= 0
return false
end
while true
if num == 1
return true
elsif num % 2 == 0
num = num / 2
else
return false
end
end
end

This is fascinating. Though both answers work well, mine is really wasteful. Let me explain:

With my response, we ask a million questions.

The Million Dumb Questions Approach:

Him: “Is 78 a power of two?”
Her: “Is 1 ** 2 equal to 78?”
Him: “No. It’s 2.”
Her: “Ok… how about 2 ** 2?”
Him: “Nope, that’s 4”

(2 hours and 76 attempts later.)

Her: “Ok… how about 77 ** 2?”
Him: “HELLL NO! That’s 5,929!”
Her: “Ok… how about 78 ** 2?”
Him: “You’re driving me crazy! That’s 6,084!”
Her: “Great, I can tell you that 78 is not a multiple of 2”

This is a dumb way to do it.
There are a lot of different ways to solve this problem more efficiently listed here on Wikipedia.

December 31st, 2015

Update: Because I still this approach for it’s simplicity in process rather than rigor in math, I found a way to do it better. The idea is that once the results of squaring ‘idx’ become greater than num, it makes no sense to keep it going. So we write a conditional statement that stops asking if idx ** 2 becomes greater than n.

def is_power_of_two?(num)
if num < 1
return false
end
idx = 0
while idx <= num if (idx) ** 2 == num return true elsif (idx) ** 2 > num
return false
end
idx += 1
end
return false
end

The way the solutions says is to do this:

Him: “Is 78 a power of 2?”
Her: “Well, 78 divided by 2 is 39. And 39 divided by 2 is 19.5. As soon as we see fractions in this math, we know that the number is not a multiple of 2.”

So this is a powerful lesson. I’m happy that I was able to solve the solution myself without the aid of the solution set. Also, I now have a greater understanding of how using more efficient algorithms can make a big difference in processor demands.

Revised December 28, 2015

Upon revisiting the problem, I didn’t get their version right away. It had to do with my understanding of syntax, but also my understanding of the math of powers of two.

I now understand it even deeper. Here’s what I learned. The key is to take each num provided and repeatedly divide by 2. Do this until you hit 1. If you don’t hit 1 on the dot (meaning you get a fraction near one) then you don’t have a power of 2. That’s the heart of the code provided by a/A. So when thinking about their solution. num/2 to infinity. Keep going until you hit exactly 1. If you hit exactly 1 it’s true, if not, the result will go below 1 and any calculation resulting in < 1 == false.

December 29, 2015

I came back to this problem but couldn’t remember how to write the modulo system of finding if a number is a square. After doing battle for an hour, I could another way to get the right answer. Here it is:

def is_power_of_two?(num)
while num > 1
num = num / 2.0
end
if num == 1
return true
end
if num < 1
return false
end
end

It is cool that I found a new way to do the problem. That said, it’s no cause to celebrate. The reality is I couldn’t remember the syntax of the a/A solution which I committed to memory a few days ago. It’s the “while true” element that threw me off.

I just committed the a/A solution to memory again with a deeper understanding of the problem and the syntax. With luck, it’ll stick this time around.

10-third-greatest.rb

This one is really tough. I don’t know how to order arrays based on the value of the integers… It’s easy to print the 3rd position once the array is in order from longest to shortest… but how do we organize an array of numbers from longest to shortest?

Bubble sort method is the way to do it… I saw it on wikipedia once but don’t know exactly how to do it with ruby syntax.

so if num[idx] > num[idx + 1] then have them switch.

Side note: This one could be solved in the same way that we found the longest value in an array from earlier problems… I’ll revisit that one to see if I can remember the way we did that.

-Back- Yes, from looking back at the 02-longest-word.rb exercise we learn that we can solve this problem the same way that we solved the longest word problem. I actually wrote the code to print out the new arrays in order here:
def longest_word(sentence)
words = sentence.split(" ")
longest_word = nil
inbetween_word = nil
shortest_word = nil
idx = 0
while idx < words.length current_word = words[idx] if longest_word == nil || longest_word.length > current_word.length
shortest_word = inbetween_word
inbetween_word = longest_word
longest_word = current_word
elsif inbetween_word == nil || inbetween_word.length > current_word.length
shortest_word = inbetween_word
inbetween_word = current_word
else shortest_word == nil || shortest_word.length < current_word.length
shortest_word = current_word
end
idx += 1
end
return [longest_word.to_s, inbetween_word.to_s, shortest_word.to_s]
end

Nope, I take that back. What the above method does is organize the words, but this doesn’t work for that array because the array may have less values than 3 in it. The above method does not account for arrays that have less than 3 values and thus can’t provide the right answer.

December 29th, 2015

Update: Yes, I was able to solve the problem using the methodology from the previous problem in which we sought out the longest word. The code that I wrote in the above note is embarrassing. It displays some wacky thinking and I don’t quite understand what I was doing. Anyways, here’s the code that works for this problem, but using the methodology we learned when seeking the longest word.

def third_greatest(nums)
first = nil
second = nil
third = nil
idx = 0
while idx < nums.length current_num = nums[idx] if (first == nil) || (current_num > first)
third = second
second = first
first = current_num
elsif (second == nil) || (current_num > second)
third = second
second = current_num
elsif (third == nil) || (current_num > third)
third = current_num
end
idx += 1
end
return third
end

It’s fun when you check the code in the solution and it’s essentially the same. This is good news, I’m starting to really get this.

11-most-common-letter.rb

I’ve put a LOT of time into understanding this. All day yesterday and much of the day today.

Yesterday, I spent all my time understanding the code. Today I was able to write it all up, but I screwed it up a bit and needed the solution to get the method to work.

def most_common_letter(string)
most_common_letter = nil
most_common_letter_count = nil
idx = 0
while idx < string.length
current_letter = string[idx]
current_letter_count = 0
idx2 = 0
while idx2 < string.length if string[idx2] == current_letter current_letter_count += 1 end idx2 += 1 end if (most_common_letter_count == nil) || (current_letter_count > most_common_letter_count)
most_common_letter = current_letter
most_common_letter_count = current_letter_count
end
idx += 1
end
return [most_common_letter, most_common_letter_count]
end

Essentially for this problem we wrap a loop in another loop. The first loop does two things:

  • Selects the current letter
  • Assigns the results of the second loop if it should

The second loop takes the current letter and asks if each position on the string contains the same letter. When the same letters are there, the second loop counts them.

So this isn’t so hard to understand now, but the syntax can be a challenge to nail.

I’m feeling great about loops now.

December 30, 2014

Today I was able to write out the whole code but I screwed up on the positioning of the initial definition of the count. It turns out, if you put the “count = 0” code in the wrong loop, the count just keeps adding up. It never resets to zero with the new loop. Lesson learned! I got this now.

 

12-dasherize-number.rb

So this one really threw me off. There were two things that threw me off:

  1. Double Hashes between odd number pairs
  2. When odd numbers are at the end of the words

Today I was able to get a grip on how to solve the problem. More importantly, I realized an important lesson. Simply working the problem over and over again wasn’t especially effective. I spent hours coding it backwards and forwards using the tools I had. I never did get it right on my own and I found out later that the method was something I hadn’t ever been exposed to. Therefore, I wasted a lot of time trying to get it to work.

Going forward, if I don’t get the problem intuitively within 15 minutes, I’ll glance at the solution provided by a/A to get the gist of it. That will help me skip the slow, hopeless process of trial and error when my systems won’t work.

Anyways, dehasherize the odd numbers was useful because it showed me a different way to work backwards through an array.

It’s midnight and I’ve got a big day of coding tomorrow so I’m off to bed.

January 4th, 2015

So I was able to write my own way to solve this problem. Essentially the idea is that you run the problem, adding each string one after the other. If either value is odd, the loop fills in a “-“. The problem is at the end. If the last letter is odd, the program wants to add a “-” to the end which leads to us getting false results. So I wrote a quick if statement. If the string ends in a dash, the if statement sets the array to not include the dash. Pretty simple right? Here’s the code.

def dasherize_number(num)
num_string = num.to_s
result = ""
idx1 = 0
while idx1 < (num_string.length)
idx2 = idx1 + 1
result += num_string[idx1]
if (num_string[idx1].to_i % 2 == 1) || (num_string[idx2].to_i % 2 == 1)
result += "-"
end
idx1 += 1
end
if result[-1] == "-"
result = result[0...-1]
end
return result
end

This is not the a/A solution to this problem. Their provided answer is much more elegant and I like it more. With theirs, it just doesn’t run the hash process unless idx is greater than 0. That’s really smart. The cool thing about this is that my solution works fine. It might be a little less elegant than theirs, but I sat and retyped the problem 3 times each with slight variations in both methods. Now I have a solid understanding of this so I can use the ideas in other problems.

What’s next?!

 

13-capitalize-words.rb

I love splitting, manipulating and joining arrays. It makes more sense than anything else. This one is elegant and simple.

14-scramble-string.rb

Something very interesting has happened here. I’m keeping my mouth shut for now, but the code below has the meaning if you look closely. This is my code and I’m certain it’s correct:
def scramble_string(string, positions)
pair_array = [""]
idx = 0
while idx < string.length
paired = positions[idx].to_s + string[idx]
pair_array = pair_array.push(paired)
idx += 1
end
pair_array = pair_array.sort
final_array = []
idx = 0
while idx < pair_array.length
individuals = pair_array[idx]
final_array = final_array.push(individuals[1])
idx += 1
end
final_array = final_array.join("")
return final_array
end

15-is-prime.rb

This has to be one of the more interesting problems because of the distraction the answer led me to. Let me explain:

All computer programming is iterative (at least so far for me). That means everything is done in a step by step way. Do this, then this.

In order to find prime numbers using a computer program, we seek numbers that are divisible nothing other than themselves and 1.

The first person credited with identifying this process was known as Eratosthenes. His Sieve of Eratosthenes is still the key to identifying prime numbers by iterative negation. That means, we identify a number that we want to know is prime, then we count up using negation. 4 is not prime because it’s divisible by 2

Example:

Is 21 a prime number? 

Is 21 divisible by 2? | 21/2 = 10.5 | No

Is 21 divisible by 3? |  21/3 = 7 | Yes

Then the answer is, no. 21 is not a prime number

Alternatively, is 11 a prime number?

Is 11 divisible by 2? | 11/2 = 5.5 | No

Is 11 divisible by 3? |  11/3 = 3.66 | No

(Continue this on)

Is 11 divisible by 9? | 11/9 = 1.22  | No

Is 11 divisible by 10? |  11/10 = 1.1 | No

Then the answer is, yes. 11 is a a prime number because if we divide all the numbers [1-10] that lead up to 11, we get fractions.

Note: Eratosthenes is also a fascinating character. I’d love to do more research into his life. Wikipedia says he was one of the fist to measure the axis of the earth relative to the sun and provide surprisingly accurate estimates for the size of the sun and the earth. Sorry US History books, not everyone pre-Columbus thought the world was flat.

The solution to this problem is a mathematical exact. I think we could use arrays and more complex ways of writing a program to solve this problem, but this one seems quite elegant to me:
def is_prime?(number)
idx = 2
while number > idx
if number % idx == 0
return false
end
idx += 1
end
return true
end

Essentially this program says, count up dividing your count by the number and asking if the result is a fraction. Start at 2 and keep going until you hit the number. If you find a result without a fraction, it’s not prime. If you do, do this.

Updated December 23th, 2015

16-nth-prime.rb

– To Be Added

17-longest-palindrome.rb

Updated January 7th, 2015

This one is fun and quite easy because we learned both processes earlier. We know how to get true/false of a palindrome and we know how to work through a string to get the longest words. This is just putting the two together. The important lesson s is that we create two methods to solve this problem. In method 2 we use method 1 within the code.

In my method, I threw in a puts order to get a cool vision readout of how the computer iterates through the string (see blow highlighted in yellow):

strings and palindromes - app academy study

18-greatest-common-factor.rb

Feeling quite accomplished after figuring out the answer to this problem all on my own. Here’s my code. After I save my code here, I’ll look to see the solution provided by a/A. They are generally have far more elegant than me, but I’m still happy to get a win. Here’s my code:

def create_factor_arr(n)
  factors = []

  idx = 1
    while idx <= n
      if n % idx == 0
        factors = factors.push(idx)
      end

      idx += 1
    end

  return factors
end

def greatest_common_factor(number1, number2)
  n1_factors = create_factor_arr(number1)
  n2_factors = create_factor_arr(number2)
  greatest_common_factor = nil
  
  idx = 0
    while idx < n1_factors.length
      factor1 = n1_factors[idx]

      idx2 = 0
      while idx2 < n2_factors.length factor2 = n2_factors[idx2] if factor1 == factor2 current_factor =              factor1
          if (greatest_common_factor == nil) || (current_factor > greatest_common_factor)
            greatest_common_factor = factor1
          end
        end

      idx2 += 1
    end

    idx += 1
  end

  return greatest_common_factor
end

Now I’ll dive into their code.

Ugh. Yes, their solution is clearly an example of more efficient thinking.

Essentially it works like this => Which number is lower. Set idx integer to that number. Count down from there asking constantly if the idx is a factor of the other number. Yes, that is far easier. I’ve put the solution away and will now try to write it from memory.

After reading a/A solution I was able to write a similar code from scratch which was far less complex than my original code. Anyways, I didn’t get it quite as elegant as the solution, but this solution works too:

def greatest_common_factor(n1, n2)
  greatest_common_factor = 1
  i = 0
  if n1 < n2 i = n1 elsif i = n2 end while i > 0
    if (n1 % i == 0) && (n2 % i == 0)
      current_factor = i
      if greatest_common_factor < current_factor
        greatest_common_factor = current_factor
      end
    end
    i -= 1
  end

  return greatest_common_factor
end

The solution code was 17 lines. My first version was 29 lines of code. My second version had 24 lines of code. I’m getting better, but it’s still not so good. Now I’ll re-examine their solution and try to get it even tighter.

I set idx to the lower number and then just iterated down to zero. That’s an inefficient way to do it because the first number it finds is going to be the greatest common factor. In my version, comparative variables were critical to ensure lower factors wouldn’t override the greatest common factor. But of course, the greatest common factor is going to be the first one we find. This time, I’ll set the loop to end on the first variable it finds in common between the two. I hope I can figure it out by memory. Here goes:

This time I wrote it out perfectly like they did. The lesson I learned here is, Go straight for the number you’re hunting and return it immediately.

def greatest_common_factor(n1, n2)
  i = nil
  if n1 <= n2
    i = n1
  else
    i = n2
  end

  while true
    if (n1 % i == 0) && (n2 % i == 0)
      return i
    end

   i -= 1
  end
end


19-caesar-cipher.rb

January 7th, 2015

Here’s the code I created before looking at a/A solution:

def caesar_cipher(offset, string)
  offset_string = []

  idx = 0
  while idx < string.length
    character_num = string[idx].ord
    
    if character_num < 97 || character_num > 122
      character_num = character_num.chr
      offset_string = offset_string.push(character_num)
    elsif (character_num >= 97) && (character_num <= 122)
      character_num = (((character_num - 97 + 3) % 26) + 97).chr
      offset_string = offset_string.push(character_num)
    end

    idx += 1
  end

  return offset_string.join("")
end

The key to understanding this code was learning the letters positioning on the ASCII chart. Also, the key is to subtract your 97 (the number that references to “a” and starts the alphabet) first. Then you can add to the string as the offset suggests. After you’ve got that, the modulo at 26 will take the reference numbers off the top and move them to the beginning (therefore what was a z (122) had gone off the charts (125) so when we modulo it it becomes (3).

Then we bring back the reference space (so we add 97) and runs the .chr on it.

That’s the key to this problem. The key is understanding how to use the leftovers and convert them back.

I can’t imagine they have some dramatically different way to do this. It’s not like identifying primes numbers or anything right? It’s just moving around digits and arithmetic. Anyways, I’ll dissect their solution, but a quick notes:

 

This is an excellent computer science exercise.

 

Why? Because it draws connections from the base of computing to the level we’re at now. The ASCII chart can tell you the 7 digit sets of | and 0 that create letters.

With these letters we can create code already which answers intense math questions and can lead us on a narrative storyline. So this brings a LOT into perspective. From Ada to now, it’s all starting to become more clear.

20-num-repeats.rb

January 5, 2015

I’m very happy to write that I was able to find a solution to this problem without the aid of any outside sources. It took a long time to sort out the specifics and I can’t imagine this is the most efficient way to do this, but here’s the code I came up with to solve the problem:

def num_repeats(string)
  num_letters_appearing_more_than_once = 0
  current_letter = ""
  counted_letters = []

  idx1 = 0
    while idx1 < string.length
      current_letter = string[idx1]

      idx2 = 0
      idx3 = 0

      while idx3 <= counted_letters.length
        if counted_letters[idx3] == current_letter
          idx2 += string.length + 1
        end
        idx3 += 1
      end

      compare_letter = ""
      compare_count = 0

      while idx2 < string.length
        compare_letter = string[idx2]
        if compare_letter == current_letter
          compare_count += 1
        if (compare_count == 2)
          counted_letters = counted_letters.push(current_letter)
        num_letters_appearing_more_than_once += 1
      end
    end

    idx2 += 1
    end

    idx1 += 1
  end
  
  return num_letters_appearing_more_than_once
end

 

Here is what the above code does: First we set a loop to run through the first string comparing individual letters. Then we set another string to run through each individual letters a second time. We compare each letter against each letter to see if the frequency goes above 2. We use 2 because every result will come up with 1 because each letter in the string appears once. Once the repeating letter is identified, we push it onto an array of letters that we have counted. Moving forward, before counting a new string, we check the new potential double letter against the array of letters that have already been counted. If the current letter is not in that array and has been counted twice, we count it too. This gives us the proper answer.

Phew! Ok I can already think of a few other ways to do this. For now, I’d like to check the a/A result to see if they look at it totally different. That’s what I’ll do now.

Their code is 37 lines deep and mine is 43 so they aren’t dramatically different. Their’s works like this:

  1. It loops the string and iterates through by letter
  2. They assign each letter to an array (with a side array, which is the first time I’ve seen this) in order of appearance
  3. Then they simply walk through the array asking each if there are values above 1

Good news is, their process and my own solution work in very similar ways.

Note: I want to make a quick note on how I deconstruct the code of others. The key is to slide in put commands in places where you don’t understand what’s happening. Then you run the program and can read the output of the inner workings of various programs. Here is a screen shot of what I’m talking about (some code is hidden so the critical elements can be seen on a single screen:

How to Deconstruct Code to Understand it's inner workings

I like that their code utilizes a process of breaking the code into useful arrays. One could imagine that if you did this process to a huge database, you could use the output to get more understanding using the arrays created from identifying this. That said, I feel like if you really wanted to search a large amount of data, my code would be more useful because it uses more negation and therefore less required processing to move through strings.

Either way, this assignment of strings to arrays and connecting their letters to values is a tool which will be useful one day. I’ll write their code a few times to learn the process of breaking strings into frequency arrays.

Update January 16th, 2015

Running through the code again and I wrote this program in a different way. The fundamental difference is that the code below uses two method whereas the code above uses one. The second code is dependent upon the first now, but the first one could be used anytime you want to identify if a string is in an array. This makes the code simpler to understand. I think this one is better than my first version.

def letter_counted?(string, arr)
    idx = 0
    while idx < arr.length
        if arr[idx] == string
            return true
        end
        idx += 1
    end
    return false
end

def num_repeats(string)
    num_of_appearing_letters = 0
    counted_letters = []
    
    idx = 0
    while idx < string.length
        current_letter = string[idx]
        letter_count = -1
        
        idx2 = 0
        while idx2 < string.length
            compare_letter = string[idx2]
            
            if (current_letter == compare_letter)
                letter_count += 1
                if letter_count == 1 && (letter_counted?(current_letter, counted_letters) == false)
                    num_of_appearing_letters += 1
                    counted_letters = counted_letters.push(current_letter)
                end
            end
            
            idx2 += 1
        end
        
        idx += 1
    end
    
    return num_of_appearing_letters
end

Wrapping up – Application Time

January 24, 2015

I’ve been studying Ruby for a month and a half. Really trying to get as good as I could. Today, I found myself diving into really complex problems at CodeWars.com and I realized, I’ll never be more ready for the a/A coding test. To be honest, I’m procrastinating because I want to ensure success.

So I went back to a/A application process and ran the practice problems. We’re supposed to solve them within 45 minutes. I opened them up and solved all three in 13 minutes.

Here’s the code it took for me to solve the problems:

# start 15:22 Jan 24 - 2015
# complete 15:35 Jan 24 - 2015
# Time to Complete = 13 minutes

def lucky_sevens?(numbers)

  idx = 0
  while (idx < numbers.length) && (idx + 2 < numbers.length)
    if numbers[idx] + numbers[idx + 1] + numbers[idx + 2] == 7
      return true
    end
    idx += 1
  end

  return false
end

puts lucky_sevens?([2,1,5,1,0])
puts lucky_sevens?([0,-2,1,8])
puts lucky_sevens?([7,7,7,7])
puts lucky_sevens?([3,4,3,4])

def oddball_sum(numbers)
  sum = 0

  idx = 0
  while idx < numbers.length
    if numbers[idx] % 2 != 0
      sum += numbers[idx]
    end
    idx += 1
  end

  return sum
end

puts oddball_sum([1,2,3,4,5]).to_s + " should be 9"
puts oddball_sum([0,6,4,4]).to_s + " should be 0"
puts oddball_sum([1,2,1]).to_s + " should be 2"

def disemvowel(string)
  vowelless_string = ""

  idx = 0
  while idx < string.length
    if string[idx] != "a" && string[idx] != "e" && string[idx] != "i" && string[idx] != "o" && string[idx] != "u"
      vowelless_string += string[idx]
    end
    idx += 1
  end

  return vowelless_string
end

puts disemvowel("foobar").to_s + " should be = fbr"
puts disemvowel("ruby").to_s + " should be = rby"
puts disemvowel("aeiou").to_s + " should be = \"\""

So there is no reason for me not to apply right now. That’s what I’m going to do.

Application

January 24, 2015

I spent 15:50 to 16:23 (estimated) which is about 33 minutes. Fairly certain all my solutions were rock solid. In the solutions I left the tests that I ran to ensure my code was correct. I hope that doesn’t hurt my results.

I’ll not share my code here as they request that we don’t share our code regarding this test.

That’s it for this round of studying.

To be honest, that’s pretty much it for this post on learning code too. Whether I’m accepted to a/A or not, I’ll continue to develop this skill until I can start building things on my own.

Though a/A is my first choice of schools, I will also apply to some of the other great coding bootcamps. Hack Reactor, Fullstack Academy look great as well as a few others I’ll begin the application process for.

Thank you for reading. If you found these notes helpful, please feel free to leave a message or some code below in the comment section.

4 Replies to “AppAcademy.io Practice Problem Notes”

  1. Hey Ian,

    As a prospective A/a student, I just wanted to say thank you for sharing this material! I’ve only gone through bits and pieces of this post, but I very much enjoy seeing your thought processes through these practice problems.

    Two questions come to mind:

    1. In addition to the supplied prep reading, would you say that being able to solve all 21 of A/a’s “official” practice problems adequately prepares me for the coding challenge and technical interview?

    2. The November 2016 cohort looks attractive to me as well. I’m just about to wrap up those practice problems (solving and re-solving the last 2-3 “hard” problems) after about three weeks of studying. I was also able to solve all three practice coding exercises (http://prepwork.appacademy.io/coding-test-1/practice-coding-exercise/) within ~10 minutes total.

    Today is October 5th — would you say I’d be rushing to get into this cohort, and I should just shoot for the next (i.e., January 2017)?

    Thanks again!

    1. Hey Anderson,

      It’s great to hear from you. Answers:

      1. Yes. I learned them all. Then I went back through and tried to ensure I could do every problem in under 15 minutes and in more than one way.

      2. Great work. It seems to me that you have the key to success which is work ethic. To me, it’s important to apply quickly. If you get rejected, you can always apply again. Rush your way in there. Life is short. 😀 It would be great to see you in the cohort in November. That’s the one I’m in.

  2. Thanks for your effort.

    Both of the codes for the time conversion actually don’t work properly if you copy and paste the code into repl.it ; You should edit them so that the code is correct and future students won’t have to debug it on top of learning the concept.

    A few syntax errors, also try to use your code to call the method, after that use 0 and see what happens. You’ll see the true code to be more efficient and can deal with any integer input whereas your code will come across issues.

    Thanks again….

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.