版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yangbo_hr/article/details/4225187
记录从
Ruby Quiz练习中学习到的技术。
- Quiz 1 - Solitaire Cipher 用时近4小时. 代码存放在Github。
- 预处理的函数可以用一个形象的英文动词sanitize来命名,sanitize意为“清洁”,就像本函数是要把输入参数清洁化为大写字母,并且只保留字母。
- 抽象出Deck对象。
- 使用 return 语句更易读。
- 五个字母分为一组,用空格分割,最后一组不足五个的话用X补全:
我的实现: def every_5 msg splited = "" msg.chars.each_with_index do |c, idx| splited << c splited << " " if idx >= 4 and (idx+1)%5==0 end splited.upcase end def preprocess orig_msg filterd_msg = orig_msg.chars.reject do |c| c =~ /[^a-zA-Z]/ end msg = filterd_msg.to_s msg += "X"* (5 - (filterd_msg.size+5) % 5) if (filterd_msg.size+5)%5 != 0 msg.upcase end
更好的实现:
def sanitize(s)
s = s.upcase
s = s.gsub(/[^A-Z]/, "")
s = s + "X" * ((5 - s.size % 5) % 5)
out = ""
(s.size / 5).times {|i| out << s[i*5,5] << " "}
return out
end - 把一张牌往后移动几位:
我的实现:
另一种实现:
def move_forward deck, card, num
idx = deck.index card
if idx + num >= deck.size
insert_idx = num - (deck.size-1-idx)
deck.delete_at idx
deck.insert insert_idx, card
else
deck.insert idx+num+1, card
deck.delete_at idx
end
enddef move_down( index )
if index == @deck.length - 1
@deck[1..1] = @deck[index], @deck[1] # 表示把@deck[1..]区间的一个元素替换为两个元素
@deck.pop
else
@deck[index], @deck[index + 1] = @deck[index + 1], @deck[index]
end
end - 替换数组中的子数组:
array[index] = obj → obj
array[start, length] = obj or an_array or nil → obj or an_array or nil
array[range] = obj or an_array or nil → obj or an_array or nil
示例:
a = Array.new
a[4] = "4"; #=> [nil, nil, nil, nil, "4"]
a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "4"]
a[1..2] = [ 1, 2 ] #=> ["a", 1, 2, nil, "4"]
a[0, 2] = "?" #=> ["?", 2, nil, "4"]
a[0..2] = "A" #=> ["A", "4"]
a[-1] = "Z" #=> ["A", "Z"]
a[1..-1] = nil #=> ["A"] - optionparse库的使用
require 'optparse'
options = {
:key => nil,
}
ARGV.options do |opts|
opts.banner = "ruby #{FILE.basename(__FILE__)} [options]"
opts.on("-k", "--key") do
options[:key] = :key
end
opts.on("-h", "--help") do
puts opts; exit
end
opts.parse!
end - a[index], a[index+1] = a[index+1], a[index] # 进行数组元素互换。