diff --git a/00_hello/hello.rb b/00_hello/hello.rb new file mode 100644 index 000000000..61626e810 --- /dev/null +++ b/00_hello/hello.rb @@ -0,0 +1,7 @@ +def hello + "Hello!" +end + +def greet(name) + "Hello, #{name}!" +end diff --git a/01_temperature/temperature.rb b/01_temperature/temperature.rb new file mode 100644 index 000000000..d82b233da --- /dev/null +++ b/01_temperature/temperature.rb @@ -0,0 +1,7 @@ +def ftoc(degrees) + (degrees - 32).to_f * 5.0 / 9.0 +end + +def ctof(d) + d * 9.0 / 5.0 + 32.0 +end diff --git a/02_calculator/calculator.rb b/02_calculator/calculator.rb new file mode 100644 index 000000000..09aa5c6c0 --- /dev/null +++ b/02_calculator/calculator.rb @@ -0,0 +1,27 @@ +def add(x, y) + x + y +end + +def subtract(x, y) + x - y +end + +def sum(nums) + nums.reduce(0){ |total, n| total + n } +end + +def multiply(*nums) + nums.reduce(1){ |total, n| total * n } +end + +def power(x, y) + x ** y +end + +def factorial(x) + if x <= 1 + 1 + else + x * factorial(x - 1) + end +end diff --git a/02_calculator/calculator_spec.rb b/02_calculator/calculator_spec.rb index fef7e9d00..3ce77d87f 100644 --- a/02_calculator/calculator_spec.rb +++ b/02_calculator/calculator_spec.rb @@ -79,21 +79,41 @@ describe "#multiply" do - it "multiplies two numbers" + it "multiplies two numbers" do + expect(multiply(3,3)).to eq(9) + end + + it "multiplies several numbers" do + expect(multiply(3, 4, 5)).to eq(60) + 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(2, 3)).to eq(8) + 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..37a3d4353 --- /dev/null +++ b/03_simon_says/simon_says.rb @@ -0,0 +1,40 @@ +def echo(s) + s +end + +def shout(s) + s.upcase +end + +def repeat(s, times=2) + if times <= 1 + s + else + s + " " + repeat(s, times - 1) + end +end + +def start_of_word(s, length) + s[0...length] +end + +def first_word(s) + s.split(" ")[0] +end + +def titleize(s) + littlewords = ["the", "and", "over"] + split = s.split(" ") + capwords = split.each_with_index.map do |word, i| + if i == 0 && split[0] == word + word.capitalize + elsif littlewords.include?(word) + word + else + word.capitalize + end + end + capwords.join(" ") +end + +titleize("the bridge over the river kwai") diff --git a/04_pig_latin/pig_latin.rb b/04_pig_latin/pig_latin.rb new file mode 100644 index 000000000..e6670ab96 --- /dev/null +++ b/04_pig_latin/pig_latin.rb @@ -0,0 +1,24 @@ +def translate(s) + vowels = "aeiou".split("") + split = s.split(" ") + split.reduce([]) do |acc, word| + # begins with vowel + if vowels.include?(word[0].downcase) + word = word + "ay" + # with 3 consonants + elsif word[0..2].split("").all?{ |char| not(vowels.include?(char)) } || + (not(vowels.include?(word[0])) && word[1..2] == "qu") + word = word[3..-1] + word[0..2] + "ay" + # with 2 consonants + elsif word[0..1].split("").all?{ |char| not(vowels.include?(char)) } || + word[0..1].downcase == "qu" + word = word[2..-1] + word[0..1] + "ay" + # with 1 consonant + else + word = word[1..-1] + word[0] + "ay" + end + acc.push(word) + end.join(" ") +end + +translate("the quick brown fox") diff --git a/05_silly_blocks/silly_blocks.rb b/05_silly_blocks/silly_blocks.rb new file mode 100644 index 000000000..b9650b5b4 --- /dev/null +++ b/05_silly_blocks/silly_blocks.rb @@ -0,0 +1,13 @@ +def reverser + yield.split(" ").map(&:reverse).join(" ") +end + +def adder(n=1) + yield + n +end + +def repeater(times=1) + times.times do + yield + end +end diff --git a/06_performance_monitor/performance_monitor.rb b/06_performance_monitor/performance_monitor.rb new file mode 100644 index 000000000..4f2b0faa8 --- /dev/null +++ b/06_performance_monitor/performance_monitor.rb @@ -0,0 +1,11 @@ +require "time" + +def measure(times=1) + acc = [] + times.times do + start = Time.now + yield + acc.push(Time.now - start) + end + acc.reduce(&:+).to_f / times.to_f +end diff --git a/07_hello_friend/friend.rb b/07_hello_friend/friend.rb new file mode 100644 index 000000000..cf9f4bbdb --- /dev/null +++ b/07_hello_friend/friend.rb @@ -0,0 +1,9 @@ +class Friend + def greeting(name=nil) + if name + "Hello, #{name}!" + else + "Hello!" + end + end +end diff --git a/08_book_titles/book.rb b/08_book_titles/book.rb new file mode 100644 index 000000000..363af456b --- /dev/null +++ b/08_book_titles/book.rb @@ -0,0 +1,24 @@ +class Book + + attr_reader :title, :app_state + + def initialize + @app_state = { + exceptions: "the a an and in of".split(" ") + } + @title = nil + end + + def title=(s) + @title = s.split(" ").each_with_index.map do |word, i| + if i == 0 + word.capitalize + elsif app_state[:exceptions].include?(word) + word + else + word.capitalize + end + end.join(" ") + end + +end diff --git a/09_timer/timer.rb b/09_timer/timer.rb new file mode 100644 index 000000000..ae879e79e --- /dev/null +++ b/09_timer/timer.rb @@ -0,0 +1,22 @@ +class Timer + attr_accessor :seconds + + def initialize + @seconds = 0 + end + + def pre_zero(int) + if int.to_s.length == 1 + "0#{int}" + else + int.to_s + end + end + + def time_string + seconds_left = seconds % 60 + minutes_left = (seconds/60) % 60 + hour = (seconds/60) / 60 + "#{pre_zero(hour)}:#{pre_zero(minutes_left)}:#{pre_zero(seconds_left)}" + end +end diff --git a/10_temperature_object/temperature.rb b/10_temperature_object/temperature.rb new file mode 100644 index 000000000..efd79451d --- /dev/null +++ b/10_temperature_object/temperature.rb @@ -0,0 +1,89 @@ +def ftoc(degrees) + (degrees - 32).to_f * 5.0 / 9.0 +end + +def ctof(d) + d * 9.0 / 5.0 + 32.0 +end + +# ---------------------------------------------------------------------- +# Temperature +# ---------------------------------------------------------------------- + +class Temperature + + attr_accessor :degrees + + def initialize(options = {}) + @degrees = options + end + + def self.from_celsius(d) + Temperature.new({c: d}) + end + + def self.from_fahrenheit(d) + Temperature.new({f: d}) + end + + def in_fahrenheit + if degrees[:f] + degrees[:f] + else + ctof(degrees[:c]) + end + end + + def in_celsius + if degrees[:f] + ftoc(degrees[:f]) + else + degrees[:c] + end + end + +end + +# ---------------------------------------------------------------------- +# Celsius +# ---------------------------------------------------------------------- + +class Celsius < Temperature + + attr_accessor :degree + + def initialize(d) + @degree = d + end + + def in_celsius + degree + end + + def in_fahrenheit + ctof(degree) + end + +end + +# ---------------------------------------------------------------------- +# Fahrenheit +# ---------------------------------------------------------------------- + +class Fahrenheit < Temperature + + attr_accessor :degree + + def initialize(d) + @degree = d + end + + def in_fahrenheit + degree + end + + def in_celsius + ftoc(degree) + end + +end diff --git a/11_dictionary/dictionary.rb b/11_dictionary/dictionary.rb new file mode 100644 index 000000000..b0453bb93 --- /dev/null +++ b/11_dictionary/dictionary.rb @@ -0,0 +1,41 @@ +class Dictionary + + attr_accessor :entries + + def initialize + @entries = {} + end + + def add(keyvals) + if keyvals.is_a?(Hash) + @entries = entries.merge(keyvals) + else + @entries = entries.merge({keyvals => nil}) + end + end + + def keywords + entries.keys.sort + end + + def include?(k) + entries.include?(k) + end + + def find(s) + entries.select{ |k, v| k.include?(s) } + end + + def printable + entries.sort.reduce("") do |acc, kv| + k, v = kv + s = %Q{[#{k}] "#{v}"} + if acc.empty? + s + else + acc + "\n" + s + end + end + end + +end diff --git a/12_rpn_calculator/rpn_calculator.rb b/12_rpn_calculator/rpn_calculator.rb new file mode 100644 index 000000000..c97ea47b8 --- /dev/null +++ b/12_rpn_calculator/rpn_calculator.rb @@ -0,0 +1,91 @@ +class RPNCalculator + + attr_accessor :stack, :value + + def initialize + @stack = [] + @value = 0 + end + + def tokens(s) + operators = "* + - /".split(" ") + s.split(" ").map do |char| + if operators.include?(char) + char.to_sym + else + char.to_i + end + end + end + + def map_operators(op) + { + :* => method(:times), + :/ => method(:divide), + :- => method(:minus), + :+ => method(:plus) + }[op] + end + + def evaluate(s) + operators = [:*, :/, :+, :-] + stack_ = tokens(s) + stack_.each do |i| + if i.is_a?(Integer) + push(i) + elsif operators.include?(i) + map_operators(i).call + end + end + value + end + + def empty_stack_error + raise "calculator is empty" + end + + def push(n) + stack.push(n) + end + + def plus + if stack.empty? + empty_stack_error + end + x, y = stack.pop, stack.pop + result = x + y + @value = result + push(result) + end + + def minus + if stack.empty? + empty_stack_error + end + x, y = stack.pop, stack.pop + result = y - x + @value = result + push(result) + end + + def divide + if stack.empty? + empty_stack_error + end + x, y = stack.pop, stack.pop + result = y.to_f / x.to_f + @value = result + push(result) + end + + def times + if stack.empty? + empty_stack_error + end + x, y = stack.pop, stack.pop + result = x * y + @value = result + push(result) + end + +end diff --git a/14_array_extensions/array_extensions.rb b/14_array_extensions/array_extensions.rb new file mode 100644 index 000000000..8d237a6de --- /dev/null +++ b/14_array_extensions/array_extensions.rb @@ -0,0 +1,17 @@ +class Array + + def square + if self.empty? + [] + else + self.map { |i| i*i } + end + end + + def square! + self.each_with_index do |item, i| + self[i] = item*item + end + end + +end diff --git a/15_in_words/in_words.rb b/15_in_words/in_words.rb new file mode 100644 index 000000000..086fdbf42 --- /dev/null +++ b/15_in_words/in_words.rb @@ -0,0 +1,151 @@ +class Integer + + def one_to_ten + case self + when 0 + "zero" + when 1 + "one" + when 2 + "two" + when 3 + "three" + when 4 + "four" + when 5 + "five" + when 6 + "six" + when 7 + "seven" + when 8 + "eight" + when 9 + "nine" + end + end + + def ten_to_twelve + case self + when 10 + "ten" + when 11 + "eleven" + when 12 + "twelve" + end + end + + def teens + case self + when 13 + "thirteen" + when 14 + "fourteen" + when 15 + "fifteen" + when 16 + "sixteen" + when 17 + "seventeen" + when 18 + "eighteen" + when 19 + "nineteen" + end + end + + def tens + case self + when 20 + "twenty" + when 30 + "thirty" + when 40 + "forty" + when 50 + "fifty" + when 60 + "sixty" + when 70 + "seventy" + when 80 + "eighty" + when 90 + "ninety" + end + end + + def hundreds + n, rem = self / 100, self % 100 + r = "#{n.in_words} hundred" + r += " " + rem.in_words if rem > 0 + r + end + + def decimalize + self.to_s.split("").reverse.each_with_index.map do |s, i| + s.to_i * (10**i) + end.reverse + end + + def others_less_than_hundred + self.decimalize.map(&:in_words).join(" ") + end + + def twenty_below_hundred + tens || others_less_than_hundred + end + + def thousands + n, rem = self / 1000, self % 1000 + r = "#{n.in_words} thousand" + r += " " + rem.in_words if rem > 0 + r + end + + def millions + n, rem = self / 1_000_000, self % 1_000_000 + r = "#{n.in_words} million" + r += " " + rem.in_words if rem > 0 + r + end + + def billions + n, rem = self / 1_000_000_000, self % 1_000_000_000 + r = "#{n.in_words} billion" + r += " " + rem.in_words if rem > 0 + r + end + + def trillions + n, rem = self / 1_000_000_000_000, self % 1_000_000_000_000 + r = "#{n.in_words} trillion" + r += " " + rem.in_words if rem > 0 + r + end + + def in_words + case self + when 0..9 + one_to_ten + when 10..12 + ten_to_twelve + when 13..19 + teens + when 20..99 + twenty_below_hundred + when 100..999 + hundreds + when 1000..999_999 + thousands + when 1_000_000..999_999_999 + millions + when 1_234_567_890..999_999_999_999 + billions + else + trillions + end + end + +end diff --git a/15_in_words/in_words_spec.rb b/15_in_words/in_words_spec.rb index 1f5768575..09ca9d882 100644 --- a/15_in_words/in_words_spec.rb +++ b/15_in_words/in_words_spec.rb @@ -20,7 +20,7 @@ require "in_words" -describe Fixnum do +describe Integer do it "reads 0 to 9" do expect(0.in_words).to eq('zero')