reduce(l|r)をRubyで実装しますた!
404 Blog Not Found:Code Snippets - reduce(l|r)を実装汁!
というわけで問題。reducelとreducerを実装せよ。制限時間はあわせて10分。ただし、reducelとreducerは、Haskellにおいて次の挙動を示すものとする。

*Main> reducel (\x y -> "("++x++"#"++y++")") $ map show [1..4]
"(((1#2)#3)#4)"
*Main> reducer (\x y -> "("++x++"#"++y++")") $ map show [1..4]
"(1#(2#(3#4)))"

 弾さんから課題が出されていたのでやってみた。既に Perl の回答例があったので、Ruby で実装。というか、まんま移植と言った方が正しいかもしれないけど・・・(汗)。とりあえず、10分間の制限時間に間に合うように書いたのが、以下。

def reducel(proc, arr)
result = arr.shift
arr.each do |i|
result = proc.call(result, i)
end
result
end

def reducer(proc, arr)
result = arr.pop
arr.reverse.each do |i|
result = proc.call(i, result)
end
result
end

puts reducel(lambda{ |x, y| "(#{x}\##{y})" }, [1, 2, 3, 4])
#=> (((1#2)#3)#4)
puts reducer(lambda{ |x, y| "(#{x}\##{y})" }, [1, 2, 3, 4])
#=> (1#(2#(3#4)))

 Ruby の Range オブジェクトは pop とか shift が使えないところでつまづいた(そのせいで、(1..4) と書けばすみそうなところが [1, 2, 3, 4] なんて書き方になっている)。

 で、少し調べてみたら、inject を使えば、そのまま書けるじゃんという事に気づく。あと、Range オブジェクトは to_a で配列に変換可能なので、それらをふまえると、以下のような感じになる。

def reducel_r(proc, arr)
arr.inject do |result, item|
result = proc.call(result, item)
end
end

def reducer_r(proc, arr)
arr.reverse.inject do |result, item|
result = proc.call(item, result)
end
end

puts reducel_r(lambda{ |x, y| "(#{x}\##{y})" }, (1..4).to_a)
#=> (((1#2)#3)#4)
puts reducer_r(lambda{ |x, y| "(#{x}\##{y})" }, (1..4).to_a)
#=> (1#(2#(3#4)))


 というか、そもそも Haskell のコードがほとんど分からなくなっている事にショック。それに、reduce(l|r) なんて初めて聞くような気がするし、まだまだ勉強が足りないっすね・・・。


 もうちょっと別の言語(Scheme、JavaScript あたり)でも書いてみたいなぁ。Haskell で再実装も面白いかもしれない。


*追記:
 to_a は、reduce(r|l) に入れた方が、Duck Typing的に良いような気がする。

def reducel_r(proc, arr)
arr.to_a.inject do |result, item|
result = proc.call(result, item)
end
end

def reducer_r(proc, arr)
arr.to_a.reverse.inject do |result, item|
result = proc.call(item, result)
end
end
こうしとけば、

puts reducel_r(lambda{ |x, y| "(#{x}\##{y})" }, (1..4))
puts reducer_r(lambda{ |x, y| "(#{x}\##{y})" }, (1..4))
でも

puts reducel_r(lambda{ |x, y| "(#{x}\##{y})" }, [1, 2, 3, 4])
puts reducer_r(lambda{ |x, y| "(#{x}\##{y})" }, [1, 2, 3, 4])
でもOK。
[PR]
by fkmn | 2007-06-03 23:01 | IT
<< LL魂のチケットを買った リンクに target=&qu... >>


とあるWebアプリケーションエンジニアの日記
S M T W T F S
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
カテゴリ
以前の記事
ブログパーツ
リンク
検索
タグ
最新のトラックバック
プログラミングが「出来る..
from とりあえず9JP?
Genographic ..
from ナンジャモンジャ
ジュセリーノ
from ありの出来事
くちこみブログ集(ライフ..
from くちこみブログ集(ライフ)(..
以降、丁寧語で行こう!
from エッセイ的な何か
その他のジャンル
ファン
記事ランキング
ブログジャンル
画像一覧

fkmnの最近読んだ本 フィードメーター - フッ君の日常 あわせて読みたい AX