こんにちは。ささだです。

  [ [ruby-math:00851] Ramanujan Number ]
  Mon, 12 May 2003 10:19:05 +0900 への返信です。

 Haskell っぽい書き方なバージョンです。


 とりあえず、次を定義しておきます。


def inflist x,&b ; lambda{[x,inflist(b.call(x),&b)]}   ;end
def car(lst)     ; car,cdr = (Proc === lst) ? lst.call : lst ; car ; end
def cdr(lst)     ; car,cdr = (Proc === lst) ? lst.call : lst ; cdr ; end
def zip(xs,ys)   ;[[car(xs),car(ys)],lambda{zip cdr(xs),cdr(ys)}]  ; end

def take n,lst
  r = []
  n.times{
    r  << car(lst);lst = cdr(lst)
  } ; r
end

def filter lst
  cond = yield(car lst)
  while !cond
    lst = cdr lst
    cond = yield(car lst)
  end
  [car(lst),lambda{filter cdr(lst),&proc}]
end


 これで、こんなふうに作ります。

# Haskell => take 10 zip([2..],[3,2..])
# (2,3) , (3,4) , ... を最初から 10個選べ
p take(10,zip inflist(2){|x|x+1},inflist(3){|x|x-1})

# take 10 [x| x<-[0..], x % 2 == 0]
# 0,1,2,3,... で、偶数のものを最初から 10個選べ
p take(10,filter(inflist(0){|x| x+1}){|x| x % 2 == 0})


----------------------------------------------------------------------------

 上記を用いて、次のように解きます。


def f x; x[0]**3+x[1]**3 ; end
def fsort k; [[k,k],lambda{fmerge(inflist([k,k+1]){|x| [k,x[1]+1]},fsort(k+1))}] ;end

def fmerge xs,ys
  x = car(xs); xs = cdr(xs)
  y = car(ys); ys = cdr(ys)
  f(x) <= f(y) ? 
    [x,lambda{fmerge xs,[y,ys]}] :
    [y,lambda{fmerge [x,xs],ys}]
end

p take 10,filter(zip(fsort(1),cdr(fsort(1)))){|x|  f(x[0]) == f(x[1]) }


 実行は、非常に効率が悪いので、全然終わらないんですが ^^;

 なんとなく Haskell っぽいコードを Ruby で書いてみる部門、でした。


 以上。

-- 
// SASADA Koichi @ namikilab.tuat.ac.jp
//