Exercises from Chapter 13

Extend the Built-in Classes

How you could do it:

class​ Array
def​ shuffle
arr = self
# Now we can just copy the old shuffle method.
shuf = []
while​ arr.length > 0
# Randomly pick one element of the array.
rand_index = rand(arr.length)
# Now go through each item in the array,
# putting them all into new_arr except for
# the randomly chosen one, which goes into
# shuf.
curr_index = 0
new_arr = []
arr.each ​do​ |item|
if​ curr_index == rand_index
shuf.push item
else
new_arr.push item
end
curr_index = curr_index + 1
end
# Replace the original array with the new,
# smaller array.
arr = new_arr
end
shuf
end
end
class​ Integer
def​ factorial
if​ self <= 1
1
else
self * (self-1).factorial
end
end
def​ to_roman
# I chose old-school roman numerals just to save space.
roman = ​''
roman = roman + ​'M'​ * (self / 1000)
roman = roman + ​'D'​ * (self % 1000 / 500)
roman = roman + ​'C'​ * (self % 500 / 100)
roman = roman + ​'L'​ * (self % 100 / 50)
roman = roman + ​'X'​ * (self % 50 / 10)
roman = roman + ​'V'​ * (self % 10 / 5)
roman = roman + ​'I'​ * (self % 5 / 1)
roman
end
end
puts [1,2,3,4,5].shuffle
puts 7.factorial
puts 73.to_roman
3
5
4
1
2
5040
LXXIII

How I would do it:

class​ Array
def​ shuffle
sort_by{rand} ​# "self" is implied, remember?
end
end
class​ Integer
def​ factorial
raise ​'Must not use negative integer'​ ​if​ self < 0
(self <= 1) ? 1 : self * (self-1).factorial
end
def​ to_roman
# I chose old-school roman numerals just to save space.
raise ​'Must use positive integer'​ ​if​ self <= 0
roman = ​''
roman << ​'M'​ * (self / 1000)
roman << ​'D'​ * (self % 1000 / 500)
roman << ​'C'​ * (self % 500 / 100)
roman << ​'L'​ * (self % 100 / 50)
roman << ​'X'​ * (self % 50 / 10)
roman << ​'V'​ * (self % 10 / 5)
roman << ​'I'​ * (self % 5 / 1)
roman
end
end
# Get ready for the pure awesome...
p 7.factorial.to_roman.split(//).shuffle
["X", "X", "M", "M", "M", "X", "M", "X", "M"]

Orange Tree

How you could do it:

class​ OrangeTree
def​ initialize
@height = 0
@orange_count = 0
@alive = true
end
def​ height
if​ @alive
@height
else
'A dead tree is not very tall. :('
end
end
def​ count_the_oranges
if​ @alive
@orange_count
else
'A dead tree has no oranges. :('
end
end
def​ one_year_passes
if​ @alive
@height = @height + 0.4
@orange_count = 0 ​# old oranges fall off
if​ @height > 10 && rand(2) > 0
# tree dies
@alive = false
'Oh, no! The tree is too old, and has died. :('
elsif​ @height > 2
# new oranges grow
@orange_count = (@height * 15 - 25).to_i
"This year your tree grew to ​#{@height}​m tall,"​ +
" and produced ​#{@orange_count}​ oranges."
else
"This year your tree grew to ​#{@height}​m tall,"​ +
" but is still too young to bear fruit."
end
else
'A year later, the tree is still dead. :('
end
end
def​ pick_an_orange
if​ @alive
if​ @orange_count > 0
@orange_count = @orange_count - 1
'You pick a juicy, delicious orange!'
else
'You search every branch, but find no oranges.'
end
else
'A dead tree has nothing to pick. :('
end
end
end
ot = OrangeTree.new
23.times ​do
ot.one_year_passes
end
puts(ot.one_year_passes)
puts(ot.count_the_oranges)
puts(ot.height)
puts(ot.one_year_passes)
puts(ot.one_year_passes)
puts(ot.one_year_passes)
puts(ot.one_year_passes)
puts(ot.one_year_passes)
puts(ot.height)
puts(ot.count_the_oranges)
puts(ot.pick_an_orange)
This year your tree grew to 9.6m tall, and produced 119 oranges.
119
9.6
This year your tree grew to 10.0m tall, and produced 125 oranges.
Oh, no! The tree is too old, and has died. :(
A year later, the tree is still dead. :(
A year later, the tree is still dead. :(
A year later, the tree is still dead. :(
A dead tree is not very tall. :(
A dead tree has no oranges. :(
A dead tree has nothing to pick. :(

That’s pretty much how I would do it, too: clean and simple.

Interactive Baby Dragon

How you could do it:

# using the Dragon class from the chapter
puts ​'What would you like to name your baby dragon?'
name = gets.chomp
pet = Dragon.new name
while​ true
puts
puts ​'commands: feed, toss, walk, rock, put to bed, exit'
command = gets.chomp
if​ command == ​'exit'
exit
elsif​ command == ​'feed'
pet.feed
elsif​ command == ​'toss'
pet.toss
elsif​ command == ​'walk'
pet.walk
elsif​ command == ​'rock'
pet.rock
elsif​ command == ​'put to bed'
pet.put_to_bed
else
puts ​'Huh? Please type one of the commands.'
end
end

How I would do it:

# using the Dragon class from the chapter
puts ​'What would you like to name your baby dragon?'
name = gets.chomp
pet = Dragon.new name
obj = Object.new ​# just a blank, dummy object
while​ true
puts
puts ​'commands: feed, toss, walk, rock, put_to_bed, exit'
command = gets.chomp
if​ command == ​'exit'
exit
elsif​ pet.respond_to?(command) && !obj.respond_to?(command)
# I only want to accept methods that dragons have,
# but that regular objects *don't* have.
pet.send command
else
puts ​'Huh? Please type one of the commands.'
end
end
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.116.81.223