diff --git a/assignments/assignment01.rb b/assignments/assignment01.rb deleted file mode 100644 index cf3a605..0000000 --- a/assignments/assignment01.rb +++ /dev/null @@ -1,93 +0,0 @@ -# ======================================================================================== -# Sample Problem - `number_to_string` -def number_to_string(n, lang) - lang_digit_strings = { - en: %w(zero one two three four five six seven eight nine), - de: %w(null eins zwei drei vier fünf sechs sieben acht neun), - es: %w(cero uno dos tres cuatro cinco seis siete ocho nueve), - fr: %w(zéro un deux trois quatre cinq six sept huit neuf) - } - - digit_strings = lang_digit_strings[lang] - return "no such language" if digit_strings.nil? - - s = n.to_s - string_digits = s.split "" - - - num_digits = [] - string_digits.each do |s| - num_digits << s.to_i - end - - result = "" - num_digits.each do |digit| - result << digit_strings[digit] - result << " " - end - - result.chop -end - - -# ======================================================================================== -# Problem 1 - `titleize` - -# implement a method `titleize` - -# it accepts a string -# and returns the same string with each word capitalized. -def titleize(s) - words = s.split - caps = [] - words.each do |word| - caps << word.capitalize - end - caps.join " " -end - -# Your method should generate the following results: -titleize "hEllo WORLD" #=> "Hello World" - -titleize "gooDbye CRUel wORLD" #=> "Goodbye Cruel World" - - -# ======================================================================================== -# Problem 2 - `my_reverse` - -# Write your own implementation of `reverse` called `my_reverse` -# You may *not* use the built-in `reverse` method -def my_reverse(s) - output = "" - letters = s.split "" - n = letters.length - while n > 0 - n -= 1 - output << letters[n] - end - output -end - -# Your method should generate the following results: -my_reverse "Hello World" #=> "dlroW olleH" - -my_reverse "Goodbye Cruel World" #=> "dlroW leurC eybdooG" - - -# ======================================================================================== -# Problem 3 - `palindrome?` - -# Write a method `palindrome?` -# that determines whether a string is a palindrome -def palindrome?(s) - stripped = s.delete(" ").delete(",").downcase - stripped == stripped.reverse -end - -# Your method should generate the following results: -palindrome? "abba" #=> true -palindrome? "aBbA" #=> true -palindrome? "abb" #=> false - -palindrome? "Able was I ere I saw elba" #=> true -palindrome? "A man, a plan, a canal, Panama" #=> true diff --git a/assignments/assignment02-input.csv b/assignments/assignment02-input.csv deleted file mode 100644 index a19c0fd..0000000 --- a/assignments/assignment02-input.csv +++ /dev/null @@ -1,53 +0,0 @@ -date,payee,amount,type -12/1/2014,Walgreens,21.92,withdrawal -12/18/2014,check #5129,125.00,withdrawal -12/16/2014,check #5127,50.00,withdrawal -12/7/2014,Safeway,23.89,withdrawal -12/31/2014,Starbucks,8.45,withdrawal -12/30/2014,ATM,100.00,withdrawal -12/4/2014,Univ Washington,1500.00,deposit -12/4/2014,Starbucks,5.30,withdrawal -12/4/2014,Subway,7.80,withdrawal -12/5/2014,Nike Town,85.00,withdrawal -12/6/2014,Starbucks,5.30,withdrawal -12/6/2014,ATM,50.00,deposit -12/8/2014,Starbucks,5.30,withdrawal -12/11/2014,Safeway,42.15,withdrawal -12/9/2014,Bartell's,7.83,withdrawal -12/9/2014,check #5128,575.00,withdrawal -12/15/2014,Starbucks,5.30,withdrawal -12/22/2014,check #5130,120.00,withdrawal -12/15/2014,ATM,50.00,deposit -12/11/2014,Home Depot,17.89,withdrawal -12/18/2014,Starbucks,5.30,withdrawal -12/27/2014,Walgreens,14.56,withdrawal -12/30/2014,Safeway,35.17,withdrawal -12/23/2014,Starbucks,5.30,withdrawal -12/18/2014,Starbucks,5.30,withdrawal -12/31/2014,check #5131,20.00,withdrawal -12/7/2014,check #5132,75.00,withdrawal -12/14/2014,check #5133,17.50,withdrawal -12/13/2014,check #5134,45.68,withdrawal -12/14/2014,Office Depot,24.85,withdrawal -12/17/2014,Apple,110.62,withdrawal -12/6/2014,ATM,500.00,deposit -12/26/2014,check #5135,62.50,withdrawal -12/28/2014,check #5136,62.50,withdrawal -12/27/2014,Starbucks,5.30,withdrawal -12/12/2014,ATM,60.00,withdrawal -12/13/2014,QFC,13.25,withdrawal -12/13/2014,check #5126,25.00,withdrawal -12/19/2014,Chipotle,10.42,withdrawal -12/18/2014,Bartell's,14.82,withdrawal -12/22/2014,Safeway,28.45,withdrawal -12/21/2014,ATM,20.00,deposit -12/22/2014,QFC,48.13,withdrawal -12/22/2014,Shell,52.00,withdrawal -12/5/2014,ATM,60.00,withdrawal -12/7/2014,Arco,42.00,withdrawal -12/17/2014,Univ Washington,1500.00,deposit -12/14/2014,Chipotle,10.42,withdrawal -12/15/2014,ATM,60.00,withdrawal -12/16/2014,7-Eleven,5.26,withdrawal -12/16/2014,Arco,48.01,withdrawal -12/29/2014,Starbucks,5.30,withdrawal diff --git a/assignments/assignment02-output.html b/assignments/assignment02-output.html deleted file mode 100644 index c327bd7..0000000 --- a/assignments/assignment02-output.html +++ /dev/null @@ -1,472 +0,0 @@ - - - Bank Statement - - - -

Bank Statement

-

Summary

- - - - - -
Starting Balance $ 0.00
Total Deposits $ 3,620.00
Total Withdrawals$ 2,178.76
Ending Balance $ 1,441.24
- -

Withdrawals

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
12/01/2014Walgreens$ 21.92
12/04/2014Subway$ 7.80
12/04/2014Starbucks$ 5.30
12/05/2014Nike Town$ 85.00
12/05/2014ATM$ 60.00
12/06/2014Starbucks$ 5.30
12/07/2014check #5132$ 75.00
12/07/2014Arco$ 42.00
12/07/2014Safeway$ 23.89
12/08/2014Starbucks$ 5.30
12/09/2014Bartell's$ 7.83
12/09/2014check #5128$ 575.00
12/11/2014Home Depot$ 17.89
12/11/2014Safeway$ 42.15
12/12/2014ATM$ 60.00
12/13/2014check #5134$ 45.68
12/13/2014check #5126$ 25.00
12/13/2014QFC$ 13.25
12/14/2014Office Depot$ 24.85
12/14/2014check #5133$ 17.50
12/14/2014Chipotle$ 10.42
12/15/2014Starbucks$ 5.30
12/15/2014ATM$ 60.00
12/16/2014Arco$ 48.01
12/16/2014check #5127$ 50.00
12/16/20147-Eleven$ 5.26
12/17/2014Apple$ 110.62
12/18/2014Bartell's$ 14.82
12/18/2014Starbucks$ 5.30
12/18/2014Starbucks$ 5.30
12/18/2014check #5129$ 125.00
12/19/2014Chipotle$ 10.42
12/22/2014check #5130$ 120.00
12/22/2014Shell$ 52.00
12/22/2014Safeway$ 28.45
12/22/2014QFC$ 48.13
12/23/2014Starbucks$ 5.30
12/26/2014check #5135$ 62.50
12/27/2014Starbucks$ 5.30
12/27/2014Walgreens$ 14.56
12/28/2014check #5136$ 62.50
12/29/2014Starbucks$ 5.30
12/30/2014ATM$ 100.00
12/30/2014Safeway$ 35.17
12/31/2014Starbucks$ 8.44
12/31/2014check #5131$ 20.00
- -

Deposits

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
12/04/2014Univ Washington$ 1,500.00
12/06/2014ATM$ 50.00
12/06/2014ATM$ 500.00
12/15/2014ATM$ 50.00
12/17/2014Univ Washington$ 1,500.00
12/21/2014ATM$ 20.00
- -

Daily Balances

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
12/01/2014$ -21.92
12/04/2014$ 1,464.98
12/05/2014$ 1,319.98
12/06/2014$ 1,864.68
12/07/2014$ 1,723.79
12/08/2014$ 1,718.49
12/09/2014$ 1,135.66
12/11/2014$ 1,075.62
12/12/2014$ 1,015.62
12/13/2014$ 931.69
12/14/2014$ 878.92
12/15/2014$ 863.62
12/16/2014$ 760.35
12/17/2014$ 2,149.73
12/18/2014$ 1,999.31
12/19/2014$ 1,988.89
12/21/2014$ 2,008.89
12/22/2014$ 1,760.31
12/23/2014$ 1,755.01
12/26/2014$ 1,692.51
12/27/2014$ 1,672.65
12/28/2014$ 1,610.15
12/29/2014$ 1,604.85
12/30/2014$ 1,469.68
12/31/2014$ 1,441.24
- - - - diff --git a/assignments/assignment02.rb b/assignments/assignment02.rb index 532f55c..95a94db 100644 --- a/assignments/assignment02.rb +++ b/assignments/assignment02.rb @@ -9,14 +9,12 @@ # creates an english string from array -def to_sentence(ary) - if ary.length == 0 - [] - elsif ary.length == 1 - ary[0] +def to_sentence(ary) + unless (ary.length < 2) + last_word = ary.pop.to_s + sentence = (ary.join ", ") << " and " << last_word else - last = ary.pop - "#{ary.join(", ")} and #{last}" + ary.pop.to_s end end @@ -32,21 +30,13 @@ def to_sentence(ary) # implement methods "mean", "median" on Array of numbers def mean(ary) - sum = ary.reduce(0) {|x, acc| acc + x} - sum.to_f / ary.length + ary.reduce {|item, acc| acc + item} / ary.length.to_f end def median(ary) - sorted_ary = ary.sort - len = sorted_ary.length - mid_index = len/2 - if len.odd? - sorted_ary[mid_index] - else - mid_lo = sorted_ary[mid_index] - mid_hi = sorted_ary[mid_index+1] - (mid_lo + mid_hi)/2.0 - end + middle = ary.length / 2 + sorted = ary.sort + ary.length.odd? ? sorted[middle] : 0.5 * (sorted[middle] + sorted[middle - 1]) end # Your method should generate the following results: @@ -62,7 +52,13 @@ def median(ary) # implement method `pluck` on array of hashes def pluck(ary, key) - ary.map {|item| item[key]} + # create an empty array + values = [] + # for each element in ary, fetch the value associated with key + # push the value into values + ary.each_index {|x| values.push ary[x].fetch(key, "")} + #return values + values end # Your method should generate the following results: @@ -90,10 +86,9 @@ def pluck(ary, key) # - daily balance # - summary: # - starting balance, total deposits, total withdrawals, ending balance + def bank_statement - - # ------------------------------------------------------------------------ - # formatting helpers: + def format_currency(amount) prefix = if amount < 0 amount = -amount @@ -117,15 +112,13 @@ def format_currency(amount) end "$ #{prefix}#{dollars}.#{cents}" end - + def format_date(date) month_string = date[:month] < 10 ? "0#{date[:month]}" : date[:month].to_s - day_string = date[:day] < 10 ? "0#{date[:day]}" : date[:day].to_s + day_string = date[:day] < 10 ? "0#{date[:day]}" : date[:day].to_s "#{month_string}/#{day_string}/#{date[:year]}" end - - # ------------------------------------------------------------------------ - # rendering: + def render_html(statement) <<-HTML @@ -133,7 +126,7 @@ def render_html(statement) Bank Statement @@ -142,105 +135,92 @@ def render_html(statement) HTML end - + def render_body(statement) - <<-BODY - -

Bank Statement

- #{render_summary statement[:summary]} - #{render_txs statement[:withdrawals], "Withdrawals"} - #{render_txs statement[:deposits], "Deposits"} - #{render_daily_balances statement[:dates], statement[:daily_balances]} - - BODY + <<-BODY + +

Bank Statement

+ #{render_summary statement[:summary]} + #{render_txs statement[:withdrawals], "Withdrawals"} + #{render_txs statement[:deposits], "Deposits"} + #{render_daily_balances statement[:dates], statement[:daily_balances]} + + BODY end - + def render_summary(summary) - <<-SUMMARY -

Summary

- - - - - -
Starting Balance #{format_currency summary[:starting_balance]}
Total Deposits #{format_currency summary[:sum_deposits]}
Total Withdrawals#{format_currency summary[:sum_withdrawals]}
Ending Balance #{format_currency summary[:ending_balance]}
- SUMMARY - end - - def render_tx(tx) - <<-TX - - #{tx[:formatted_date]} - #{tx[:payee]} - #{format_currency tx[:amount]} - - TX - end - - def render_txs(txs, label) - <<-TXS -

#{label}

- - #{txs.map {|tx| render_tx tx}.join "\n"} -
- TXS - end + <<-SUMMARY +

Summary

+ + + + + +
Starting Balance #{format_currency summary[:starting_balance]}
Total Deposits #{format_currency summary[:sum_deposits]}
Total Withdrawals#{format_currency summary[:sum_withdrawals]}
Ending Balance #{format_currency summary[:ending_balance]}
+ SUMMARY + end - def render_daily_balance(date, balance) - <<-TXS - - #{date} - #{format_currency balance[:summary][:ending_balance]} - - TXS - end + def render_tx(tx) + <<-TX + + #{tx[:formatted_date]} + #{tx[:payee]} + #{format_currency tx[:amount]} + + TX + end - def render_daily_balances(dates, balances) - <<-BALANCES -

Daily Balances

- - #{dates.map {|date| render_daily_balance date, balances[date]}.join "\n"} -
- BALANCES - end + def render_txs(txs, label) + <<-TXS +

#{label}

+ + #{txs.map {|tx| render_tx tx}.join "\n"} +
+ TXS + end - # ------------------------------------------------------------------------ - # read csv file, generate txs: - def read_txs + def render_daily_balance(date, balance) + <<-TXS + + #{date} + #{format_currency balance[:summary][:ending_balance]} + + TXS + end + + def read_transactions File.open("assignment02-input.csv") do |file| lines = file.readlines keys = lines.shift.chomp.split(",").map {|key| key.to_sym} lines.map do |line| - tx = {} + transaction = {} line.chomp.split(",").each_with_index do |field, index| key = keys[index] - tx[key] = field + transaction[key] = field end - tx - end.map do |tx| - tx[:amount] = (tx[:amount].to_f * 100).to_i - month, day, year = tx[:date].split "/" + transaction + end.map do |transaction| + transaction[:amount] = (transaction[:amount].to_f * 100).to_i + month, day, year = transaction[:date].split "/" date = {year: year.to_i, month: month.to_i, day: day.to_i} - tx[:date] = date - tx[:formatted_date] = format_date date - tx + transaction[:date] = date + transaction[:formatted_date] = format_date date + transaction end.sort {|a,b| a[:formatted_date] <=> b[:formatted_date]} end end - - # ------------------------------------------------------------------------ - # calc totals for collection of txs: - def txs_totals(txs, starting_balance) - withdrawals = txs.select {|tx| tx[:type] == "withdrawal"}.sort {|a,b| a[:formatted_date] <=> b[:formatted_date]} - sum_withdrawals = withdrawals.reduce(0) {|acc, tx| acc += tx[:amount]} - deposits = txs.select {|tx| tx[:type] == "deposit"}.sort {|a,b| a[:formatted_date] <=> b[:formatted_date]} - sum_deposits = deposits.reduce(0) {|acc, tx| acc += tx[:amount]} + def transaction_totals(transactions, starting_balance) + withdrawals = transactions.select {|transaction| transaction[:type] == "withdrawal"}.sort {|a,b| a[:formatted_date] <=> b[:formatted_date]} + sum_withdrawals = withdrawals.reduce(0) {|acc, transaction| puts "transaction => #{transaction}, acc => #{acc}"; acc += transaction[:amount]} + + deposits = transactions.select {|transaction| transaction[:type] == "deposit"}.sort {|a,b| a[:formatted_date] <=> b[:formatted_date]} + sum_deposits = deposits.reduce(0) {|acc, transaction| puts "transaction => #{transaction}, acc => #{acc}"; acc += transaction[:amount]} ending_balance = starting_balance + sum_deposits - sum_withdrawals - + { summary: { starting_balance: starting_balance, @@ -252,44 +232,37 @@ def txs_totals(txs, starting_balance) deposits: deposits } end - - # ------------------------------------------------------------------------ - # calc statement from txs: - def calc_statement(txs) - statement = txs_totals txs, 0 - dates = txs.map {|tx| tx[:formatted_date]}.uniq.sort + def calc_statement(transactions) + statement = transactions_totals transactions, 0 + + dates = transactions.map {|transaction| transaction[:formatted_date]}.uniq.sort daily_balances = {} dates.each_with_index do |date, index| - txs_for_date = txs.select {|tx| tx[:formatted_date] == date} + transactions_for_date transactions.select {|transaction| transaction[:formatted_date] == date} starting_balance = if index == 0 - # first day, so use starting balance: statement[:summary][:starting_balance] else - # use ending balance of previous date: prev_date = dates[index-1] daily_balances[prev_date][:summary][:ending_balance] end - daily_balances[date] = txs_totals txs_for_date, starting_balance + daily_balances[date] = transactions_totals transactions_for_date, starting_balance end statement[:dates] = dates statement[:daily_balances] = daily_balances statement end - - # ------------------------------------------------------------------------ - # write html to file: + def write_html(html) File.open("assignment02-output.html", "w") do |file| file.write html end end - - # ------------------------------------------------------------------------ - txs = read_txs - statement = calc_statement txs + + transactions = read_transactions + statement = calc_statement transactions html = render_html statement write_html html nil -end +end \ No newline at end of file diff --git a/assignments/assignment03.rb b/assignments/assignment03.rb index ee5cd93..dfbe82f 100644 --- a/assignments/assignment03.rb +++ b/assignments/assignment03.rb @@ -4,37 +4,47 @@ # ======================================================================================== # Problem 1 - re-implement titleize, palindrome? - # re-implement titleize and palindrome? as methods on String -"hEllo WORLD".titleize #=> "Hello World" -"gooDbye CRUel wORLD".titleize #=> "Goodbye Cruel World" - -"abba".palindrome? #=> true -"aBbA".palindrome? #=> true -"abb".palindrome? #=> false - -"Able was I ere I saw elba".palindrome? #=> true -"A man, a plan, a canal, Panama".palindrome? #=> true - +class String + def titleize + word = self.split + title=[] + word.each do |words| + title << words.capitalize + end + title.join " " + end + + def palindrome? + inputstring = self.delete(" ").delete(",").downcase + inputstring == inputstring.reverse + end +end # ======================================================================================== # Problem 2 - re-implement mean, median, to_sentence - # re-implement mean, median, to_sentence as methods on Array - -# Your method should generate the following results: -[1, 2, 3].mean #=> 2 -[1, 1, 4].mean #=> 2 - -[1, 2, 3].median #=> 2 -[1, 1, 4].median #=> 1 - -[].to_sentence #=> "" -["john"].to_sentence #=> "john" -["john", "paul"].to_sentence #=> "john and paul" -[1, "paul", 3, "ringo"].to_sentence #=> "1, paul, 3 and ringo" - +class Array + def mean + self.reduce {|item, acc| acc + item} / self.length.to_f + end + + def median + middle = self.length / 2 + sorted = self.sort + self.length.odd? ? sorted[middle] : 0.5 * (sorted[middle] + sorted[middle - 1]) + end + + def to_sentence + unless (self.length < 2) + last_word = self.pop.to_s + sentence = (self.join ", ") << " and " << last_word + else + self.pop.to_s + end + end +end # ======================================================================================== # Problem 3 - re-implement bank statement diff --git a/assignments/assignment04.rb b/assignments/assignment04.rb deleted file mode 100644 index d2443a2..0000000 --- a/assignments/assignment04.rb +++ /dev/null @@ -1,112 +0,0 @@ -# ======================================================================================== -# Assignment 4 -# ======================================================================================== - -# ======================================================================================== -# Problem 1 - Fibonacci - -# 1, 1, 2, 3, 5, 8, 13, 21, ... - -# F[0] -> 1 -# F[1] -> 1 -# F[n] -> F[n-2] + F[n-1] - -def fib(n) - # your implementation here -end - -# expected behavior: -fib(0) #=> 1 -fib(1) #=> 1 -fib(5) #=> 8 -fib(4) #=> 5 -fib(12) #=> 233 - - -# ======================================================================================== -# Problem 2 - Queue - -# implement a Queue class that does not use Array. - -# expected behavior: -q = Queue.new -q.empty? #=> true -q.enqueue "first" -q.empty? #=> false -q.enqueue "second" -q.dequeue #=> "first" -q.dequeue #=> "second" -q.dequeue #=> nil - -class Queue - def initialize - # your implementation here - end - def enqueue(item) - # your implementation here - end - def dequeue - # your implementation here - end - def empty? - # your implementation here - end - def peek - # your implementation here - end - def length - # your implementation here - end -end - - -# ======================================================================================== -# Problem 3 - LinkedList - -# implement a LinkedList class that does not use Array. - -# expected behavior: -ll = LinkedList.new -ll.empty? #=> true - -ll << "first" -ll.empty? #=> false -ll.length #=> 1 -ll.first #=> "first" -ll.last #=> "first" - -ll << "second" -ll.length #=> 2 -ll.first #=> "first" -ll.last #=> "second" - -ll << "third" #=> 3 -ll.each {|x| puts x} #=> prints out "first", "second", "third" - -ll.delete "second" #=> "second" -ll.length #=> 2 -ll.each {|x| puts x} #=> prints out "first", "third" - -class LinkedList - def initialize - # your implementation here - end - def empty? - # your implementation here - end - def length - # your implementation here - end - def <<(item) - # your implementation here - end - def first - # your implementation here - end - def last - # your implementation here - end - def each(&block) - # your implementation here - end -end diff --git a/assignments/assignment04_solution.rb b/assignments/assignment04_solution.rb deleted file mode 100644 index 910866c..0000000 --- a/assignments/assignment04_solution.rb +++ /dev/null @@ -1,490 +0,0 @@ -# ======================================================================================== -# Assignment 4 -# ======================================================================================== - -require 'minitest/autorun' - - -module Assignment04 - - # ======================================================================================== - # Problem 1 - Fibonacci - - # 1, 1, 2, 3, 5, 8, 13, 21, ... - - # F[0] -> 1 - # F[1] -> 1 - # F[n] -> F[n-2] + F[n-1] - - def self.fib(n) - n < 2 ? 1 : fib(n-2)+fib(n-1) - end - - - - # ======================================================================================== - # Problem 2 - Queue - - # implement a Queue class that does not use Array. - class Queue - - class Node - attr_accessor :item, :link - def initialize(item, link) - @item = item - @link = link - end - def to_s - "[item => #{item}, link => #{link}]" - end - end - - def initialize - @nodes = nil - end - - def enqueue(item) - new_node = Node.new item, nil - - if empty? - @nodes = new_node - else - node = @nodes - while node.link - node = node.link - end - node.link = new_node - end - self - end - - def dequeue - node = @nodes - @nodes = node.nil? ? nil : node.link - node.nil? ? nil : node.item - end - - def empty? - @nodes.nil? - end - - def peek - @nodes.nil? ? nil : @nodes.item - end - - def length - return 0 if empty? - - node = @nodes - count = 1 - while node.link - count += 1 - node = node.link - end - count - end - end - - - # ======================================================================================== - # Problem 3 - LinkedList - - # implement a LinkedList class that does not use Array. - class LinkedList - - class Node - attr_accessor :item, :link - def initialize(item, link) - @item = item - @link = link - end - def to_s - "[item => #{item}, link => #{link}]" - end - end - - def initialize - @nodes = nil - end - - def empty? - @nodes.nil? - end - - def length - return 0 if empty? - - node = @nodes - count = 1 - while node.link - count += 1 - node = node.link - end - count - end - - def <<(item) - new_node = Node.new item, nil - - if empty? - @nodes = new_node - else - node = @nodes - while node.link - node = node.link - end - node.link = new_node - end - self - end - - def first - empty? ? nil : @nodes.item - end - - def last - return nil if empty? - - node = @nodes - while node.link - node = node.link - end - - node.item - end - - def delete(item) - return nil if empty? - - node = @nodes - if item == node.item - @nodes = node.link - return node.item - end - - while node.link - if item == node.link.item - node.link = node.link.link - return item - end - node = node.link - end - - nil - end - - def each(&block) - return if empty? - - node = @nodes - while node != nil - yield node.item - node = node.link - end - end - end - -end - - -# ======================================================================================== -require 'minitest/autorun' - -class TestAssignment04 < Minitest::Test - - def test_fib - assert_equal 1, Assignment04.fib(0) #=> 1 - assert_equal 1, Assignment04.fib(1) #=> 1 - assert_equal 8, Assignment04.fib(5) #=> 8 - assert_equal 5, Assignment04.fib(4) #=> 5 - assert_equal 233, Assignment04.fib(12) #=> 233 - end - - def test_queue - q = Assignment04::Queue.new - refute_nil q - assert_empty q #=> true - assert_equal 0, q.length - - assert_equal q, q.enqueue("first") - refute_empty q #=> true - assert_equal 1, q.length - assert_equal "first", q.peek - - assert_equal q, q.enqueue("second") - refute_empty q #=> true - assert_equal 2, q.length - assert_equal "first", q.peek - - assert_equal q, q.enqueue("third") - refute_empty q #=> true - assert_equal 3, q.length - assert_equal "first", q.peek - - assert_equal "first", q.dequeue #=> "first" - refute_empty q #=> true - assert_equal 2, q.length - assert_equal "second", q.peek - - assert_equal "second", q.dequeue #=> "second" - refute_empty q #=> true - assert_equal 1, q.length - assert_equal "third", q.peek - - assert_equal "third", q.dequeue #=> "second" - assert_empty q #=> true - assert_equal 0, q.length - - assert_nil q.dequeue #=> nil - end - - def test_linked_list - ll = Assignment04::LinkedList.new - refute_nil ll - assert_empty ll - assert_equal 0, ll.length - - assert_equal ll, ll << "first" - refute_empty ll - assert_equal 1, ll.length - assert_equal "first", ll.first - assert_equal "first", ll.last - - assert_equal ll, ll << "second" - refute_empty ll - assert_equal 2, ll.length - assert_equal "first", ll.first - assert_equal "second", ll.last - - assert_equal ll, ll << "third" - refute_empty ll - assert_equal 3, ll.length - assert_equal "first", ll.first - assert_equal "third", ll.last - - items = [] - ll.each {|item| items << item} - assert_equal ["first", "second", "third"], items - - assert_equal "second", ll.delete("second") - refute_empty ll - assert_equal 2, ll.length - assert_equal "first", ll.first - assert_equal "third", ll.last - - items = [] - ll.each {|item| items << item} - assert_equal ["first", "third"], items - end - - def test_linked_list_delete_only - ll = Assignment04::LinkedList.new - refute_nil ll - assert_empty ll - assert_equal 0, ll.length - assert_nil ll.first - assert_nil ll.last - - assert_equal ll, ll << "first" - refute_empty ll - assert_equal 1, ll.length - assert_equal "first", ll.first - assert_equal "first", ll.last - - assert_nil ll.delete("other") - refute_empty ll - assert_equal 1, ll.length - assert_equal "first", ll.first - assert_equal "first", ll.last - - assert_equal "first", ll.delete("first") - assert_empty ll - assert_equal 0, ll.length - assert_nil ll.first - assert_nil ll.last - end - - def test_linked_list_delete_first_of_two - ll = Assignment04::LinkedList.new - refute_nil ll - assert_empty ll - assert_equal 0, ll.length - assert_nil ll.first - assert_nil ll.last - - assert_equal ll, ll << "first" - refute_empty ll - assert_equal 1, ll.length - assert_equal "first", ll.first - assert_equal "first", ll.last - - assert_equal ll, ll << "second" - refute_empty ll - assert_equal 2, ll.length - assert_equal "first", ll.first - assert_equal "second", ll.last - - assert_nil ll.delete("other") - refute_empty ll - assert_equal 2, ll.length - assert_equal "first", ll.first - assert_equal "second", ll.last - - assert_equal "first", ll.delete("first") - refute_empty ll - assert_equal 1, ll.length - assert_equal "second", ll.first - assert_equal "second", ll.last - end - - def test_linked_list_delete_last_of_two - ll = Assignment04::LinkedList.new - refute_nil ll - assert_empty ll - assert_equal 0, ll.length - assert_nil ll.first - assert_nil ll.last - - assert_equal ll, ll << "first" - refute_empty ll - assert_equal 1, ll.length - assert_equal "first", ll.first - assert_equal "first", ll.last - - assert_equal ll, ll << "second" - refute_empty ll - assert_equal 2, ll.length - assert_equal "first", ll.first - assert_equal "second", ll.last - - assert_nil ll.delete("other") - refute_empty ll - assert_equal 2, ll.length - assert_equal "first", ll.first - assert_equal "second", ll.last - - assert_equal "second", ll.delete("second") - refute_empty ll - assert_equal 1, ll.length - assert_equal "first", ll.first - assert_equal "first", ll.last - end - - def test_linked_list_delete_first_of_three - ll = Assignment04::LinkedList.new - refute_nil ll - assert_empty ll - assert_equal 0, ll.length - assert_nil ll.first - assert_nil ll.last - - assert_equal ll, ll << "first" - refute_empty ll - assert_equal 1, ll.length - assert_equal "first", ll.first - assert_equal "first", ll.last - - assert_equal ll, ll << "second" - refute_empty ll - assert_equal 2, ll.length - assert_equal "first", ll.first - assert_equal "second", ll.last - - assert_equal ll, ll << "third" - refute_empty ll - assert_equal 3, ll.length - assert_equal "first", ll.first - assert_equal "third", ll.last - - assert_nil ll.delete("other") - refute_empty ll - assert_equal 3, ll.length - assert_equal "first", ll.first - assert_equal "third", ll.last - - assert_equal "first", ll.delete("first") - refute_empty ll - assert_equal 2, ll.length - assert_equal "second", ll.first - assert_equal "third", ll.last - end - - def test_linked_list_delete_middle_of_three - ll = Assignment04::LinkedList.new - refute_nil ll - assert_empty ll - assert_equal 0, ll.length - assert_nil ll.first - assert_nil ll.last - - assert_equal ll, ll << "first" - refute_empty ll - assert_equal 1, ll.length - assert_equal "first", ll.first - assert_equal "first", ll.last - - assert_equal ll, ll << "second" - refute_empty ll - assert_equal 2, ll.length - assert_equal "first", ll.first - assert_equal "second", ll.last - - assert_equal ll, ll << "third" - refute_empty ll - assert_equal 3, ll.length - assert_equal "first", ll.first - assert_equal "third", ll.last - - assert_nil ll.delete("other") - refute_empty ll - assert_equal 3, ll.length - assert_equal "first", ll.first - assert_equal "third", ll.last - - assert_equal "second", ll.delete("second") - refute_empty ll - assert_equal 2, ll.length - assert_equal "first", ll.first - assert_equal "third", ll.last - end - - def test_linked_list_delete_last_of_three - ll = Assignment04::LinkedList.new - refute_nil ll - assert_empty ll - assert_equal 0, ll.length - assert_nil ll.first - assert_nil ll.last - - assert_equal ll, ll << "first" - refute_empty ll - assert_equal 1, ll.length - assert_equal "first", ll.first - assert_equal "first", ll.last - - assert_equal ll, ll << "second" - refute_empty ll - assert_equal 2, ll.length - assert_equal "first", ll.first - assert_equal "second", ll.last - - assert_equal ll, ll << "third" - refute_empty ll - assert_equal 3, ll.length - assert_equal "first", ll.first - assert_equal "third", ll.last - - assert_nil ll.delete("other") - refute_empty ll - assert_equal 3, ll.length - assert_equal "first", ll.first - assert_equal "third", ll.last - - assert_equal "third", ll.delete("third") - refute_empty ll - assert_equal 2, ll.length - assert_equal "first", ll.first - assert_equal "second", ll.last - end - -end diff --git a/assignments/assignment05.rb b/assignments/assignment05.rb deleted file mode 100644 index 9e96ea4..0000000 --- a/assignments/assignment05.rb +++ /dev/null @@ -1,19 +0,0 @@ -# ======================================================================================== -# Assignment 5 -# ======================================================================================== - -# ======================================================================================== -# Problem 1 - implement prop_reader, write MiniTest unit tests - -# expected results: -class PropReader - prop_reader :flavor - def initialize(flavor) - @flavor = flavor - end -end - -obj = PropReader.new "spicy" -obj.respond_to? :flavor #=> true -obj.respond_to? :"flavor=" #=> false -obj.flavor #=> "spicy" diff --git a/assignments/assignment06.rb b/assignments/assignment06.rb index 9017e02..d7289fd 100644 --- a/assignments/assignment06.rb +++ b/assignments/assignment06.rb @@ -7,101 +7,227 @@ # implement a PriorityQueue, validate using MiniTest unit tests -class PriorityQueue - def initialize - # your implementation here - end - def enqueue(item, priority=:medium) - # your implementation here - end - def dequeue - # your implementation here - end - def empty? - # your implementation here - end - def peek - # your implementation here - end - def length - # your implementation here - end -end +module Assignment06 + class PriorityQueue + def initialize + @items = [] + end -# expected results: -pq = PriorityQueue.new -pq.empty? #=> true + def enqueue(item,priority=:medium) + new_item = [] + new_item << {item: item, priority: priority} -pq.enqueue "first" -pq.empty? #=> false + if @items.empty? + @items << {item: item, priority: priority} + @items.last[:item] + + elsif new_item.last[:priority] == :medium and @items.last[:priority] == :low + if @items.first[:priority] == :low + @items.unshift({item: item, priority: priority}) + @items.last[:item] + else + h = @items.rindex {|x| x[:priority] == :medium} + 1 + @items.insert(h, {item: item, priority: priority}) + @items.last[:item] + end + elsif new_item.last[:priority] == :high and @items.last[:priority] == :medium + if @items.first[:priority] == :medium + @items.unshift({item: item, priority: priority}) + @items.last[:item] + else + h = @items.rindex {|x| x[:priority] == :high} + 1 + @items.insert(h, {item: item, priority: priority}) + @items.last[:item] + end + elsif new_item.last[:priority] == :high and @items.last[:priority] == :low + if @items.first[:priority] == :low or @items.first[:priority] == :medium + @items.unshift({item: item, priority: priority}) + @items.last[:item] + else + h = @items.rindex {|x| x[:priority] == :high} + 1 + @items.insert(h, {item: item, priority: priority}) + @items.last[:item] + end + else + @items << {item: item, priority: priority} + @items.last[:item] + end + end + + def dequeue + @items.empty? ? nil : @items.shift[:item] + end -pq.enqueue "top", :high -pq.enqueue "last", :low -pq.enqueue "second" -pq.enqueue "another top", :high + def empty? + @items.empty? + end -pq.length #=> 5 + def peek + @items.first[:item] + end -pq.dequeue #=> "top" -pq.dequeue #=> "another top" -pq.dequeue #=> "first" -pq.dequeue #=> "second" -pq.dequeue #=> "last" + def length + @items.length + end + end + require 'minitest/autorun' + + class TestPriorityQueue < MiniTest::Test + def test_priorityqueue + pq = PriorityQueue.new + a = pq.empty? + assert_equal a, true + b = pq.length + assert_equal b, 0 + c = pq.enqueue "first" + assert_equal c, "first" + d = pq.length + assert_equal d, 1 + e = pq.empty? + assert_equal e, false + f = pq.peek + assert_equal f, "first" + pq.enqueue "top", :high + g = pq.peek + assert_equal g, "top" + h = pq.length + assert_equal h, 2 + pq.enqueue "last", :low + pq.enqueue "second" + pq.enqueue "another top", :high + j = pq.length + assert_equal j, 5 + k = pq.dequeue + assert_equal k, "top" + l = pq.length + assert_equal l, 4 + m = pq.dequeue + assert_equal m, "another top" + n = pq.dequeue + assert_equal n, "first" + o = pq.dequeue + assert_equal o, "second" + p = pq.dequeue + assert_equal p, "last" + q = pq.empty? + assert_equal q, true + r = pq.length + assert_equal r, 0 + end + end # ======================================================================================== # Problem 2 - Recipe to DSL # render a Recipe object to Recipe DSL - -class Recipe - attr_accessor :steps, :ingredients, :name, :category, :prep_time, :rating - def initialize(name) - @name = name - end + class Recipe + attr_accessor :steps, :ingredients, :name, :category, :prep_time, :rating + def initialize(name) + @name = name + end - def render_dsl - # your code here - end -end + def render_ingredients + <<-INGREDIENTS + ingredients do + #{ingredients.map {|i| "x \"#{i}\""}}.join "\n"} + end + INGREDIENTS + end -class RecipeBuilder - def recipe(name, &block) - @recipe = Recipe.new(name) - self.instance_eval &block - @recipe + def render_steps + <<-STEPS + steps do + #{steps.map {|s| "x \"#{s}\""}}.join "\n"} + end + STEPS + end + + def render_dsl + <<-RECIPE + recipe "#{name}" do + category "#{category}" + prep_time "#{prep_time}" + rating "#{rating}" + #{render_ingredients} + #{render_steps} + end + RECIPE + end end + + class RecipeBuilder + def recipe(name, &block) + @recipe = Recipe.new(name) + self.instance_eval &block + @recipe + end - def category(value) - @recipe.category = value - end + def category(value) + @recipe.category = value + end - def prep_time(value) - @recipe.prep_time = value - end + def prep_time(value) + @recipe.prep_time = value + end - def rating(value) - @recipe.rating = value - end + def rating(value) + @recipe.rating = value + end - def ingredients(&block) - @recipe.ingredients = [] - @items = @recipe.ingredients - self.instance_eval &block - end + def ingredients(&block) + @recipe.ingredients = [] + @items = @recipe.ingredients + self.instance_eval &block + end - def steps(&block) - @recipe.steps = [] - @items = @recipe.steps - self.instance_eval &block - end + def steps(&block) + @recipe.steps = [] + @items = @recipe.steps + self.instance_eval &block + end - def x(item) - @items << item + def x(item) + @items << item + end + end + + def recipe(name, &block) + rb = RecipeBuilder.new + rb.recipe(name, &block) end -end -def recipe(name, &block) - rb = RecipeBuilder.new - rb.recipe(name, &block) -end + require 'minitest/autorun' + + class TestRecipe < MiniTest::Test + def test_recipe + eggs = recipe "Scrambled Eggs" do + category "breakfast" + prep_time "10 minutes" + rating 4 + ingredients do + x "2 eggs" + x "1/4 cup of milk" + x "1 tbsp of butter" + x "dash of salt" + x "dash of pepper" + end + steps do + x "crack eggs into medium mixing bowl" + x "whisk eggs" + x "add milk" + x "add salt & pepper to taste" + x "heat pan to medium high heat" + x "melt butter in pan" + x "once hot, add eggs to pan" + end + end + assert_equal eggs.name, "Scrambled Eggs" + assert_equal eggs.steps, ["crack eggs into medium mixing bowl", "whisk eggs", "add milk", "add salt & pepper to taste", "heat pan to medium high heat", "melt butter in pan", "once hot, add eggs to pan"] + assert_equal eggs.ingredients, ["2 eggs", "1/4 cup of milk", "1 tbsp of butter", "dash of salt", "dash of pepper"] + assert_equal eggs.category, "breakfast" + assert_equal eggs.prep_time, "10 minutes" + assert_equal eggs.rating, 4 + end + end +end \ No newline at end of file diff --git a/assignments/assignment07.rb b/assignments/assignment07.rb index 5d86f95..64743ed 100644 --- a/assignments/assignment07.rb +++ b/assignments/assignment07.rb @@ -10,23 +10,42 @@ module Assignment07 module Observable - def add_observer(obj) - # your implementation here + + attr_accessor :state + + def add_observer(observer) + @observers ||= [] + @observers << observer unless @observers.include? observer end - def delete_observer(obj) - # your implementation here + + def delete_observer(observer) + @observers.delete(observer) unless @observers == nil end + def delete_observers - # your implementation here + @observers.clear unless @obervers == nil + end + + def count_observers + @observers.count end + def changed(new_state=true) - # your implementation here + @state = new_state end + def changed? - # your implementation here + @state unless @state == nil end + def notify_observers(*args) - # your implementation here + if @state == true + @observers.each do |observer| + observer.update(*args) + end + @state = false + end end + end -end +end \ No newline at end of file diff --git a/assignments/assignment08.rb b/assignments/assignment08.rb index 3d46269..8924aed 100644 --- a/assignments/assignment08.rb +++ b/assignments/assignment08.rb @@ -10,47 +10,442 @@ module Assignment08 class RomanNumeral - def initialize(i) - # your implementation here + def initialize(number) + @numeral = number + @rn = "" end def to_s - # your implementation here + if @numeral > 3999 + return "Number is too large to convert!" + elsif @numeral < 1 + return "Number cannot be converted!" + else while @numeral > 999 + @numeral = @numeral - 1000 + @rn << "M" + end + while @numeral > 899 + @numeral = @numeral - 900 + @rn << "CM" + end + while @numeral > 499 + @numeral = @numeral - 500 + @rn << "D" + end + while @numeral > 399 + @numeral = @numeral - 400 + @rn << "CD" + end + while @numeral > 99 + @numeral = @numeral - 100 + @rn << "C" + end + while @numeral > 89 + @numeral = @numeral - 90 + @rn << "XC" + end + while @numeral > 49 + @numeral = @numeral - 50 + @rn << "L" + end + while @numeral > 39 + @numeral = @numeral - 40 + @rn << "XL" + end + while @numeral > 9 + @numeral = @numeral - 10 + @rn << "X" + end + while @numeral > 8 + @numeral = @numeral - 9 + @rn << "IX" + end + while @numeral > 4 + @numeral = @numeral - 5 + @rn << "V" + end + while @numeral > 3 + @numeral = @numeral - 4 + @rn << "IV" + end + while @numeral > 0 + @numeral = @numeral - 1 + @rn << "I" + end + end + @rn end - + def to_i - # your implementation here + @rn = @numeral + if @rn == "" + return "No conversion is possible!" + elsif (@rn.delete "CDILMVX") != "" + return "That is not a valid roman numeral!" + else + rn = @rn.reverse + @numeral = 0 + return "That is not a valid roman numeral!" if rn.end_with?("MMMM") + while rn.end_with?("M") + @numeral += 1000 + rn.chop! + return @numeral if rn.empty? + end + if rn.end_with?("MC") + @numeral += 900 + rn.chop!.chop! + return "That is not a valid roman numeral!" if rn.end_with?("M") + return "That is not a valid roman numeral!" if rn.end_with?("D") + return "That is not a valid roman numeral!" if rn.end_with?("C") + return @numeral if rn.empty? + end + if rn.end_with?("D") + @numeral += 500 + rn.chop! + return "That is not a valid roman numeral!" if rn.end_with?("M") + return "That is not a valid roman numeral!" if rn.end_with?("D") + return @numeral if rn.empty? + end + if rn.end_with?("DC") + @numeral += 400 + rn.chop!.chop! + return "That is not a valid roman numeral!" if rn.end_with?("M") + return "That is not a valid roman numeral!" if rn.end_with?("D") + return "That is not a valid roman numeral!" if rn.end_with?("C") + return @numeral if rn.empty? + end + return "That is not a valid roman numeral!" if rn.end_with?("CCCC") + while rn.end_with?("C") + @numeral += 100 + rn.chop! + return "That is not a valid roman numeral!" if rn.end_with?("M") + return "That is not a valid roman numeral!" if rn.end_with?("D") + return @numeral if rn.empty? + end + if rn.end_with?("CX") + @numeral += 90 + rn.chop!.chop! + return "That is not a valid roman numeral!" if rn.end_with?("M") + return "That is not a valid roman numeral!" if rn.end_with?("D") + return "That is not a valid roman numeral!" if rn.end_with?("C") + return "That is not a valid roman numeral!" if rn.end_with?("L") + return "That is not a valid roman numeral!" if rn.end_with?("X") + return @numeral if rn.empty? + end + if rn.end_with?("L") + @numeral += 50 + rn.chop! + return "That is not a valid roman numeral!" if rn.end_with?("M") + return "That is not a valid roman numeral!" if rn.end_with?("D") + return "That is not a valid roman numeral!" if rn.end_with?("C") + return "That is not a valid roman numeral!" if rn.end_with?("L") + return @numeral if rn.empty? + end + if rn.end_with?("LX") + @numeral += 40 + rn.chop!.chop! + return "That is not a valid roman numeral!" if rn.end_with?("M") + return "That is not a valid roman numeral!" if rn.end_with?("D") + return "That is not a valid roman numeral!" if rn.end_with?("C") + return "That is not a valid roman numeral!" if rn.end_with?("L") + return "That is not a valid roman numeral!" if rn.end_with?("X") + return @numeral if rn.empty? + end + return "That is not a valid roman numeral!" if rn.end_with?("XXXX") + while rn.end_with?("X") + @numeral += 10 + rn.chop! + return "That is not a valid roman numeral!" if rn.end_with?("M") + return "That is not a valid roman numeral!" if rn.end_with?("D") + return "That is not a valid roman numeral!" if rn.end_with?("C") + return "That is not a valid roman numeral!" if rn.end_with?("L") + return @numeral if rn.empty? + end + if rn.end_with?("XI") + @numeral += 9 + rn.chop!.chop! + return @numeral if rn.empty? + return "That is not a valid roman numeral!" + end + if rn.end_with?("V") + @numeral += 5 + rn.chop! + return "That is not a valid roman numeral!" if rn.end_with?("M") + return "That is not a valid roman numeral!" if rn.end_with?("D") + return "That is not a valid roman numeral!" if rn.end_with?("C") + return "That is not a valid roman numeral!" if rn.end_with?("L") + return "That is not a valid roman numeral!" if rn.end_with?("X") + return "That is not a valid roman numeral!" if rn.end_with?("V") + return @numeral if rn.empty? + end + if rn.end_with?("VI") + @numeral += 4 + rn.chop!.chop! + return @numeral if rn.empty? + return "That is not a valid roman numeral!" + end + return "That is not a valid roman numeral!" if rn.end_with?("IIII") + while rn.end_with?("I") + @numeral += 1 + rn.chop! + return "That is not a valid roman numeral!" if rn.end_with?("M") + return "That is not a valid roman numeral!" if rn.end_with?("D") + return "That is not a valid roman numeral!" if rn.end_with?("C") + return "That is not a valid roman numeral!" if rn.end_with?("L") + return "That is not a valid roman numeral!" if rn.end_with?("X") + return "That is not a valid roman numeral!" if rn.end_with?("V") + return @numeral if rn.empty? + end + @numeral + end end # bonus: create from Roman Numeral - def self.from_string - # your implementation here - # returns a new instance + def self.from_string(roman_numeral) + RomanNumeral.new(roman_numeral) end end -end -# expected results: -RomanNumeral.new(1).to_s # => 'I' -RomanNumeral.new(2).to_s # => 'II' -RomanNumeral.new(3).to_s # => 'III' -RomanNumeral.new(4).to_s # => 'IV' -RomanNumeral.new(5).to_s # => 'V' -RomanNumeral.new(6).to_s # => 'VI' -RomanNumeral.new(9).to_s # => 'IX' -RomanNumeral.new(10).to_s # => 'X' -RomanNumeral.new(19).to_s # => 'XIX' -RomanNumeral.new(32).to_s # => 'XXXII' -RomanNumeral.new(51).to_s # => 'LI' -# bonus: -RomanNumeral.from_string('III').to_i # => 3 -RomanNumeral.from_string('IX').to_i # => 9 -RomanNumeral.from_string('IX').to_i # => 9 +require 'minitest/autorun' + + class TestRomanNumeral < MiniTest::Test + def test_romannumeraltostring + a = RomanNumeral.new(1).to_s + assert_equal a, "I" + b = RomanNumeral.new(2).to_s + assert_equal b, "II" + c = RomanNumeral.new(3).to_s + assert_equal c, "III" + d = RomanNumeral.new(4).to_s + assert_equal d, "IV" + e = RomanNumeral.new(5).to_s + assert_equal e, "V" + f = RomanNumeral.new(6).to_s + assert_equal f, "VI" + g = RomanNumeral.new(9).to_s + assert_equal g, "IX" + h = RomanNumeral.new(10).to_s + assert_equal h, "X" + i = RomanNumeral.new(19).to_s + assert_equal i, "XIX" + j = RomanNumeral.new(32).to_s + assert_equal j, "XXXII" + k = RomanNumeral.new(40).to_s + assert_equal k, "XL" + l = RomanNumeral.new(49).to_s + assert_equal l, "XLIX" + m = RomanNumeral.new(50).to_s + assert_equal m, "L" + n = RomanNumeral.new(89).to_s + assert_equal n, "LXXXIX" + o = RomanNumeral.new(90).to_s + assert_equal o, "XC" + p = RomanNumeral.new(100).to_s + assert_equal p, "C" + q = RomanNumeral.new(399).to_s + assert_equal q, "CCCXCIX" + r = RomanNumeral.new(400).to_s + assert_equal r, "CD" + s = RomanNumeral.new(499).to_s + assert_equal s, "CDXCIX" + t = RomanNumeral.new(500).to_s + assert_equal t, "D" + u = RomanNumeral.new(899).to_s + assert_equal u, "DCCCXCIX" + v = RomanNumeral.new(900).to_s + assert_equal v, "CM" + w = RomanNumeral.new(999).to_s + assert_equal w, "CMXCIX" + x = RomanNumeral.new(1000).to_s + assert_equal x, "M" + y = RomanNumeral.new(1399).to_s + assert_equal y, "MCCCXCIX" + z = RomanNumeral.new(1400).to_s + assert_equal z, "MCD" + aa = RomanNumeral.new(1899).to_s + assert_equal aa, "MDCCCXCIX" + ab = RomanNumeral.new(1900).to_s + assert_equal ab, "MCM" + ac = RomanNumeral.new(1999).to_s + assert_equal ac, "MCMXCIX" + ad = RomanNumeral.new(2000).to_s + assert_equal ad, "MM" + ae = RomanNumeral.new(2999).to_s + assert_equal ae, "MMCMXCIX" + af = RomanNumeral.new(3999).to_s + assert_equal af, "MMMCMXCIX" + ag = RomanNumeral.new(4000).to_s + assert_equal ag, "Number is too large to convert!" + bo = RomanNumeral.new(0).to_s + assert_equal bo, "Number cannot be converted!" + end -# given any arbitrary integer n: -n == RomanNumeral.from_string(RomanNumeral.new(n).to_s).to_i + def test_romannumeraltointeger + ah = RomanNumeral.from_string("I").to_i + assert_equal ah, 1 + ai = RomanNumeral.from_string("II").to_i + assert_equal ai, 2 + aj = RomanNumeral.from_string("III").to_i + assert_equal aj, 3 + ak = RomanNumeral.from_string("IV").to_i + assert_equal ak, 4 + al = RomanNumeral.from_string("V").to_i + assert_equal al, 5 + am = RomanNumeral.from_string("VI").to_i + assert_equal am, 6 + an = RomanNumeral.from_string("IX").to_i + assert_equal an, 9 + ao = RomanNumeral.from_string("X").to_i + assert_equal ao, 10 + ap = RomanNumeral.from_string("XIX").to_i + assert_equal ap, 19 + aq = RomanNumeral.from_string("XXXII").to_i + assert_equal aq, 32 + ar = RomanNumeral.from_string("XL").to_i + assert_equal ar, 40 + as = RomanNumeral.from_string("XLIX").to_i + assert_equal as, 49 + at = RomanNumeral.from_string("L").to_i + assert_equal at, 50 + au = RomanNumeral.from_string("LXXXIX").to_i + assert_equal au, 89 + av = RomanNumeral.from_string("XC").to_i + assert_equal av, 90 + aw = RomanNumeral.from_string("C").to_i + assert_equal aw, 100 + ax = RomanNumeral.from_string("CCCXCIX").to_i + assert_equal ax, 399 + ay = RomanNumeral.from_string("CD").to_i + assert_equal ay, 400 + az = RomanNumeral.from_string("CDXCIX").to_i + assert_equal az, 499 + ba = RomanNumeral.from_string("D").to_i + assert_equal ba, 500 + bb = RomanNumeral.from_string("DCCCXCIX").to_i + assert_equal bb, 899 + bc = RomanNumeral.from_string("CM").to_i + assert_equal bc, 900 + bd = RomanNumeral.from_string("CMXCIX").to_i + assert_equal bd, 999 + be = RomanNumeral.from_string("M").to_i + assert_equal be, 1000 + bf = RomanNumeral.from_string("MCCCXCIX").to_i + assert_equal bf, 1399 + bg = RomanNumeral.from_string("MCD").to_i + assert_equal bg, 1400 + bh = RomanNumeral.from_string("MDCCCXCIX").to_i + assert_equal bh, 1899 + bi = RomanNumeral.from_string("MCM").to_i + assert_equal bi, 1900 + bj = RomanNumeral.from_string("MCMXCIX").to_i + assert_equal bj, 1999 + bk = RomanNumeral.from_string("MM").to_i + assert_equal bk, 2000 + bl = RomanNumeral.from_string("MMCMXCIX").to_i + assert_equal bl, 2999 + bm = RomanNumeral.from_string("MMMCMXCIX").to_i + assert_equal bm, 3999 + bn = RomanNumeral.from_string("MMMM").to_i + assert_equal bn, "That is not a valid roman numeral!" + bq = RomanNumeral.from_string("MCMM").to_i + assert_equal bq, "That is not a valid roman numeral!" + br = RomanNumeral.from_string("MCMD").to_i + assert_equal br, "That is not a valid roman numeral!" + bs = RomanNumeral.from_string("MCMC").to_i + assert_equal bs, "That is not a valid roman numeral!" + bt = RomanNumeral.from_string("DM").to_i + assert_equal bt, "That is not a valid roman numeral!" + bu = RomanNumeral.from_string("DD").to_i + assert_equal bu, "That is not a valid roman numeral!" + bv = RomanNumeral.from_string("CDM").to_i + assert_equal bv, "That is not a valid roman numeral!" + bw = RomanNumeral.from_string("CDD").to_i + assert_equal bw, "That is not a valid roman numeral!" + bx = RomanNumeral.from_string("CDC").to_i + assert_equal bx, "That is not a valid roman numeral!" + by = RomanNumeral.from_string("CCCC").to_i + assert_equal by, "That is not a valid roman numeral!" + bz = RomanNumeral.from_string("CMCM").to_i + assert_equal bz, "That is not a valid roman numeral!" + ca = RomanNumeral.from_string("CMCD").to_i + assert_equal ca, "That is not a valid roman numeral!" + cb = RomanNumeral.from_string("XCM").to_i + assert_equal cb, "That is not a valid roman numeral!" + cc = RomanNumeral.from_string("XCD").to_i + assert_equal cc, "That is not a valid roman numeral!" + cd = RomanNumeral.from_string("XCC").to_i + assert_equal cd, "That is not a valid roman numeral!" + ce = RomanNumeral.from_string("XCL").to_i + assert_equal ce, "That is not a valid roman numeral!" + cf = RomanNumeral.from_string("XCX").to_i + assert_equal cf, "That is not a valid roman numeral!" + cg = RomanNumeral.from_string("LM").to_i + assert_equal cg, "That is not a valid roman numeral!" + ch = RomanNumeral.from_string("LD").to_i + assert_equal ch, "That is not a valid roman numeral!" + ci = RomanNumeral.from_string("LC").to_i + assert_equal ci, "That is not a valid roman numeral!" + cj = RomanNumeral.from_string("LL").to_i + assert_equal cj, "That is not a valid roman numeral!" + ck = RomanNumeral.from_string("XLM").to_i + assert_equal ck, "That is not a valid roman numeral!" + cl = RomanNumeral.from_string("XLD").to_i + assert_equal cl, "That is not a valid roman numeral!" + cm = RomanNumeral.from_string("XLC").to_i + assert_equal cm, "That is not a valid roman numeral!" + cn = RomanNumeral.from_string("XLL").to_i + assert_equal cn, "That is not a valid roman numeral!" + co = RomanNumeral.from_string("XLX").to_i + assert_equal co, "That is not a valid roman numeral!" + cp = RomanNumeral.from_string("XXXX").to_i + assert_equal cp, "That is not a valid roman numeral!" + cq = RomanNumeral.from_string("XM").to_i + assert_equal cq, "That is not a valid roman numeral!" + cr = RomanNumeral.from_string("XD").to_i + assert_equal cr, "That is not a valid roman numeral!" + cs = RomanNumeral.from_string("XLXC").to_i + assert_equal cs, "That is not a valid roman numeral!" + ct = RomanNumeral.from_string("XLXL").to_i + assert_equal ct, "That is not a valid roman numeral!" + cu = RomanNumeral.from_string("IXM").to_i + assert_equal cu, "That is not a valid roman numeral!" + cv = RomanNumeral.from_string("IXD").to_i + assert_equal cv, "That is not a valid roman numeral!" + cw = RomanNumeral.from_string("IXC").to_i + assert_equal cw, "That is not a valid roman numeral!" + cx = RomanNumeral.from_string("IXL").to_i + assert_equal cx, "That is not a valid roman numeral!" + cy = RomanNumeral.from_string("IXX").to_i + assert_equal cy, "That is not a valid roman numeral!" + cz = RomanNumeral.from_string("IXV").to_i + assert_equal cz, "That is not a valid roman numeral!" + da = RomanNumeral.from_string("IVI").to_i + assert_equal da, "That is not a valid roman numeral!" + db = RomanNumeral.from_string("IIII").to_i + assert_equal db, "That is not a valid roman numeral!" + dc = RomanNumeral.from_string("IM").to_i + assert_equal dc, "That is not a valid roman numeral!" + dd = RomanNumeral.from_string("ID").to_i + assert_equal dd, "That is not a valid roman numeral!" + de = RomanNumeral.from_string("ID").to_i + assert_equal de, "That is not a valid roman numeral!" + df = RomanNumeral.from_string("IC").to_i + assert_equal df, "That is not a valid roman numeral!" + dg = RomanNumeral.from_string("IL").to_i + assert_equal dg, "That is not a valid roman numeral!" + dh = RomanNumeral.from_string("IXI").to_i + assert_equal dh, "That is not a valid roman numeral!" + di = RomanNumeral.from_string("IVIV").to_i + assert_equal di, "That is not a valid roman numeral!" + end + def test_romannumeralfromstring + bp = RomanNumeral.from_string("IX") + assert_instance_of RomanNumeral, bp + end + end +#end # ======================================================================================== @@ -60,13 +455,61 @@ def self.from_string # calculate the golden ratio up to specified precision # validate using MiniTest unit tests -module Assignment08 +#module Assignment08 def golden_ratio(precision) - # your implementation here + x = fib(99)/fib(98).to_f + x.round(precision) end -end + def fib(n) + def calc_fib(n, cache) + if cache.length > n + cache[n] + else + cache[n] = calc_fib(n-1, cache) + calc_fib(n-2, cache) + end + end + calc_fib(n, [1,1]) + end + +require 'minitest/autorun' -# expected results: -golden_ratio(2) # => 1.62 -golden_ratio(5) # => 1.61803 -golden_ratio(8) # => 1.61803399 + class TestGoldenRatio < MiniTest::Test + def test_goldenratio + a = golden_ratio(0) + assert_equal a, 2 + b = golden_ratio(1) + assert_equal b, 1.6 + c = golden_ratio(2) + assert_equal c, 1.62 + d = golden_ratio(3) + assert_equal d, 1.618 + e = golden_ratio(4) + assert_equal e, 1.618 + f = golden_ratio(5) + assert_equal f, 1.61803 + g = golden_ratio(6) + assert_equal g, 1.618034 + h = golden_ratio(7) + assert_equal h, 1.618034 + i = golden_ratio(8) + assert_equal i, 1.61803399 + j = golden_ratio(9) + assert_equal j, 1.618033989 + k = golden_ratio(10) + assert_equal k, 1.6180339887 + l = golden_ratio(11) + assert_equal l, 1.61803398875 + m = golden_ratio(12) + assert_equal m, 1.61803398875 + n = golden_ratio(13) + assert_equal n, 1.6180339887499 + o = golden_ratio(14) + assert_equal o, 1.6180339887499 + p = golden_ratio(15) + assert_equal p, 1.618033988749895 + q = golden_ratio(15) + assert_equal q, 1.618033988749895 + + end + end +end diff --git a/assignments/final_project.rb b/assignments/final_project.rb deleted file mode 100644 index a621230..0000000 --- a/assignments/final_project.rb +++ /dev/null @@ -1,75 +0,0 @@ -# ======================================================================================== -# Final Project: Game of Life -# ======================================================================================== - -# The Game of Life is a simplified model of evolution and natural selection -# invented by the mathematician James Conway. - -# http://en.wikipedia.org/wiki/Conway's_Game_of_Life - - -# --------------------------------------------------------------------------------------- -# Rules - -# You have a grid of cells in 2 dimensions. - -# Each cell has 8 neighbors: -# - top, right, bottom, left -# - top-left, top-right, bottom-right, bottom-left - -# Each cell has 2 possible states: alive or dead. - -# if a cell is alive and -# - has fewer than 2 live neighbors, it dies -# - has more than 3 live neighbors, it dies -# - has 2 or 3 live neighbors, it lives to next generation - -# if cell is dead and -# - has exactly 3 live neighbors, it becomes a live cell - -# edges of board: -# - pretend the board is folded onto itself -# - the edges touch each other - - -# --------------------------------------------------------------------------------------- -# Tests - -# You must have MiniTest unit tests for your class to validate your implementation. -# You might need to add methods or change the method signatures to enable testing. - - -# --------------------------------------------------------------------------------------- -# Rendering - -# You choose how you want to render the current state of the board. -# ASCII? HTML? Something else? - - -# --------------------------------------------------------------------------------------- -# Bonus: DSL - -# - Create a DSL that represents a state of the game. -# - Your render method can then be formatted as the DSL, so that you can round-trip -# between the textual DSL representation and the running instance. - - -# --------------------------------------------------------------------------------------- -# Suggested Implementation - -module FinalProject - class GameOfLife - def initialize(size) - # randomly initialize the board - end - def evolve - # apply rules to each cell and generate new state - end - def render - # render the current state of the board - end - def run(num_generations) - # evolve and render for num_generations - end - end -end diff --git a/assignments/final_project_with_tests.rb b/assignments/final_project_with_tests.rb new file mode 100644 index 0000000..c62931f --- /dev/null +++ b/assignments/final_project_with_tests.rb @@ -0,0 +1,414 @@ +# ======================================================================================== +# Final Project: Game of Life +# ======================================================================================== + +# The Game of Life is a simplified model of evolution and natural selection +# invented by the mathematician James Conway. + +# http://en.wikipedia.org/wiki/Conway's_Game_of_Life + + +# --------------------------------------------------------------------------------------- +# Rules + +# You have a grid of cells in 2 dimensions. + +# Each cell has 8 neighbors: +# - top, right, bottom, left +# - top-left, top-right, bottom-right, bottom-left + +# Each cell has 2 possible states: alive or dead. + +# if a cell is alive and +# - has fewer than 2 live neighbors, it dies +# - has more than 3 live neighbors, it dies +# - has 2 or 3 live neighbors, it lives to next generation + +# if cell is dead and +# - has exactly 3 live neighbors, it becomes a live cell + +# edges of board: +# - pretend the board is folded onto itself +# - the edges touch each other + + +# --------------------------------------------------------------------------------------- +# Tests + +# You must have MiniTest unit tests for your class to validate your implementation. +# You might need to add methods or change the method signatures to enable testing. + + +# --------------------------------------------------------------------------------------- +# Rendering + +# You choose how you want to render the current state of the board. +# ASCII? HTML? Something else? + + +# --------------------------------------------------------------------------------------- +# Bonus: DSL + +# - Create a DSL that represents a state of the game. +# - Your render method can then be formatted as the DSL, so that you can round-trip +# between the textual DSL representation and the running instance. + + +# --------------------------------------------------------------------------------------- +# Suggested Implementation + +#module FinalProject + class GameOfLife + attr_accessor :gameboard, :seeds + def initialize(gameboard = GameBoard.new, seeds=[]) + @gameboard = gameboard + @seeds = seeds + + seeds.each do |seed| + gameboard.board[seed[0]][seed[1]].is_alive = true + end + end + + def evolve! + + cell_is_dead_in_next_state = [] + cell_is_alive_in_next_state = [] + + gameboard.cells.each do |cell| + #Rule #1 + if cell.is_alive? && gameboard.neighbors(cell).count < 2 + cell_is_dead_in_next_state << cell + end + #Rule #2 + if cell.is_alive? && gameboard.neighbors(cell).count > 3 + cell_is_dead_in_next_state << cell + end + #Rule #3 + if cell.is_alive? && gameboard.neighbors(cell).count == 2 + cell_is_alive_in_next_state << cell + end + + if cell.is_alive? && gameboard.neighbors(cell).count == 3 + cell_is_alive_in_next_state << cell + end + #Rule #4 + if !cell.is_alive? && gameboard.neighbors(cell).count == 3 + cell_is_alive_in_next_state << cell + end + end + + cell_is_dead_in_next_state.each do |cell| + cell.kill_cell! + end + cell_is_alive_in_next_state.each do |cell| + cell.resurrect! + end + end + end + + class GameBoard + attr_accessor :rows, :columns, :board, :cells + + def initialize(rows=3, columns=3) + @rows = rows + @columns = columns + @cells = [] + @board = Array.new(rows) do |row| + Array.new(columns) do |column| + cell = Cell.new(column,row) + cells << cell + cell + end + end + end + + def neighbors(cell) + neighbors = [] + + #northeast neighbor + if cell.x_pos < (columns - 1) && cell.y_pos > 0 + neighbor = self.board[cell.y_pos - 1][cell.x_pos + 1] + neighbors << neighbor if neighbor.is_alive? + elsif cell.x_pos < (columns - 1) && cell.y_pos == 0 + neighbor = self.board[cell.y_pos + (self.rows - 1)][cell.x_pos + 1] + neighbors << neighbor if neighbor.is_alive? + elsif cell.x_pos == (columns - 1) && cell.y_pos > 0 + neighbor = self.board[cell.y_pos - 1][0] + neighbors << neighbor if neighbor.is_alive? + else + neighbor = self.board[cell.y_pos + (self.rows - 1)][0] + neighbors << neighbor if neighbor.is_alive? + end + + #southeast neighbor + if cell.x_pos < (columns - 1) && cell.y_pos < (rows - 1) + neighbor = self.board[cell.y_pos + 1][cell.x_pos + 1] + neighbors << neighbor if neighbor.is_alive? + elsif cell.x_pos < (columns - 1) && cell.y_pos == (rows - 1) + neighbor = self.board[0][cell.x_pos + 1] + neighbors << neighbor if neighbor.is_alive? + elsif cell.x_pos == (columns - 1) && cell.y_pos < (rows - 1) + neighbor = self.board[cell.y_pos + 1][0] + neighbors << neighbor if neighbor.is_alive? + else + neighbor = self.board[0][0] + neighbors << neighbor if neighbor.is_alive? + end + + #southwest neighbor + if cell.x_pos > 0 && cell.y_pos < (rows - 1) + neighbor = self.board[cell.y_pos + 1][cell.x_pos - 1] + neighbors << neighbor if neighbor.is_alive? + elsif cell.x_pos > 0 && cell.y_pos == (rows - 1) + neighbor = self.board[0][cell.x_pos - 1] + neighbors << neighbor if neighbor.is_alive? + elsif cell.x_pos == 0 && cell.y_pos < (rows - 1) + neighbor = self.board[cell.y_pos + 1][cell.x_pos + (self.columns - 1)] + neighbors << neighbor if neighbor.is_alive? + else + neighbor = self.board[0][cell.x_pos + (self.columns - 1)] + neighbors << neighbor if neighbor.is_alive? + end + + #northwest neighbor + if cell.x_pos > 0 && cell.y_pos > 0 + neighbor = self.board[cell.y_pos - 1][cell.x_pos - 1] + neighbors << neighbor if neighbor.is_alive? + elsif cell.x_pos > 0 && cell.y_pos == 0 + neighbor = self.board[cell.y_pos + (self.rows - 1)][cell.x_pos - 1] + neighbors << neighbor if neighbor.is_alive? + elsif cell.x_pos == 0 && cell.y_pos > 0 + neighbor = self.board[cell.y_pos - 1][cell.x_pos + (self.columns - 1)] + neighbors << neighbor if neighbor.is_alive? + else + neighbor = self.board[cell.y_pos + (self.rows - 1)][cell.x_pos + (self.columns - 1)] + neighbors << neighbor if neighbor.is_alive? + end + + #north neighbor + if cell.y_pos > 0 + neighbor = self.board[cell.y_pos - 1][cell.x_pos] + neighbors << neighbor if neighbor.is_alive? + else + neighbor = self.board[cell.y_pos + (self.rows - 1)][cell.x_pos] + neighbors << neighbor if neighbor.is_alive? + end + + #east neighbor + if cell.x_pos < (columns - 1) + neighbor = self.board[cell.y_pos][cell.x_pos + 1] + neighbors << neighbor if neighbor.is_alive? + else + neighbor = self.board[cell.y_pos][0] + neighbors << neighbor if neighbor.is_alive? + end + + #south neighbor + if cell.y_pos < (rows - 1) + neighbor = self.board[cell.y_pos + 1][cell.x_pos] + neighbors << neighbor if neighbor.is_alive? + else + neighbor = self.board[0][cell.x_pos] + neighbors << neighbor if neighbor.is_alive? + end + + #west_neighbor + if cell.x_pos > 0 + neighbor = self.board[cell.y_pos][cell.x_pos - 1] + neighbors << neighbor if neighbor.is_alive? + else + neighbor = self.board[cell.y_pos][cell.x_pos + (self.columns - 1)] + neighbors << neighbor if neighbor.is_alive? + end + + neighbors + end + + def live_cells + cells.select{|cell| cell.is_alive?} + end + + def randomly_populate + cells.each do |cell| + cell.is_alive = [true, false].sample + end + end + + end + + class Cell + attr_accessor :x_pos, :y_pos, :is_alive + + def initialize(xpos=0, ypos=0) + @x_pos = xpos + @y_pos = ypos + @is_alive = false + end + + def is_alive? + is_alive + end + + def kill_cell! + @is_alive = false + end + + def resurrect! + @is_alive = true + end + end + + require 'gosu' + + class GameOfLifeWindow < Gosu::Window + + def initialize(height=800, width=600) + @height = height + @width = width + super height, width, false + self.caption = "Conway's Game Of Life" + + @background_color = Gosu::Color.new(0xffdedede) + @cell_color = Gosu::Color.new(0xff121212) + @blank_color = Gosu::Color.new(0xffededed) + + #game + @columns = width / 10 + @rows = height / 10 + @column_width = width / @columns + @row_height = height / @rows + @gameboard = GameBoard.new(@columns, @rows) + @game = GameOfLife.new(@gameboard) + @game.gameboard.randomly_populate + end + + def update + @game.evolve! + end + + def draw + draw_quad(0, 0, @background_color, + width, 0, @background_color, + width, height, @background_color, + 0, height, @background_color) + + @game.gameboard.cells.each do |cell| + + if cell.is_alive? + draw_quad(cell.x_pos * @column_width, cell.y_pos * @row_height, @cell_color, + cell.x_pos * @column_width + (@column_width - 1), cell.y_pos * @row_height, @cell_color, + cell.x_pos * @column_width + (@column_width - 1), cell.y_pos * @row_height + (@row_height - 1), @cell_color, + cell.x_pos * @column_width, cell.y_pos * @row_height + (@row_height - 1), @cell_color) + + else + draw_quad(cell.x_pos * @column_width, cell.y_pos * @row_height, @blank_color, + cell.x_pos * @column_width + (@column_width - 1), cell.y_pos * @row_height, @blank_color, + cell.x_pos * @column_width + (@column_width - 1), cell.y_pos * @row_height + (@row_height - 1), @blank_color, + cell.x_pos * @column_width, cell.y_pos * @row_height + (@row_height - 1), @blank_color) + end + end + end + + def needs_cursor? + true + end + + + end + + GameOfLifeWindow.new.show + + require 'minitest/autorun' + + class TestGameOfLife < Minitest::Test + + def test_GameBoard + a = GameBoard.new + assert_instance_of GameBoard, a + assert_respond_to a, :rows + assert_respond_to a, :columns + assert_respond_to a, :board + assert_respond_to a, :neighbors + assert_respond_to a, :cells + assert_respond_to a, :randomly_populate + assert_respond_to a, :live_cells + assert_instance_of Array, a.board + a.board.each do |row| + assert_instance_of Array, row + row.each do |column| + assert_instance_of Cell, column + end + end + + assert_equal 9, a.cells.count + + a.cells.each do |cell| + assert_equal false, cell.is_alive? + end + + assert_equal 0, a.live_cells.count + a.randomly_populate + refute_equal 0, a.live_cells.count + end + + def test_Cell + b = Cell.new + assert_instance_of Cell, b + assert_respond_to b, :is_alive + assert_equal false, b.is_alive + assert_respond_to b, :x_pos + assert_respond_to b, :y_pos + assert_respond_to b, :kill_cell! + assert_respond_to b, :resurrect! + assert_equal b.x_pos, 0 + assert_equal b.y_pos, 0 + end + + def test_GameOfLife + c = GameOfLife.new + assert_instance_of GameOfLife, c + assert_respond_to c, :gameboard + assert_respond_to c, :seeds + assert_instance_of GameBoard, c.gameboard + assert_instance_of Array, c.seeds + + d = GameOfLife.new(GameBoard.new, [[1,2], [0,2]]) + assert_equal true, d.gameboard.board[1][2].is_alive? + assert_equal true, d.gameboard.board[0][2].is_alive? + + e = GameOfLife.new(GameBoard.new, [[1,0], [2,0]]) + e.evolve! + assert_equal false, e.gameboard.board[1][0].is_alive? + assert_equal false, e.gameboard.board[2][0].is_alive? + + f = GameOfLife.new(GameBoard.new, [[0,1], [1,1], [2,1]]) + assert_equal 2, f.gameboard.neighbors(f.gameboard.board[1][1]).count + assert_equal 2, f.gameboard.neighbors(f.gameboard.board[0][1]).count + assert_equal true, f.gameboard.board[1][1].is_alive? + f.evolve! + assert_equal true, f.gameboard.board[0][1].is_alive? + assert_equal true, f.gameboard.board[1][1].is_alive? + assert_equal true, f.gameboard.board[2][1].is_alive? + + g = GameOfLife.new(GameBoard.new, [[0,1], [1,1], [2,1], [2,2]]) + assert_equal 3, g.gameboard.neighbors(g.gameboard.board[1][1]).count + assert_equal true, g.gameboard.board[1][1].is_alive? + g.evolve! + assert_equal false, g.gameboard.board[0][1].is_alive? + assert_equal true, g.gameboard.board[1][1].is_alive? + assert_equal true, g.gameboard.board[2][1].is_alive? + assert_equal true, g.gameboard.board[2][2].is_alive? + + h = GameOfLife.new(GameBoard.new, [[0,1], [1,1], [2,1], [2,2], [1,2]]) + assert_equal 4, h.gameboard.neighbors(h.gameboard.board[1][1]).count + assert_equal true, h.gameboard.board[2][2].is_alive? + assert_equal 3, h.gameboard.neighbors(h.gameboard.board[2][2]).count + h.evolve! + assert_equal true, h.gameboard.board[0][1].is_alive? + assert_equal false, h.gameboard.board[1][1].is_alive? + assert_equal true, h.gameboard.board[2][1].is_alive? + assert_equal true, h.gameboard.board[2][2].is_alive? + assert_equal false, h.gameboard.board[1][2].is_alive? + end + end +#end \ No newline at end of file