diff --git a/00_hello/hello.rb b/00_hello/hello.rb new file mode 100644 index 000000000..5a5ad056e --- /dev/null +++ b/00_hello/hello.rb @@ -0,0 +1,7 @@ +def hello + "Hello!" +end + +def greet(who) + "Hello, #{who}!" +end diff --git a/01_temperature/temperature.rb b/01_temperature/temperature.rb new file mode 100644 index 000000000..be7149d19 --- /dev/null +++ b/01_temperature/temperature.rb @@ -0,0 +1,7 @@ +def ftoc(temp) + (temp - 32) * 5.0/9 +end + +def ctof(temp) + temp * 9.0/5 + 32 +end diff --git a/02_calculator/calculator.rb b/02_calculator/calculator.rb new file mode 100644 index 000000000..cde7cb863 --- /dev/null +++ b/02_calculator/calculator.rb @@ -0,0 +1,36 @@ +def add(a, b) + a + b +end + +def subtract(a,b) + a - b +end + +def sum(nums) + return 0 if nums == [] + sum = 0 + nums.each do |n| + sum += n + end + sum +end + +def multiply(*args) + product = 1 + args.each do |n| + product *= n + end + product +end + +def power(base, exp) + base ** exp +end + +def factorial(num) + product = 1 + (1..num).reverse_each do |n| + product *= n + end + product +end diff --git a/02_calculator/calculator_spec.rb b/02_calculator/calculator_spec.rb index fef7e9d00..073ede582 100644 --- a/02_calculator/calculator_spec.rb +++ b/02_calculator/calculator_spec.rb @@ -79,21 +79,37 @@ describe "#multiply" do - it "multiplies two numbers" + it "multiplies two numbers" do + expect(multiply(3,4)).to eq(12) + end + + it "multiplies several numbers" do + expect(multiply(6,7,8)).to eq(336) + end - it "multiplies several numbers" - end describe "#power" do - it "raises one number to the power of another number" + it "raises one number to the power of another number" do + expect((power(9,2))).to eq(81) + end end # http://en.wikipedia.org/wiki/Factorial describe "#factorial" do - it "computes the factorial of 0" - it "computes the factorial of 1" - it "computes the factorial of 2" - it "computes the factorial of 5" - it "computes the factorial of 10" + it "computes the factorial of 0" do + expect(factorial(0)).to eq(1) + end + it "computes the factorial of 1" do + expect(factorial(1)).to eq(1) + end + it "computes the factorial of 2" do + expect(factorial(2)).to eq(2) + end + it "computes the factorial of 5" do + expect(factorial(5)).to eq(120) + end + it "computes the factorial of 10" do + expect(factorial(10)).to eq(3628800) + end end diff --git a/03_simon_says/simon_says.rb b/03_simon_says/simon_says.rb new file mode 100644 index 000000000..a9182acfe --- /dev/null +++ b/03_simon_says/simon_says.rb @@ -0,0 +1,29 @@ +def echo(word) + word +end + +def shout(word) + word.upcase +end + +def repeat(word, num=2) + word += ((' ' + word) * (num - 1)) +end + +def start_of_word(word, num=1) + word[0...num] +end + +def first_word(word) + word.split(" ")[0] +end + +def titleize(words) + return words.capitalize unless words.include?(' ') + little_words = ['a', 'the', 'in', 'to', + 'and', 'an', 'over'] + words = words.split(' ').each_with_index do |word, i| + word.capitalize! unless little_words.include?(word) && i != 0 + end + words.join(' ') +end diff --git a/04_pig_latin/pig_latin.rb b/04_pig_latin/pig_latin.rb new file mode 100644 index 000000000..f6e0665d4 --- /dev/null +++ b/04_pig_latin/pig_latin.rb @@ -0,0 +1,53 @@ +def translate(words) + vowels = ['a', 'e', 'i', 'o', 'u'] + special_sequences = ['qu', 'squ'] + + words = words.split(' ').each do |word| + + # deal with words that start with vowel + next if starts_with_vowel?(word, vowels) + + # deal with words that start with special sequence + next if starts_with_special_sequence?(word, special_sequences) + + # deal with words that start with consonant + next if starts_with_consonant(word, vowels) + + end + + words.join(' ') + +end + +def starts_with_consonant(word, vowels) + i = word.length - 1 + vowels.each do |vowel| + unless word.index(vowel).nil? + if word.index(vowel) < i + i = word.index(vowel) + end + end + end + start = word.slice!(0...i) + word << start + 'ay' + +end + +def starts_with_vowel?(word, vowels) + if vowels.include?(word[0]) + word << 'ay' + return true + end + false +end + +def starts_with_special_sequence?(word, sequences) + sequences.each do |seq| + if word.index(seq) == 0 + word.slice!(0...seq.length) + word << seq + 'ay' + return true + end + end + false +end diff --git a/05_silly_blocks/silly_blocks.rb b/05_silly_blocks/silly_blocks.rb new file mode 100644 index 000000000..90fe8b5a1 --- /dev/null +++ b/05_silly_blocks/silly_blocks.rb @@ -0,0 +1,14 @@ +def reverser() + return yield.reverse if yield.split(' ').size == 1 + yield.split(' ').each { |w| w.reverse! }.join(' ') +end + +def adder(num=1) + yield + num +end + +def repeater(repeats=1) + repeats.times do + yield + end +end diff --git a/05_silly_blocks/silly_blocks_spec.rb b/05_silly_blocks/silly_blocks_spec.rb index c64e3ef70..38f604025 100644 --- a/05_silly_blocks/silly_blocks_spec.rb +++ b/05_silly_blocks/silly_blocks_spec.rb @@ -29,13 +29,13 @@ describe "adder" do it "adds one to the value returned by the default block" do expect(adder do - 5 + 5 end).to eq(6) end it "adds 3 to the value returned by the default block" do expect(adder(3) do - 5 + 5 end).to eq(8) end end diff --git a/06_performance_monitor/performance_monitor.rb b/06_performance_monitor/performance_monitor.rb new file mode 100644 index 000000000..440fd2de8 --- /dev/null +++ b/06_performance_monitor/performance_monitor.rb @@ -0,0 +1,7 @@ +def measure(n=1) + elapsed_time = Time.now + n.times do + yield + end + ( Time.now - elapsed_time ) / n +end diff --git a/07_hello_friend/friend.rb b/07_hello_friend/friend.rb new file mode 100644 index 000000000..30469d37e --- /dev/null +++ b/07_hello_friend/friend.rb @@ -0,0 +1,7 @@ +class Friend + + def greeting(friend='') + return "Hello!" if friend == '' + "Hello, #{friend}!" + end +end diff --git a/08_book_titles/book.rb b/08_book_titles/book.rb new file mode 100644 index 000000000..8469bfd36 --- /dev/null +++ b/08_book_titles/book.rb @@ -0,0 +1,13 @@ +class Book + attr_accessor :title + + def title + non_caps = ['and', 'in', 'of', 'the', 'a', 'an'] + @title = @title.split(' ').each_with_index do |word, i| + word.capitalize! unless non_caps.include?(word) && i != 0 + word + end + @title.join(' ') + end + +end diff --git a/09_timer/timer.rb b/09_timer/timer.rb new file mode 100644 index 000000000..99cda89b9 --- /dev/null +++ b/09_timer/timer.rb @@ -0,0 +1,22 @@ +class Timer + attr_accessor :seconds + + def initialize(seconds=0) + @seconds = seconds + end + + def time_string + time = @seconds + hours, mins, secs = 0, 0, 0 + while time > 60 + if time >= 60 * 60 + hours = time / 60 / 60 + time -= hours * 60 * 60 + elsif time >= 60 + mins = time / 60 + time -= mins * 60 + end + end + human_time = "#{sprintf '%02d', hours}:#{sprintf '%02d', mins}:#{sprintf '%02d', time}" + end +end diff --git a/10_temperature_object/temperature.rb b/10_temperature_object/temperature.rb new file mode 100644 index 000000000..8005f25a4 --- /dev/null +++ b/10_temperature_object/temperature.rb @@ -0,0 +1,41 @@ +class Temperature + + def initialize( options = {}) + @options = options + end + + def in_fahrenheit + return @options[:f] unless @options[:f].nil? + (@options[:c] * 9)/5.0 + 32 + end + + def in_celsius + return (@options[:f] - 32) * 5/9 if @options[:c].nil? + @options[:c] + end + + def self.from_celsius(temp) + Temperature.new({:c => temp}) + end + + def self.in_celsius + @options[:c] + end + + def self.from_fahrenheit(temp) + Temperature.new({:f => temp}) + end + +end + +class Celsius < Temperature + def initialize(temp) + @options = {:c => temp} + end +end + +class Fahrenheit < Temperature + def initialize(temp) + @options = {:f => temp} + end +end diff --git a/11_dictionary/dictionary.rb b/11_dictionary/dictionary.rb new file mode 100644 index 000000000..aad9a0f2e --- /dev/null +++ b/11_dictionary/dictionary.rb @@ -0,0 +1,38 @@ +class Dictionary + attr_accessor :entries + + def initialize(opts = {}) + @entries = opts + end + + def add(entry) + if entry.is_a?(String) + @entries[entry] = nil + else + @entries.merge!(entry) + end + end + + def include?(keyword) + keywords.include?(keyword) + end + + def find(keyword) + return @entries if @entries.empty? + @entries.select { |word, definition| word.match(keyword)} + end + + def printable + printout = '' + keywords.each_with_index do |key, i| + printout << "[#{key}] \"#{@entries[key]}\"" + printout << "\n" if i < keywords.size-1 + end + printout + end + + def keywords + @entries.keys.sort + end + +end diff --git a/12_rpn_calculator/rpn_calculator.rb b/12_rpn_calculator/rpn_calculator.rb new file mode 100644 index 000000000..23387386b --- /dev/null +++ b/12_rpn_calculator/rpn_calculator.rb @@ -0,0 +1,62 @@ +class RPNCalculator + + attr_reader :nums, :value + + def initialize + @nums = [] + @value = 0 + end + + def push(num) + @nums << num + end + + def plus + @value = do_maths {'+'} + end + + def minus + @value = do_maths {'-'} + end + + def divide + @value = do_maths{'/'} + end + + def times + @value = do_maths{'*'} + end + + def evaluate(items) + items = tokens(items) + items.each do |item| + push(item) if item.is_a?(Fixnum) + times if item == :* + plus if item == :+ + minus if item == :- + divide if item == :/ + end + value + + end + + def tokens(tokens) + operators = ['+', '-', '*', '/'] + tokens.split(' ').collect! do |token| + operators.include?(token)? token.to_sym : token.to_i + end + end + + def do_maths + begin + @nums[-2] += @nums[-1] if yield == '+' + @nums[-2] -= @nums[-1] if yield == '-' + @nums[-2] /= @nums[-1] * 1.0 if yield == '/' + @nums[-2] *= @nums[-1] if yield == '*' + rescue NoMethodError + raise "calculator is empty" + end + @nums.pop + @val = @nums[-1] + end +end diff --git a/14_array_extensions/array_extensions.rb b/14_array_extensions/array_extensions.rb new file mode 100644 index 000000000..e902cce6c --- /dev/null +++ b/14_array_extensions/array_extensions.rb @@ -0,0 +1,18 @@ +class Array + + def sum + return 0 if self.empty? + self.inject { |prev, curr| prev + curr} + end + + def square + return self if self.empty? + self.map { |n| n**2 } + end + + def square! + return self if self.empty? + self.map! { |n| n**2 } + end + +end diff --git a/15_in_words/in_words.rb b/15_in_words/in_words.rb new file mode 100644 index 000000000..0524a2139 --- /dev/null +++ b/15_in_words/in_words.rb @@ -0,0 +1,67 @@ +class Fixnum + + def in_dictionary(word) + dictionary = { 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five', 6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine', 10 => 'ten', 11 => 'eleven', 12 => 'twelve', 13 => 'thirteen', 14 => 'fourteen', 15 => 'fifteen', 16 => 'sixteen', 17 => 'seventeen', 18 => 'eighteen', 19 => 'nineteen', 20 => 'twenty', 30 => 'thirty', 40 => 'forty', 50 => 'fifty', 60 => 'sixty', 70 => 'seventy', 80 => 'eighty', 90 => 'ninety'} + dictionary[word] + end + + def in_words + + # return 0 and other numbers immediately if they are in dictionary + return 'zero' if self == 0 + return in_dictionary(self) unless in_dictionary(self).nil? + + words = [] + num = self + + # split num into chunks of 3 digits and store in array + chunks = self.to_s.reverse.scan(/.{1,3}/).reverse.map!{|n| n.reverse.to_i} + + # keep track of the chunk of 1000 we're on + z = chunks.size + + chunks.each_with_index do |n, i| + + n = hundreds(words, n) + + if in_dictionary(n) + words << in_dictionary(n) + elsif n > 0 + n = tens(words, n) + n = ones(words, n) + end + + if chunks[i] > 0 + words.push('trillion') if z == 5 + words.push('billion') if z == 4 + words.push('million') if z == 3 + words << 'thousand' if z == 2 + end + + z -= 1 + end + + words.join(' ') + + end + + def ones(list, num) + return num unless num >= 0 + list << in_dictionary(num) + num -= num + end + + def tens(list, num) + return num unless num >= 10 + list << in_dictionary(num/10*10) + num = num % 10 + end + + def hundreds(list, num) + return num unless num >= 100 + list << in_dictionary(num/100) + list << 'hundred' + num = num % 100 + end + +end diff --git a/15_in_words/words.rb b/15_in_words/words.rb new file mode 100644 index 000000000..305207c2a --- /dev/null +++ b/15_in_words/words.rb @@ -0,0 +1,48 @@ +class Fixnum + + def in_words + dictionary = { 0 => 'zero', 1 => 'one', 2 => 'two', 3 => 'three', 4 => 'four', 5 => 'five', 6 => 'six', 7 => 'seven', 8 => 'eight', 9 => 'nine', 10 => 'ten', 11 => 'eleven', 12 => 'twelve', 13 => 'thirteen', 14 => 'fourteen', 15 => 'fifteen', 16 => 'sixteen', 17 => 'seventeen', 18 => 'eighteen', 19 => 'nineteen', 20 => 'twenty', 30 => 'thirty', 40 => 'forty', 50 => 'fifty', 60 => 'sixty', 70 => 'seventy', 80 => 'eighty', 90 => 'ninety'} + + # return / eliminate the num in dictionary immediately if it's in above dictionary + return dictionary[self] unless dictionary[self].nil? + + # make sure zero prints as '' from here on + dictionary[0] = nil + + # set up list into which we'll push words + words = [] + + # convert to array of fixnum e,g, 72_658 => [7,2,6,5,8] + num = self + + + # iterate through each number, starting from left + # use i to keep track of the powers of 10 + while num > 0 + + exp = num.to_s.split('').size-1 + + # if it's in the dictionary, put it in + unless dictionary[num].nil? + words << dictionary[num] + num -= num/10**exp * 10**exp + next + end + + # if NOT in the dictionary + if exp == 2 + words << dictionary[num/10**exp] + end + + end + + + words.join(' ') + end + + +end + + + +puts 1099.in_words