## Ruby practice 4

2016-05-02

### Q1: Palindromes

#### My Example Code

# add new method to String class
class String
def palindrome?()
s = self.downcase.gsub(/\W*/,"")
s == s.reverse
end
end

# or we can use method_missing
class String
def method_missing(m,*args,&block)
# m is method name(a symbol), use id2name or to_s
# self is foo in this case
if m.id2name == "palindrome?"
s = self.downcase.gsub(/\W/,"")
s == s.reverse
else
# if no match here, retrun to ancestor
super
end
end
end

puts "foo".palindrome? # => false
word = "foof"
puts word.palindrome? # =>true


### Q2: Enumerable Palindrome

Adapt your palindrome solution so that it works on Enumerables. That is:
[1,2,3,2,1].palindrome? # => true

(It is not necessary for the collection’s elements to be palindromes themselves - only that the top-level collection be a palindrome.) Although hashes are considered Enumerables, your solution does not need to make sense for hashes (though it should not produce an error).

#### My Example Code

module Enumerable
def palindrome?
if self.kind_of?(Array)
self == self.reverse
else
temp = self.to_a
temp == temp.reverse
end
end
end

a = [1,2,[1,2],2,1]
b = [["a"],"b","b",["a"]]
puts a.palindrome?
puts b.palindrome?


### Q3: Cartesian Product (use yield)

Given two collections (of possibly different lengths), we want to get the Cartesian product of the sequence - in other words, every possible pair of N elements where one element is drawn from each collection.
For example, the Cartesian product of the sequences a=[:a,:b,:c] and b=[4,5] is: a×b = [[:a,4],[:a,5],[:b,4],[:b,5],[:c,4],[:c,5]]

Create a method that accepts two sequences and returns an iterator that will yield the elements of the Cartesian product, one at a time, as a two-element array.

1. It doesn’t matter what order the elements are returned in. So for the above example, the ordering [[:a,4], [:b,4], [:c,4], [:a,5], [:b,5], [:c,5]] would be correct, as would any other ordering.
2. It does matter that within each pair, the order of the elements matches the order in which the original sequences were provided. That is, [:a,4] is a member of the Cartesian product a×b, but [4,:a] is not. (Although [4,:a] is a member of the Cartesian product b×a.)

To start you off, here is a pastebin link to skeleton code (http://pastebin.com/cgSuhtPf) showing possible correct results. For your convenience the code is also shown below

class CartesianProduct
include Enumerable
end
# Examples of use
c = CartesianProduct.new([:a,:b], [4,5])
c.each { |elt| puts elt.inspect }
# [:a, 4]
# [:a, 5]
# [:b, 4]
# [:b, 5]
c = CartesianProduct.new([:a,:b], [])
c.each { |elt| puts elt.inspect }
# (nothing printed since Cartesian product
# of anything with an empty collection is empty)


#### My Example Code

class CartesianProduct
include Enumerable
def initialize(arr_1,arr_2)
@arr_1 = arr_1
@arr_2 = arr_2
end

def each()
if block_given?
len1, len2 = @arr_1.size, @arr_2.size
(0...len1).each do |i|
(0...len2).each do |j|
element = [@arr_1[i],@arr_2[j]]
yield element
end
end
else
return "Blcok missing!"
end
end
end

c = CartesianProduct.new([:a,:b,:c], [4,5])
c.each {|elt| puts elt.inspect}
puts c.each