ruby编程题

学了一段时间ruby后,又学了段时间python,学了python时间后,又想学学ruby了,本来原来打算用python搞个C/S软件的,学了一段时间后才发现根本没有针对python3的类库,wxpython没有,而pyqt那个客户端又有些问题,再加上其本身是收费的,越来越没劲,从而又想学下ruby了,毕竟在web方面,django是赶不上rails的,而且python那个通过缩进来区别代码段用着不是很习惯,所以又改学ruby了。前面的一遍博客已经有一二关的答案了,
http://fansofjava.iteye.com/admin/blogs/660506
所以从第3关开始写,改用ruby实现,其实也是从官方抄的。
One small letter, surrounded by EXACTLY  three big bodyguards on each of its sides.
题目的意思是一个小写字母,两边有且仅有三个大写字母,开始想了下,觉得很TMD的有难度,其实这就是搞web开发久的后果,几乎不会写算法了,因此无从下手,其实这个用正则表达式很简单:

text = open('e:/three.txt').read()
p text.scan(/[^A-Z][A-Z]{3}([a-z])[A-Z]{3}[^A-Z]/).join


ruby有种用法,有些方法后面可以不加括号,即也可以写成join()。

后面的关的确开始难起来了,第四关就有点难了,这关地址为
http://www.pythonchallenge.com/pc/def/linkedlist.php
当点击那张图片时地址变为
http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=12345
点此页面nothing的值也是需要改变的,这样一个一个继续下去,直到最后出现结果为止,
这个题有点难,本来对ruby都不是很熟悉的人我来说,是不太可能做得出来的,只能看答案了:

require 'open-uri'
nothing = "12345"
1.upto(400) do |n|
 open("http://www.pythonchallenge.com/pc/def/linkedlist.php?nothing=#{nothing}") do |f|
   str = f.read
   if str =~ / next nothing is (\d*)/ then
     newnothing = $1
     puts "#{nothing} -> #{newnothing} \t\t#{str.chomp}"
     nothing = newnothing
   elsif str =~ /Divide by two/ then
     ni = nothing.to_i / 2
     nothing = ni.to_s
   else
     puts str
     raise "Finished!"
   end
 end
end


可以看出,用ruby尚且写了如此多的代码,用java的话不知道得写多少代码。

第四关这个是与python相关的,主要是关于序列化的问题,查看源代码内,发现有个banner.p的文件,把它下载下来,这是一个python序列化后的文件,当然对于python不了解的我来说,也只有在网上找答案:
引用

<!-- peak hell sounds familiar ? -->这个提示, peak hell sounds like pickle,
原来这个banner.p是使用pickle序列化了python的一个对象保存下来的文本, 以前没有接触过pickle,


通过下面代码可以查出序列化前的数据:

import pickle
obj = pickle.load(open("banner.p", "r"))
for line in obj:
    print "".join([k*v for k, v in line])


如果要用ruby,也只能处理转换后的数据,也就是说只能用python来反序列化此数据,反序列化文件后会得到附件内的数据。就可以用ruby转换:

text = open("f:/ruby/banner.rb").read()
puts eval(text.tr('()','[]')).collect{|i|i.collect{|p|p[0]*p[1]}.join}


可以看出,pythonchange内容还是挺丰富的,涉及的范围很广。

第5关就更难了,如果凭空想象,依自已的实力几乎做不出来,经过网上的多方查证,勉强理解这道题的答案来历。这道题 链接:
http://www.pythonchallenge.com/pc/def/channel.html
网页给出的是一张图片,看不出什么,只得照例看源码,后有人提醒:
1.源码的第一行为:<html> <!-- <-- zip -->
2.拉链(zipper)
所以应该有一个zip的文件,于是将channel.html改为channel.zip,果然有个zip的文件可供下载,打开zip文件中的readme.txt 可以看到
welcome to my zipped list.

hint1: start from 90052
hint2: answer is inside the zip

于是一直查找到最后一个文件,查看其内容:
require 'zip/zip'
nothing = 90052
comments = ""
Zip::ZipFile.open("f:/channel.zip", Zip::ZipFile::CREATE) {
     |zFi|
     while nothing > 0
         nNot = zFi.read(nothing.to_s + ".txt")
         nothing = nNot.split("nothing is ")[1].to_i
     end
     p nNot
}


输出结果为:
"Collect the comments."

结果是想收集注释,其实这个东西本人是一点都不了解,也没看见哪里有什么文件注释,关于ruby的zip处理,可见:
http://rubyzip.sourceforge.net/
处理结果:
require 'zip/zip'
nothing = 90052
comments = ""
Zip::ZipFile.open("f:/channel.zip", Zip::ZipFile::CREATE) {
     |zFi|
     while nothing > 0
         nNot = zFi.read(nothing.to_s + ".txt")
         comments += zFi.get_entry(nothing.to_s + ".txt").comment
         nothing = nNot.split("nothing is ")[1].to_i
     end
     puts comments
}


输出结果为:
ruby编程题

访问 http://www.pythonchallenge.com/pc/def/hockey.html会得到一句话:
it's in the air. look at the letters.

联系上面的那张图片里面的字母,答案就出来了:oxygen,真不容易。

第6关更难了,自己不看答案也是不可能做出来的,说实话,这题必需要求答题人员对语言有相当高的认识才行。我当然还不是那种人,所以只能看答案。
访问: http://www.pythonchallenge.com/pc/def/oxygen.html
这网页里面只有一张图片,其余什么都没有,唯一有点特别的就是图片中间有一条颜色不太一样的条纹,答案就从中产生。这条条纹中每种颜色的长度为7px,总长与宽为629*95,用ruby的话,有关于图片处理的组件rmagick,这个组件功能很强大,在ror中经常看见有人用,不过也有些复杂,所以目前自己还没试用过,正好这也是个机会。
不过用起来才发现还真是复杂,首先是安装,rmagick对windows平台的支持力度还不够吧,不支持ruby1.9.1,在1.8.7上也费了点神才跑起来。步骤是在别人那里看来的:
引用

1 从http://rubyforge.org/projects/rmagick/ 下载rmagick-win32 对应的zip包(RMagick-2.12.0-ImageMagick-6.5.6-8-Q8.zip).
2 解压zip到一个临时目录,在该目录中有一个ImageMagick的安装文件ImageMagick-6.5.6-8-Q8-windows-dll.exe,安装。
3 开一个命令行窗口,cd到解压的临时目录,敲入命令: gem install rmagick.
4.把ImageMagick 的安装路径放到path环境变量里面


这样以后,还需要引入才可以用,结合上面需求,具体代码如下:
require 'rubygems'
require 'RMagick'

image = Magick::ImageList.new("f:/oxygen.png")
#x, y, width, height
pixels = image.get_pixels(0,image.rows/2,image.columns,1)
letters = pixels.map {|pix| pix.red.chr}
clue = ""
letters.inject(0) do |count, char|
  clue += char if count == 0
  (count + 1) % 7
end
/\[(.+)\]/.match(clue)
p $1.split(", ").map {|num| Integer(num).chr}.join


ruby有些地方很怪异,比如Array.map与Array.collect方法作用是一样的,类似的事情还很多,而且早一点的版本根本就没这两个方法,可见起初,ruby api还是相当的不完善。

为什么要引入rubygems这个包目前还不清楚,但是不引入的话会提示找不到文件。当然目前对ruby的理解还在初级阶段,不理解的东西太多了。正因如此,解决此题本人花了相当多的时间,几乎花了半天时间,ruby api的查看目前还没找到比较好的方法也是个问题。

求最大公约数:

def mod(a,b)
  if a<0 || b<0
    return "求模数字需要大于0"
  end
  a,b=b,a if(a<b)
  @yueshu = a%b
  if @yueshu.zero?
    b
  else
    mod(b,@yueshu)
  end
end

p mod(24,2)

你可能感兴趣的:(编程,python,Ruby,rubygems,wxPython)