Pythonのイディオム。
List Comprehensionの解説で
results = [(x, y)
           for x in range(10)
           for y in range(10)
           if x + y == 5
           if x > y]
という例題がある。そうか、forって複数指定できるんだ。
で、Rubyのメソッドチェーンではこのような複数シーケンスの ネストしたループをストレートに書くことができないことに気がついた。
(1..2).xxxx(1..2)
で、
[1,1],[1,2],[2,1],[2,2]
を返すようなxxxxメソッドがあれば、
(1..10).xxxx(1..10).select{|x,y| x+y == 5}.select{|x,y|x > y}
と書けるんだけど、名前がな。いい名前ないかな。
Rubyのオブジェクトはヒープと呼ばれる複数のメモリ領域のいずれかに所属する。 GCの過程で(保守的なチェックの一環で)ポインタがどのヒープ領域に所属するか をチェックしているところがある。
今までは線形探索をしていたのだが、 ここを二分検索するようにした。 まあ、現時点ではヒープの数はあまり多くならないので メリットはさしてないのだが、今後ひとつひとつのヒープのサイズを小さくすることを 考えているのでそのための下準備として。
ところが、二分検索の基本的なアルゴリズムは理解していたはずなのに なかなかバグが取れない。結構、情けない。
クリスチャン的視点から見たフリーソフトウェア運動。
っていうか、タイトルを見た時にはどういう論理展開するのかと思って読んだのだが、 実は穏当な意見であった。
テレビはダメかもしれん、という話(そのまんま)。
実際、ここ数年テレビを見る時間はぐんぐん減っている。 私の家族も最近はPCを使った情報収集に時間を取られて テレビはあまり見なくなってしまっている。
テレビはもはや時間が余った時に雑学を入力する手段くらいにしかなってなくて、 しかもそれってインターネットで代用可能だったりするんだよね。
やっぱ、2011年にはテレビを捨てることになるのかなあ。
Zed 「ゲットー」 Shawが(CIOに向けて)Rubyの「欠点」について語る。
言語そのものについての欠点の指摘はほとんどないので 言語デザイナーとしては安堵なのだが、欠点のほとんどは私の実装(MRI)の弱点なので そういう意味では涙目である。
やや、根拠が薄いような気もするが(ほんとに遅いのかとか、ほんとにリークするのかとか)、 改善の余地があることについては私も認める。
悔しいので、また手を入れることにする。 一番難しいのはGCだろうか。「保守性によるリーク」や「停止時間」の問題について また考えてみたい。
某雑誌の記事のため写真撮影。 なんか金かけてるよな。
今日はいきつけの本屋さんで立ち読みしているところの撮影だとか。 事前に本屋には許可を取ってあるのだが、 立ち読みしてるところをバシバシとられるのは かなり恥ずかしい。
cartesian_productは長いですかねぇ。
「×」の読みをとってcrossとか。
ここは思い切って,(1..2)*(1..2) とか.
みっつ以上ネストすることもありえるんで*演算子はあまりよくありませんね。
>みっつ以上ネストすることもありえるんで*演算子はあまりよくありませんね。
どのような場合でしょうか?
>ここは思い切って,(1..2)*(1..2) とか.
私が考えたのは、[^1..2]*[^1..2]です。
Haskellだったら、[1..2]*[1..2]にしたいです。
どのような場合と言われても、もともとlist comprehensionのforが複数あるケースに対応したいという話ですから、forの数が限定されていない以上、ふたつまで限定というのはうれしくないのです。
で、実は1.9にはproductというメソッドがすでにあるのですが、これは
* 引数がto_aryを持つ必要がある
* 戻り値が配列(Enumeratorじゃない)
というのがちょっとうれしくないですねえ。
まつもとさま、ご回答有難うございます。
少し美しくないですが、([^1..2]*[^1..2])*[^1..2]というようには出来ないのでしょうか?
と思いましたが、確かに直積を二重に実行すると、[[[1,1],1],[[1,1],2],..]とするのか、というようなりますですね。
それなら諦めて、cprod([^1..2],[^1..2],..).select{..}としたほうが、素直ではないかと思ったのですが、いかがでしょうか?
tupleとか?
Mathematicaではtupleを似たよーな感じで使っているようですが。
http://reference.wolfram.com/mathematica/ref/Tuples.html
(1..2).tuple(1..2) #=> Tupleクラス{(1..2),(1..2)}
Tuple.to_ary #=> {[1,1],[1,2],[2,1],[2,2]}
組み合わせ爆発が起こらないように、Tupleクラスを間に挟むとか・・・。Rubyを良く知って言っている訳ではないので、すでにこんなの存在してたらごめんなさい。
atushiさま
いまさら(?)Rubyにタプルを実装するのも如何なものかと思います。
集合論的に考えれば、集合≒配列としてよいのではないでしょうか?
ただし、[a,a,b]というのを集合としていいのか、という話しがあるので、例えば、集合クラスのインスタンスを、s=[<a,a,b>]としたら、例外が発生するというやり方があるのではないかと思っております。
先に申した「集合クラス」は、大袈裟に、「擬似集合クラス」とかいう名前で定義し、数学的な意味での集合とタプルの性質を合わせ持ったクラスであると宣言すれば、カッコ良くないでしょうか?
http://ja.wikipedia.org/wiki/%E3%82%BF%E3%83%97%E3%83%AB
「数学的な意味での集合とタプルの性質を合わせ持ったクラス」というのは、非常に無理がありましたっていうか、無理でした。(多分?) 申し訳御座いません。
pair、pair_with なんてどうでしょう? 直感的に。
pairだと2重しか意味しませんよね。
単純に関数として (Ruby1.9ではGeneratorが死んでるので1.8で)
require 'generator'
def foreach_inner(a,*b)
l = b.shift
if b.empty?
l.each{|x| yield *(a+[x])}
else
l.each{|x| foreach_inner(a+[x],*b,&Proc.new)}
end
end
def foreach(*arg)
if block_given?
foreach_inner([],*arg,&Proc.new)
arg
else
Generator.new do |g|
foreach_inner([],*arg){|*x| g.yield(x)}
end
end
end
foreach(1..3){|x| p x}
foreach(1..2,5..6,8..9,'a'..'b'){|x,y,z,s| p [x,y,z,s]}
p foreach(1..10,1..10).select{|x,y| x+y == 5}.select{|x,y|x > y}
配列の要素数が決まってしまう&Ruby的に怪しい雰囲気になりますが
(1..3).ijk { i+j+k }
なんてのはどうでしょう
comboってのは?
nest_withでは?
いっそのこと、
([1..2],[1..2],[1..2]).select{|x,y,z| ...}
とか、
([1..2],[1..2],[1..2]).each{|x,y,z| ...}
なんていうのはいかがでしょうか?