2010-01-17
■ [ruby] shinhさんの迷路ゴルフ解読した
ビフォー:
q=gets(p)*1,~/S/ (a,i,*q=q a[i]<?S&&a[i]=?$ 4.times{|x|q+=[a*1,x]if$_[x=-~x%3*-~~/$/-~/$/+-x/2+i]!=$_[x]=?*})while/G/ puts a
アフター:
seen = gets(nil) queue = [[seen.dup, ~/S/]] wid = ~/$/ while seen =~ /G/ maze, here = *queue.shift maze[here] = ?$ unless maze[here] == ?S 4.times{|k| d = (k+1) % 3 n = here + (d-1)*wid + (d + -k/2) # h w # k=0 1-1= 0 1+ 0 = 1 2 # k=1 2-1= 1 2+ -1 = 1 3$0 # k=2 0-1=-1 0+ -1 = -1 1 # k=3 1-1= 0 1+ -2 = -1 if seen[n] != ?* queue.push([maze.dup, n]) end seen[n] = ?* } end puts maze
キューを使った幅優先探索(BFS)でした。
- str*1って意味あるのかと思ったら目的はstr.dupだった
- +-x/2って-(x/2)でいいんじゃないかと思ったらマイナスのときに駄目だった
■ [mac] 特定のFlashを含むサイトがフリーズします、助けて
1/17午前は大丈夫だったんですけど、午後から特定のFlashを含むサイトをMacBook(10.5.8)で見るとブラウザごとフリーズするようになった(Safari4, Firefox3, Chrome, Opera9/10で確認)。
- セーフな例:http://www.nintendo.co.jp/ds/uorj/index.html
- アウトな例:http://www.nintendo.co.jp/ds/uorj/howtomake/index.html
Flashをアンインストールすると普通に見れるようになるので犯人なのは間違いないんですが…。
2010-01-25 Ruby基礎文法最速マスター
■ Perl基礎文法最速マスターをだいたいそのまま、Rubyに置き換えてみました。
他の言語をある程度知っている人はこれを読めばRubyの基礎をマスターしてRubyを書くことができるようになる…かも知れません。無保証です。
参考:
■ 1. 基礎
インタラクティブRuby (irb)
irbを使うと、Rubyのプログラムを簡単に練習することができます。
/Users/yhara $ irb irb(main):001:0> puts "hello" hello => nil irb(main):002:0> 1 + 1 => 2
以下の説明は、irbを起動して、自分で試しながら読むと習得が早いと思います。
表示 (print, puts, p)
print "foo" #=> 改行なし puts "foo" #=> 改行あり p 123 #=> デバッグ用
いわゆる「printfデバッグ」は、Rubyでは「pデバッグ」になります。
変数の宣言
Rubyには変数宣言はありません。また変数の型もないので、一つの変数にいろいろなクラスのオブジェクトを代入することができます。
a = 123 a = "abc" #=> aを上書きする
Rubyでは先頭の一文字によって変数の種類が変わります。
foo #=> ローカル変数 @foo #=> インスタンス変数(@) @@foo #=> クラス変数(@@) $foo #=> グローバル変数($) FOO #=> 定数(大文字から始まる)
コメント
「#」以降はコメントになります。
# コメント
スクリプトの実行
$ ruby foo.rb
出力結果をファイルに書き出すにはリダイレクトを使います。
$ ruby foo.rb > out.txt
■ 2. 数値
num = 1 num = 1.234 num = 100_000_000
四則演算
num = 1 + 1 num = 1 - 1 num = 1 * 2 num = 5 / 2 #=> 2 (整数どうしの割り算は整数になる) num = 5.0 / 2 #=> 2.5 (どちらかが小数なら結果も小数) num = 5 % 2 #=> 1 (余りをとる)
インクリメントとデクリメント
Rubyには++演算子がないので、+=や-=を使います。
i += 1 i -= 1
■ 3. 文字列
文字列はシングルクォートかダブルクォートで囲みます。ダブルクォートの中では\t(タブ)や\n(改行)などの特殊文字を利用することができます。またダブルクォートで囲まれた文字列の中では「#{}」を使って任意の式を展開することができます。
str1 = 'abc' str2 = "def" str3 = "a\tbc\n" str4 = "#{str1} def" #=> "abc def"
文字列操作
結合
str1 = "aaa" + "bbb" str2 = ["aaa", "bbb", "ccc"].join(",")
分割
record = "aaa,bbb,ccc".split(/,/)
長さ(文字数)
length = "abcdef".length length = "abcdef".size # String#sizeとString#lengthは同じ動作。好きな方をどうぞ
切り出し
substr = "abcd"[0, 2] #=> "ab" (0番目から2文字)
検索
idx = "abcd".index(/bc/) #=> 1
■ 4. 配列
配列は「[]」を使います。
ary = [100, 200, 300]
要素の参照と代入
a = ary[0] #=> 100 b = ary[1] #=> 200
ary[0] = 1 ary[1] = 2
要素の個数
n = ary.length n = ary.size # Array#sizeとArray#lengthは同じ動作。好きな方をどうぞ
配列の操作
ary = [1, 2, 3] # 先頭を取り出す a = ary.shift #=> aは1、aryは[2,3]に # 先頭に追加 ary.unshift(5) #=> aryは[5,2,3]に # 末尾を取り出す b = ary.pop #=> bは3、aryは[5,2]に # 末尾に追加 ary.push(9) #=> aryは[5,2,9]に
■ 5. ハッシュ
ハッシュ(辞書)は「{}」を使います。
hash = {"a" => 1, "b" => 2}
キーには文字列よりも、シンボル(英語しか使えないが軽い文字列みたいなもの)を使うことが多いですが。
hash = {:a => 1, :b => 2}
要素の参照と代入
hash["a"] #=> 1 hash["b"] #=> 2
hash["c"] = 5 hash["d"] = 7
ハッシュの操作
キーの取得
hash.keys #=> ["a", "b", "c", "d"] (Ruby 1.8.xでは順不動)
値の取得
hash.values #=> [1, 2, 5, 7] (同上)
キーの存在確認
hash.key?("a") #=> true
ハッシュのペアの削除
hash.delete("a")
■ 6. 制御文
Rubyでは、条件文で偽と見なされるのはfalseとnilのみで、それ以外のオブジェクトは 全て真と見なされます(0や空文字列も真)。
if文
if a == 1 ... elsif b == 2 ... else ... end
while文 (あまり使いませんが)
i = 0 while i < 5 ... i += 1 end
Array#eachとブロックを使った繰り返し
[1, 2, 3].each do |i| # 「do |..| .. end」のことをブロックと呼びます puts i # Array#eachは、各要素をブロックに渡して実行してくれます end # 1, 2, 3と順に表示します。 [1, 2, 3].each{|i| # ブロックには「{|..| .. }」というちょっと短い記法もあります。 puts i # 上の記法とは(結合順位が違うだけで)全く同じ動作になります。 }
Integer#timesとブロックを使った繰り返し
5.times do |i| # 0, 1, 2, 3, 4と順に表示します puts i end 5.times do # 値を使わないときは、「|..|」の部分は書かなくて構いません puts "hello" end
Kernel#loopとブロックを使った無限ループ
loop do puts "stop me!" # 無限に表示し続けるので、Ctrl-Cで止めてください。 end
その他の繰り返し
Enumerableモジュールには、繰り返しを行う便利なメソッドがたくさん定義されています。
条件に合うものだけを選ぶ
[1,2,3,4,5].select{|x| x.even?} #=> [2,4]
条件に合うものを除く
[1,2,3,4,5].reject{|x| x.even?} #=> [1,3,5]
条件に合う最初のものを返す
[1,2,3,4,5].detect{|x| x.even?} #=> 2
等しい値があるか調べる
[1,2,3,4,5].member?(3) #=> true
条件に合うものがあるか調べる
[1,2,3,4,5].any?{|x| x.even?} #=> true
全ての要素が条件に合うかを調べる
[1,2,3,4,5].all?{|x| x.even?} #=> false
条件に合うものの個数を数える
[1,2,3,4,5].count{|x| x.even?} #=> 2
最大のものを返す
[1,2,3,4,5].max #=> 5
最小のものを返す
[1,2,3,4,5].min #=> 1
加工結果が最大のものを返す
[1,-2,3,4,-5].max_by{|x| x.abs} #=> -5
加工結果が最小のものを返す
[1,-2,3,4,-5].min_by{|x| x.abs} #=> 1
昇順にソートする
[1,-2,3,4,-5].sort #=> [-5, -2, 1, 3, 4]
加工結果で昇順にソートする
[1,-2,3,4,-5].sort_by{|x| x.abs} #=> [1, -2, 3, 4, -5]
加工結果を配列で返す
[1,-2,3,4,-5].collect{|x| x.abs} #=> [1, 2, 3, 4, 5]
selectにはfind_all、rejectにはdelete_if、detectにはfind、member?にはinclude?、collectにはmapという別名があります。 *1
*1 Rubyistはcollect派とmap派に二分されますが、筆者はmap派です。理由はタイプ数が少ないからです
■ 7. サブルーチン
Rubyには「サブルーチン」というものはありませんが、 トップレベルでメソッド定義を行うことで、どこからでも呼べるメソッドを定義することができます。 これはサブルーチンのように使うことができます。
def sum(x, y) return x + y end p sum(1,2) #=> 3
■ 8. ファイル入出力
読み込み
とりあえずFile.readだけ覚えておけばなんとかなると思います。
str = File.read("foo.txt") #=> strに、foo.txtの内容を丸ごと含む文字列が代入される
書き込み
File.openで開いて、IO#writeで書き込みます (IO#putsとかもあります)。
File.open("out.txt", "wb") do |f| f.write str end
■ 知っておいた方がよい文法
Rubyの真偽値
前述のように、falseとnilが偽、それ以外の全ての値は真です。
「nil」は値がないことを示す特別な値です。例えば、配列で範囲外の要素を取ろうとするとnilが返ってきます。
ary = [1,2,3] ary[100] #=> nil
コマンドライン引数
ARGVという組み込み定数に入っています。
# ruby foo.rb a.txt b.txt としたとき: p ARGV #=> [a.txt, b.txt]
C言語と違って、ARGV[0]にプログラム名が入っていたりはしません。プログラム名は$0という変数から取得できます。
# ruby foo.rb a.txt b.txt としたとき: p $0 #=> foo.rb
unless式
ifの逆です。
unless a == 1 do ... end
後置のif (if修飾子)
Rubyではifやunlessを文の後ろに置くことができます。
puts "ok" if x == 1 puts "ng" unless x == 1
クラス定義
クラスは「class..end」で定義します。
class Person def initialize(name, age) @name, @age = name, age @address = nil end attr_reader :name, :age attr_accessor :address end jhon = Person.new("Jhon", 15) p jhon.name jhon.address = "USA, Earth"
その他のよく使うクラス
■ 余談
本体に入らなかった、Rubyの「仕組み」についての話です。
全てがオブジェクト
Rubyでは、全ての値が、いずれかのクラスに属するオブジェクトです。 例えば数値の「1」はFixnumクラス、文字列「"foo"」はStringクラス、 配列「[1,2,3]」はArrayクラスのオブジェクトです。
全てがメソッド
Rubyには「関数」のようなものはなく、printやputsでさえもKernelモジュールに定義されたメソッドです。
puts "foo" # これは、 self.puts "foo" # これの省略形 p self #=> main (トップレベルのselfは、mainという特別なオブジェクト) p self.class #=> Object (mainは、Objectクラスのインスタンス) # (Objectクラスは、Kernelモジュールをインクルードしている) # (なので、トップレベルでputsと書ける)
Kernelモジュールに定義されたメソッドは、プログラムのどこからでも呼び出せます。
Rubyでは演算子もメソッドです。例えば「1 + 2」はInteger#+の呼び出し、 「ary[1]」はArray#[]の呼び出し、「ary[1] = 2」はArray#[]=の呼び出しです。
■ (おまけ)Ruby書籍紹介
筆者の独断と偏見によるRuby書籍紹介です。
- 他のプログラミング言語をマスターしていて↓
- プログラミングとかあんまり慣れてない↓
- これ一冊でOK、的な本がほしい
- 4797336617
- 何かを作りながら学びたい
- 4777512924 4797352604
- これ一冊でOK、的な本がほしい
- コンピュータにあまり慣れてない↓
- 初歩から応用まで一冊で
- 4798019437
- 基礎から応用までじっくりと
- 4798117994 4798118001 479811801X
- 堅苦しいのはいやなの
- 4844327704
- 初歩から応用まで一冊で
- 基礎は分かったんで↓
- どんなことができるのか知りたい
- 4863540221 4797340045
- なんか作ってみたい
- 4839927847 4839932115 483993178X 4839931496
- Webアプリがやりたい
- 4274067858 4873114381
- 「まつもとゆきひろ」を「ひろゆき」と間違えないようになりたい
- 4822234312
- どんなことができるのか知りたい
2010-01-27
■ [ruby] 文法最速(略)について
普段ニッチな記事しか書かないので全体のhotentryに入ることってないんですが、Rubyの話でも間口が広ければちゃんと入るんですね。間違いはこっそり直しています。ご指摘ありがとうございます。
実はtDiaryの1日分がまるごと1エントリになってるんですが、これはブックマークの分散を防ぐためと、ネストが深くなりすぎるのを防ぐためでした。
「基礎としてどのような項目が必要十分か?」を考えるのが一番大変なところであって、 僕はそれに乗っかっただけなので楽させてもらいました。他の人もどんどん 「Common Lisp基礎文法最速マスター」とか「Clojure基礎文法最速マスター」とか「R6RS基礎文法最速マスター」とか書けばいいと思います(Lisp限定か)。
2010-01-29
■ [ruby] Rackミドルウェアのコンテスト、優勝者が決定
Rackミドルウェアのコンテスト「CodeRack」の結果発表があったようです。
では、上位3位の発表です!
3位:RackProctitle
Rubyプロセスのタイトルに、処理中のURLや処理時間を入れることで、時間がかかっているプロセスをpsで見つけやすくする。
2位:Rack::Superlogger
Rackレベルでログを取る。いろいろなフレームワークを使い分けているときに、全部同じログ形式になるので、解析しやすい。
1位:Rack::GeoIPCountry
アクセス元のIPから国名を推測し、env['X_GEOIP_COUNTRY'] に入れてくれる。
特別賞(?) : RedisRequestLimiter
Redis(KVS)を使って、短時間に大量にアクセスしてくるユーザを弾く。
以下、決勝敗退ミドルウェアです。他にも、99個の全応募作の中に面白いものが眠っているかも…
- Rack::MemoryBloat (メモリの増大を検出する)
- Rack::Validate (ページをw3cのhtmlチェッカーにかける)
- Rack::CacheBuster (「30分後に新バージョンをデプロイするから、クライアントのキャッシュがその時間に切れるように設定して」)
- Rack::DomainSprinkler (画像などのドメインを、分散用サーバに振り分ける)
- LiveStats (現在のセッション数を表示する)
□ willnet [僕も同じ症状になったことありますねー いろいろ調べたもののよくわからず、最終的にmacの再インストールをしてしまい..]
□ yhara [怖いですよねぇ。今回は結局再起動したら直りました。]