KEEP K.I.S.S.

tk's blog

安装jekyll后一个无法使用的问题解决

Ruby环境是安装在C:\Program Files目录下面的,而不是默认的根目录。

安装Jekyll后,无法使用jekyll命令,会提示如下错误

'""c:\program' 不是内部或外部命令,也不是可运行的程序 或批处理文件

应该是路径处理有问题。

用记事本打开Ruby安装位置的bin目录下的jekyll.bat文件,会发现调用Ruby可执行程序的部分代码中双引号不配对,开头命令"@"符号后多用了一个双引号,共有两行,去掉后就好了。可能需要管理员权限打开记事本编辑再保存。

Ruby的字节操作

一个字节其实也就是一个整数,如果用十六进制表示的话,正好是两个十六进制数,用字符串表示就是 “HH”这样的表示。

Ruby的字节操作主要是靠两个方法来实现,String#unpack 和 Array#pack,两个类的实例方法,参数均为单一字符串。

举一个例子来讲解。

一般的 32位 Little-endian 机器上的单精度浮点数 float的一个实例: f = 88.888,得到它的字节表示 =>

因为字节操作需要 Array 类的 pack 操作,所以先把 f 放入一个数组实例中

 

irb(main):001:0> f = 88.888
=> 88.888
irb(main):002:0> s = []
=> []
irb(main):003:0> s << f
=> [88.888]
irb(main):004:0>

然后需要 pack 得到字符串表示

 

irb(main):004:0> s.pack("F")
=> "\xA8\xC6\xB1B"

也许会奇怪这个字符串为什么会这样,其实这里是 "\xA8\xC6\B1\x42",因为 \x42 正好是ASCII码表中 'B' 的十六进制代码,所以这里会显示成这样连着的。

然后我们得到字节的数值表示和十六进制表示:

 

irb(main):005:0> s.pack("F").unpack("C*")
=> [168, 198, 177, 66]
irb(main):006:0> s.pack("F").unpack("H*")
=> ["a8c6b142"]

还有一种方式:

 

irb(main):007:0> s.pack("F").unpack("C*").collect {|x| x.to_s(16) }
=> ["a8", "c6", "b1", "42"]

其实难点在于 pack 和 unpack 的操作,这个参数会很多,理解起来也有点难度,我觉得还是多用用就比较好理解了。

I hate dotnet and ms

 

最近在看Unix 编程艺术,其实也是当休闲书籍看来着。
不过有很多感触,对于书里提出的很多原则和方法。
比如线程的问题。
 
    linux 里没有等同于windows下的源生线程的东西,使用的是轻量级用户进程。线程的问题在于,多线程之间共享了过多的东西,这种共享是硬性的,默认的,容易引发问题,典型的就是C库的全局变量冲突问题,所以win下有包装过的多线程C库和单线程C库。而多进程的模型中,进程彼此的C库是独立的,其他资源默认也会是独立的,不会互相冲突,对于需要共享的资源只要通过灵活的IPC机制传递或者共享文件描述符。线程间的资源是默认共享,而进程间的资源是默认独立的,前者暴露了太多细节。就并发性来说,两者应该没有太多性能上的区别,轻量级线程的切换和线程切换,性能上现在也差别不是很大了。
 
自己还是对.net 执有偏见,或者说有些抵触的态度,我的感觉是,MS 的开发链变迁真的让开发人员心憔力悴,虽然很多的windows开发者并没有这种感觉,也不会认可这种感觉。MS 我个人觉得苦逼的程序猿大多是win下吧,唉。Unix的简单哲学,KISS原则,真的很适合让自己去反省和深思的。
还有一些就是关于设计模式和Ruby了。虽然自己对于设计模式也是懂的很浅的,不过不应该把设计模式的思想仅仅拘泥在面向对象的语言中,再进一步说,不应该把设计模式的一些思想拘泥在面向对象之中,这是从这本书里感悟到的。
 
虽然从emacs奔向了vim,但是最终还是镇守在ruby这边,没有逃向python。原因感觉也不清楚。相对来说,我不喜欢那种极度严谨的感觉。国内的ruby 真的不活跃。仅有的活跃地方应该是 Ror 和 RGSS了,我也是个初学者,也需要努力的。
 

Euler Project Problem 14 with Ruby

看题

 


The following iterative sequence is defined for the set of positive integers:

n → n/2 (n is even)
n → 3n + 1 (n is odd)

Using the rule above and starting with 13, we generate the following sequence:

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.

Which starting number, under one million, produces the longest chain?

NOTE: Once the chain starts the terms are allowed to go above one million.

 

Ruby 代码 这个速度还算可以了 4秒之内出结果

 

#!/d/ruby192/bin/ruby
#coding:utf-8

# get the next num of the chain
def next_num(num)
  if num.even?
    num/2
  else
    num*3+1
  end
end

$cache = Hash.new(0)

def get_len(num)
  if $cache.include?(num)
    res = $cache[num]
  else
    res = get_len(next_num(num))+1
    $cache[num] = res
  end
  res
end
$cache[1] = 1
$cache[2] = 2
$cache[4] = 3

$max,$most = 1,1
# from 1 to 1 million, so that the $cache may be used the most
(1...1_000_000).each do |num|
  if $max < get_len(num)
    $max = get_len(num)
    $most = num
  end
end  
puts $most,$max

Euler Project Problem 11 with Ruby

不多说了,题目

 

In the 20×20 grid below, four numbers along a diagonal line have been marked in red.

08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48

The product of these numbers is 26 × 63 × 78 × 14 = 1788696.

What is the greatest product of four adjacent numbers in any direction (up, down, left, right, or diagonally) in the 20×20 grid?

我的 Ruby 解法代码,

 

#!/d/ruby192/bin/ruby
#coding:utf-8

grid = %Q{
08 02 22 97 38 15 00 40 00 75 04 05 07 78 52 12 50 77 91 08
49 49 99 40 17 81 18 57 60 87 17 40 98 43 69 48 04 56 62 00
81 49 31 73 55 79 14 29 93 71 40 67 53 88 30 03 49 13 36 65
52 70 95 23 04 60 11 42 69 24 68 56 01 32 56 71 37 02 36 91
22 31 16 71 51 67 63 89 41 92 36 54 22 40 40 28 66 33 13 80
24 47 32 60 99 03 45 02 44 75 33 53 78 36 84 20 35 17 12 50
32 98 81 28 64 23 67 10 26 38 40 67 59 54 70 66 18 38 64 70
67 26 20 68 02 62 12 20 95 63 94 39 63 08 40 91 66 49 94 21
24 55 58 05 66 73 99 26 97 17 78 78 96 83 14 88 34 89 63 72
21 36 23 09 75 00 76 44 20 45 35 14 00 61 33 97 34 31 33 95
78 17 53 28 22 75 31 67 15 94 03 80 04 62 16 14 09 53 56 92
16 39 05 42 96 35 31 47 55 58 88 24 00 17 54 24 36 29 85 57
86 56 00 48 35 71 89 07 05 44 44 37 44 60 21 58 51 54 17 58
19 80 81 68 05 94 47 69 28 73 92 13 86 52 17 77 04 89 55 40
04 52 08 83 97 35 99 16 07 97 57 32 16 26 26 79 33 27 98 66
88 36 68 87 57 62 20 72 03 46 33 67 46 55 12 32 63 93 53 69
04 42 16 73 38 25 39 11 24 94 72 18 08 46 29 32 40 62 76 36
20 69 36 41 72 30 23 88 34 62 99 69 82 67 59 85 74 04 36 16
20 73 35 29 78 31 90 01 74 31 49 71 48 86 81 16 23 57 05 54
01 70 54 71 83 51 54 69 16 92 33 48 61 43 52 01 89 19 67 48}

$array = grid.scan(/\d\d/)

def get_value(x, y)
  ret = $array[y*20+x]
  if ret
    ret.to_i
  else
    0
  end
end

def get_most(x,y)
  m = []
  m << get_value(x,y)*get_value(x+1,y)*get_value(x+2,y)*get_value(x+3,y) 
  m << get_value(x,y)*get_value(x,y+1)*get_value(x,y+2)*get_value(x,y+3)
  m << get_value(x,y)*get_value(x+1,y+1)*get_value(x+2,y+2)*get_value(x+3,y+3)
  m << get_value(x,y)*get_value(x+1,y-1)*get_value(x+2,y-2)*get_value(x+3,y-3)
  m.max
end
$most = 0
for x in 0...20 
  for y in 0...20
    if $most < get_most(x,y)
      $most = get_most(x,y)
    end
  end
end

puts $most
   
   

不过感觉这写的还是不够优雅。。。。