Ruby

割り算

n,m=$* w=m.size i=n.size f=proc{| *a|a.map{|s|s.to_s.rjust w+i+1}};a=f[n.to_i/d=m.to_i, s="-"*i,m+")"+n];t=i=0;n.chars{|c|s<<45;w+=1;s,a="-"* t.to_s.size,a+f[s,t,t-t%=d]if(t=t*10+c.to_i)/d>0};;a[ #Y.Endoh 3,2]=[]; puts a + f[s,t] $ ruby19 …

連想配列からハッシュを作る

[[1, 2], [3, 4], [5, 6]] という配列から {1=>2, 3=>4, 5=>6} を作る簡単な方法がないというのは、わりとよく出る話題でしたが、1.9 では実は Hash#[] として実装されていました (ruby-core:23225) 。 Hash[[[1, 2], [3, 4], [5, 6]]] #=> {1=>2, 3=>4, 5=>…

GMP で Bignum を高速化するパッチ

Ruby の Bignum は自力で多倍長整数演算を行っていますが、あまり速くないです。そこで、GMP を使うようにするパッチを書いてみました。GMP (The GNU MP Bignum Library) は gcc なんかも使ってるらしい多倍長整数ライブラリ *1 で、そこそこチューニングさ…

Ruby の例外クラスは分類が粗すぎる or 細かすぎる

と思いません? def foo(x) end foo(1, 2) #=> wrong number of arguments (2 for 1) (ArgumentError) 1.step(10, 0) { } #=> step can't be 0 (ArgumentError) a = []; a << a a.flatten #=> tried to flatten recursive array (ArgumentError) 確かにどれ…

回文や XML にマッチする鬼車の正規表現

ref: 鬼車 正規表現 Version 5.9.1 ref: Ruby Freaks Lounge: 第6回 Ruby M17N 事始め:正規表現編 \g と \k について今までちゃんとわかってなかったけれど、少しわかったような気になったのでメモ。Ruby というより鬼車の話なので、PHP でも使えるかもしれ…

BASIC 風 DSL (嘘)

Rubyでは行番号がどうやっても無理で Scala DSLによるBASIC実装 - Greenbear Diary (2009-04-07) 全くその通りで悔しいので、せめていんちきを。 # coding: UTF-8 require "basic" basic do 10 PRINT "Hello world!" 20 END end 以下ソース。 class << Objec…

アンダースコアだけで Ruby プログラムを書くライブラリ _

を作りました。github にアップロード済み。ref: http://github.com/mame/_/tree/master インストール 自己責任で。 $ gem install mame-_ --source=http://gems.github.com/ サンプル Hello, world! プログラム *1 。 require "_" ____ _ _____ ____ __ ___…

Ruby 1.9 の新機能もうひとめぐり (後編)

ref: http://gihyo.jp/dev/serial/01/ruby/0005 (Ruby Freak Lounge 第 5 回: Ruby 1.9 の新機能ひとめぐり (後編))の補足など。 鬼車による正規表現の強化: 名前を使った参照 /(?...)/ =~ string によって勝手にローカル変数を定義されるのがいや!という人…

Class#def_initailize

class Foo def initialize(foo, bar, baz) @foo = foo @bar = bar @baz = baz end end は各変数を 3 回も書いてぜんぜん DRY じゃなくて嫌。 class Foo def initialize(*a) @foo, @bar, @baz = *a end end は引数のチェックをしなくなるし、なんか嫌。 Foo =…

Ruby 1.9 の新機能もうひとめぐり (中編)

ref: http://gihyo.jp/dev/serial/01/ruby/0003 (Ruby 1.9 の新機能ひとめぐり (中編): 洗練された文法と意味論)の補足や思うことなど。 ブロックパラメータのスコープがブロックローカルに 要するに「ラムダ式の仮引数みたいになったよ」ということなんです…

map が面倒なので DelegateMap

簡単なことをする map を書くのが面倒です。配列の各要素に 1 足す程度のことで、いちいち .map {|x| x + 1 } などと 12 ストローク (空白除く) も必要なんですよ。しかもなんかごちゃごちゃして読みにくい。 使用頻度の低い inject とかなら許せるんですが…

double return

ref:http://www.kmonos.net/wlog/95.html#_1109090307 を見ていて、全然関係ないけど前ちょっと考えたくだらないことを思い出しました。 しばしば return を自分で定義したくなることがあります。例えば、最初に引数を検査して、だめだったら return すると…

Ruby 1.9 の新機能もうひとめぐり (前編)

ref: Ruby Freak Lounge 第1回 Ruby1.9の新機能ひとめぐり(前編):YARV,Fiber,配列処理の強化 の補足など。 YARV (Yet Another Ruby VM) による高速化 いきなり本編とあまり関係ないんだけど、高速化のまめ知識をひとつ。 YARV では while や if のよう…

gihyo.jp に Ruby 1.9 新機能の紹介記事を書いたよー

ref: Ruby Freak Lounge 第1回 Ruby1.9の新機能ひとめぐり(前編):YARV,Fiber,配列処理の強化Ruby Freak Lounge は、Ruby が好きな人が 1 人 2 回程度なにか書いて、他の人にリレーしていくという企画だそうです。最初の記事を書いてみないかというあり…

snip 関数

grep の -C オプションみたいなのって、意外に実装が難しいなと思いました。そこで考えた問題。 リストの中の条件を満たす要素の前後 n 個以外を省略する関数を書きなさい。例えば、 A B C D E F G H Iのリストに対して、E だけが条件を満たして、n = 2 であ…

Unlambda インタプリタを書いてみた (改)

一年前に Ruby 1.9 で極力シンプルな Unlambda のインタプリタを書いたんですが、yhara さんにメールでバグを指摘されてしまったので、いろいろ修正しました。 まず、d (delay) と入出力のないシンプル版。 require "continuation" def unlambda_subset(s) t…

1.9.1 リリース!

されました!1 ヶ月の延期はあったものの、ずるずる延びることがなくてよかったです。1.9.0 リリースの際は直前までバグ修正で大騒ぎだったんですが、今回はわりと前日までにおおよそケリがついてた感じで、わりと淡々としたリリースでした。みんな yugui さ…

ruby 1.9 を日常的に使うぼくが 1.9 の新機能を寸評する

なんか偉そうな見出しですが、ruby 1.9 を主に使うようになって 1 年ちょっと経ったので、1.9 の新機能に思うところや注意点などを書き残そうと思うのです。さらに 1 年後に見たとき、「あのころはあんなふうに考えてたなあ」などと感慨にひたる予定です。 …

15quzzle.rb

15 パズルを quine で作ってみました。 eval((%w[a=0;loop{a=(0..15).sort_by{rand};b=a.reverse;b=a[0,4]+b[8,4]+a [8,4]+b[0,4];n=0;16.times{|i|b[i]>0&&(0..i).map{|j|b[j]>b[i]&&n+=1}};n% 2>0&&break;};eval$s="b=0x#{a.map{|n|"%x"%n}.join}"+%w[;i=(…

quineclock

時計の絵をかいたら時計になるなんて、Ruby はとっても宣言的な言語ですね! eval s=%w(0;y=""< <32;z="eval((;s=%w(#{s} )*''));; %" <<43<<s; d="";" 0v vvnvn2 mj4kil 0v lvvul2 6l94ol 0v lv7vv" .scan (/ .{7}/ ){|n| 2. times {d.< <T ime. now. to_s.unpack(" C*") [11, 8].map{|i|("% 03b" .%7&n .to_i (32)> >3*i- =48).g sub(/. /){s>$ &?y*3: z.sl…</s;>

スタックトレースの賢い省略

Ruby は例外終了時にスタックトレースを表示しますが、長いときは以下のように省略をします。 $ ruby19 -e ' def fib(n) n <= 1 ? n : fib(n - 1) + fib(n - 2) end fib(30000) ' -e:3:in `fib': stack level too deep (SystemStackError) from -e:3:in `fib…

あけましておめでとうございます

1 時間くらいで書いた年賀状。 require"zlib";r=Zlib::Inflate.inflate(%w(eJylk 1FywzAIRK+0CBWR6xRb9z9CF6Q4mU4+0kaZ2BjxDFrwOKE TMh3jxLU UEq/stQzi6Qd CoeLikdYz7 Q9bX9POm/CBo MEfAN2K92jviAaj40E j7Im2lzS9giz aLMunvzVMYHj RLKvzUdEDjb9xYxUu5 6bp1Yt…

Bignum#* を Karatsuba 乗算で高速化した

例によってどーでもいい速度の話ですが、Ruby の Bignum の乗算を Karatsuba 法で高速化しました (ruby-dev:37392) 。これで Python より一歩進んだ気がします。今年の初めに書いた多倍長整数演算の速度比較の実験をやり直してみました。詳細はそっちをみて…

dynamic-wind と例外を考える

dynamic-wind の before や after で例外が投げられたとき、どこの rescue を起動すべきだろうか。 Scheme の意味を見てみると、「その before や after が与えられた dynamic-wind の文脈」で例外がハンドルされるみたい。つまり enable_check = false ctn …

Ruby に callcc を公式にサポートさせよう

Ruby の callcc というと、 現在の Ruby の Continuation は欠陥品で、まともに利用できないシロモノです。具体的には、dynamic-wind 相当の機能がありません。 (略) ちなみに、dynamic-wind 相当の機能を入れるのは、拡張ライブラリを全部 callcc safe にす…

1.9 の継続を 170 倍速くした

callcc {|c| c } while true でメモリリークするという話題 (ruby-core:19846) をきっかけに ruby 1.9 の継続まわりのソースを眺めていたら、継続の作成と呼び出しで毎回 VM stack を丸ごとコピー *1 していることに気がつきました。 rb_thread_mark を見る…

スタックトレースを蹂躙するクイズ

全要素が 1 以上の整数の列を受け取って、「その数を行番号とするスタックトレースを出力するプログラム」を出力するプログラムを書きなさい。 つまりこんな感じに動くもの。 $ ruby19 gen.rb 1 1 2 3 5 8 13 21 34 55 | ruby19 -:1:in `f1': unhandled exce…

eval の速度比較

ruby 1.9 は ruby 1.8 より eval が 3 倍くらい遅いというのは有名 (?) な話です。では、他の LL と比べてどうなんだろうと思ったので、比較をしてみました。 "1" を 100000 回 eval する eval の前処理と後処理にかかる時間の比較。 ruby 1.8 (trunk) : 0.2…

レーベンシュタイン距離

ふとレーベンシュタイン距離 (編集距離) の計算を書きたくなったので書いてみた。わりと綺麗に書けたと思った。 def levenshtein_distance(s, t) t.chars.with_index.inject(0..s.size) do |r, (a, z)| z += 1 [z] + s.chars.zip(r.each_cons(2)).map do |b,…

rirb を github に登録して gem 化した

はるか昔に rirb (Remote IRB) というのを作って放置していましたが、github に登録して gem を公開してみました。せっかくなので再紹介。 rirb (Remote IRB) とは 実行中の Ruby プログラムにアタッチして irb プロンプトを開かせることができます。グロー…