FAQ on Ruby and ROR by Roseanne Zhang
class Array
def shuffle!
size.downto(1) { |n| push delete_at(rand(n)) }
self
end
end
b = [0,1,2,3,4,5]
b.shuffle!
puts b.join(", ")
fib_a = Hash.new{ |h, n| n < 2 ? h[n] = n : h[n] = h[n - 1] + h[n - 2] }
Here is my code in non-recursive fashion.
fib_b = Hash.new{ |h, n|
if n < 2
h[n] = n
else
m = 2
while n>=m
h[m] = h[m-2] + h[m-1]
m += 1
end
h[n]
end
}
puts fib_b[10000]
It is O(n). All fibonacci number from 1-10000 are stored, if you want fib_b[9000] now, it takes no time at all, O(1). However, there is a problem with this approach, fib_b[11000] will recalculate everything.
Here is an improved version fib_c:
fib_c = Hash.new{ |h, n|
if n < 2
h[n] = n
else
m = 200 # allowed stack depth, adjust according to your mechine
while n>m
h[m] = h[m-2] + h[m-1]
m += 200
end
h[n] = h[n-2] + h[n-1]
end
}
fib_c will only recalculate every stack depth, and reuse all other existing results. However, all above algorithm will exausting the memory, will be dead when n is really big. A better O(log(n)) algorithm is provided in the FAQ next.
fib_d = Hash.new{ |h, n|
if (n<2)
h[n] = n
elsif n == 2
h[n]=1
else
a = n/2
b = a + n%2
h[n] = h[a]*h[b-1] + h[a+1]*h[b]
end
}
puts fib_d[1000000]
puts "FooBarBaz".split(/(?=[A-Z])/).join('_').downcase # foo_bar_baz
puts "FooBarBaz".gsub(/(\B[A-Z])/, '_\1').downcase
puts "FooBarBaz".gsub(/\B[A-Z]/, '_\&').downcase
$iterations = 0
def bag(sack, nums)
$iterations += 1
return true if nums.include?(sack)
return false if sack < 0 or nums.empty?
head, *tail = nums
return true if bag(sack - head, tail)
if tail.size >= 2 then bag(sack, tail) else return false end
end
srand
sack = rand 30
n = 4
nums = []
0.upto sack/2 do |i|
nums[i] = rand 20
end
puts "sack #{sack}, [#{nums.join(',')}]"
puts bag(sack, nums)
puts "iterations = " + $iterations.to_s
E:\ex>ruby -e "puts self.kind_of?(Class)" false E:\ex>ruby -e "puts self.kind_of?(Module)" false E:\ex>ruby -e "puts self.kind_of?(Object)" true E:\ex>ruby -e "puts self" main E:\ex>ruby -e "puts self.class" ObjectObviously, main is an Object instance. However, main is also a method of Thread class.
class Animal
attr_reader :name
def initialize(name)
@name= name
end
def says
@name + " says some strange grunty sound"
end
end
class Dog < Animal
def says
@name + " says Woof!"
end
end
class Cat < Animal
attr_reader :name
def says
@name + " says News"
end
end
# Attention: Radio is not an Animal
class Radio
attr_reader :name
def initialize(name)
@name= name
end
def says
@name + " says News"
end
end
animal = Dog.new("Fido")
puts animal.says
animal = Cat.new("Socks")
puts animal.says
animal = Animal.new("Suzi")
puts animal.says
# here animal is not an Animal any more!!!
# It will not compile in C++/Java
# It is fine, since ruby duck/dynamic typing
animal = Radio.new("BBC")
puts animal.says
def test_closure_or_not(closure_or_not)
puts
puts "before calling closure_or_not"
result = closure_or_not.call
puts "after calling closure_or_not"
puts "result from closure_or_not: #{result}"
"test_closure_or_not result"
end
def test_block(&b)
puts
puts "before calling block"
result = b.call
puts "after calling block"
puts "result from block: #{result}"
"test_block result"
end
puts "======w/o return======"
# all three are fine without return
puts "w/o return:" + test_closure_or_not(lambda {"from lambda"})
puts "w/o return:" + test_closure_or_not(Proc.new {"from Proc.new"})
puts "w/o return:" + test_block{"from block"}
puts "======w/ return======"
# Only lambda is fine with return,
# lambda is closure, block and Proc.new are not
puts "w/ return:" + test_closure_or_not(lambda {return "from lambda"})
puts "w/ return:" + test_closure_or_not(Proc.new {return "from Proc.new"})
puts "w/ return:" + test_block{return "from block"}
def usage
"usage: word [lang2 [lang1]]\n" +
"Translate word from lang1 (default en, English) to lang2 (default es, Spanish)\n" +
"ISO language code: http://www.unicode.org/unicode/onlinedat/languages.html"
end
def translate
arr = ARGV
if !arr[0] then puts usage; return end
arr[1] = "es" unless arr[1]
arr[2] = "en" unless arr[2]
langpair = "#{arr[2]}|#{arr[1]}"
response = Net::HTTP.post_form(URI.parse("http://translate.google.com/translate_t"),
{'text' => arr[0],'langpair' => langpair})
response.body =~ /<div id=result_box dir=ltr>(.*)<\/div>/
result = $1
result = "No #{langpair} translation available for #{arr[0]}" if result.size == 0
puts result
end
translate