simanのブログ

ゆるふわプログラマー。競技プログラミングやってます。Ruby好き

Rubyで全ての約数を出すメソッドを作った

「How Many Divisors?」
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_3_D

AOJの問題を解いてて「約数の配列だして、upper_boundとlower_boundをとれば終わりやな」と思ったのですが、Rubyに今の要素全部無かったので、作りました。

require 'prime'

class Array
  def upper_bound(x)
    bsearch_index { |v| v > x }
  end

  def lower_bound(x)
    bsearch_index { |v| v >= x }
  end
end

class Integer
  def divisor_list
    return [] if self <= 0
    return [1] if self == 1

    prime_division.map.with_index { |(base, k), i|
      s = i.zero? ? 0 : 1
      (s..k).map { |n| base ** n }
    }.inject { |res, e| res + res.flat_map { |t| e.map { |v| t * v } } }.sort
  end
end

a, b, c = gets.split.map(&:to_i)
list = c.divisor_list

x = list.upper_bound(b) || list.size
y = list.lower_bound(a) || list.size

puts x - y

Array#bsearch_index を使うことで簡単に実装出来た。

Rubyの文字列連結の速度比較

Rubyで文字列連結のメソッドの動作速度を比較してみました。

require 'benchmark'

Benchmark.bm do |x|
  NUM = 10000
  word = "Hello"

  x.report(:add) do
    str = ""

    NUM.times { str += word }
  end

  x.report(:concat) do
    str = ""

    NUM.times { str.concat(word) }
  end

  x.report(:shift) do
    str = ""

    NUM.times { str << word }
  end
end
       user     system      total        real
add  0.050000   0.050000   0.100000 (  0.098366)
concat  0.000000   0.000000   0.000000 (  0.001402)
shift  0.000000   0.000000   0.000000 (  0.001213)

結果としては「+=」が飛び抜けて遅かったです。理由としては連結の際に新しい文字列インスタンスを生成しているからだと思われます。「concat」や「<<」は高速に動作しますが、元のオブジェクトを破壊するので注意が必要です。

OSC Okinawa 2014に参加 & LT発表してきました!

今年も沖縄でOSCが開催されたので、1人で行ってきました!

今年は「去年に比べて、発表内容の理解が出来たかな」と思うと同時に「学ぶべきことがまだたくさんある」と感じたカンファレンスでした。

・「業務アプリケーションにおけるこれからのWeb開発」

今年勧告されたhtml5の仕様について色々知ることができました。重要な機能としては「WebSocket」と「SPDY」これらが今後のアプリ開発において重要な機能になるみたいです。

他にもhtml5ではオフラインにおけるアプリ開発をサポートするAPIが出てきており
・Application Cache
・Web Strage
・Indexed Database API
・File API

これらのAPIを駆使することで、オフラインでも動作するWebアプリが作れるとのこと。

html5が騒がれて数年が経ちますが、そろそろ本格的に勉強する時がきたのかなーと個人的に感じたセッションでした。

AWSで行うImmutable Infrastructure

先週のAWS勉強会で聴けなかった発表でした。最新の技術「Docker」に惹かれてホイホイやってきたのですが、とても面白かったです。

Dockerというコンテナ型仮想技術によって「環境を使い捨てる」という新たな概念に驚きました。Dockerでは仮想イメージを差分管理することもできるらしく、どんどんインフラな部分もプログラミング化されてきたなーと思いました。

・Ejectコマンドユーザ会(☝ ՞ਊ ՞)☝ウイーン

展示ブースでは前から気になってきたEjectコマンドユーザ会の展示を見に行きました。

Raspberry PiとCDドライブを駆使した電子工作に正直感動しました。電源のON/OFFをドライブのトレイの(出る/戻る)で実現していたのは、発想力がなんかもうスゴイなと。

ステッカーを頂いたのですが、キャラクターがなんとなくconohaのキャラに似てるなと思いました。(☝ ՞ਊ ՞)☝ウイーン

・LT発表しました!

LTセッションで、参加者を募集していたので、15分ぐらいで発表資料を作って参加してきました。

まだ開発途中のgemですが、よければ遊んでやって下さい

「shiritori」
https://github.com/siman-man/shiritori


最終的に150人近くの参加者がいたらしく、沖縄で開催されるカンファレンスとしてはかなり大規模になったと思います。アンケートに答えるのを忘れて、くじ引きが引けなかったのが心残りです。。。

Rubyで長いメソッドチェーンを作るゲームをするgemを作った

まだ作成中だけど、gemの名前確保も含めてリリース

「shiritori」
https://github.com/siman-man/shiritori

ルールに関してもまだ細かいところは決めてないけど大まかにはこんな感じ

ルール
1. 最初に適当なオブジェクトを入力
2. そのオブジェクトで使用できるメソッドを入力
     * 一度使用したメソッドは使用できない
     * 既存のメソッドや新しいメソッドの定義は禁止
3. 使用できるメソッドが無くなるまでこれを繰り返す
4. 長いメソッドチェーンを作ろう!


サンプル

% shiritori                                                                                                                                                   [master]
Please input first object > "Ruby"

+----------------------+
| Current method chain |
+----------------------+
|        "Ruby"        |
+----------------------+

+---------------+----------------+
| Current Class | Current Object |
+---------------+----------------+
|    String     |     "Ruby"     |
+---------------+----------------+

Please input next method > chars 
Exec command "Ruby".chars
:chars

+----------------------+
| Current method chain |
+----------------------+
|     "Ruby".chars     |
+----------------------+

+---------------+----------------------+
| Current Class |    Current Object    |
+---------------+----------------------+
|     Array     | ["R", "u", "b", "y"] |
+---------------+----------------------+

Please input next method > first
Exec command ["R", "u", "b", "y"].first
:first

+----------------------+
| Current method chain |
+----------------------+
|  "Ruby".chars.first  |
+----------------------+

+---------------+----------------+
| Current Class | Current Object |
+---------------+----------------+
|    String     |      "R"       |
+---------------+----------------+

楽しいかどうかは不明

追記

細かいルールをgistに書くことにしました。
https://gist.github.com/siman-man/7b67cde15c7180bd8a45

oh_my_methodなるgemを作った

作ったというより名前を確保した。

「oh_my_method」
https://github.com/siman-man/oh_my_method

gemの名前はoh_my_zshのパク...じゃなくてオマージュしました。

日頃オープンクラスしては、使い道の分からないメソッドを作って遊んでいたので、「使い捨てなのはもったいないな」と思い、まとめてgemにしようと思ったのが事の発端です。

これからも少しずつメソッドを増やしていきます。

Rubyで素数

Ruby素数を扱いたいときには便利なprimeライブラリがあります。自分がよく使用しているのは数値が素数かどうかを判定するprime?メソッドです。

require 'prime'

p 3.prime?    #=> true
p 10.prime?   #=> false
p 17.prime?   #=> true


他にも素数列を簡単に習得できたりします。

require 'prime'

prime_list = Prime::EratosthenesGenerator.new.take(5)
p prime_list    #=> [2, 3, 5, 7, 11]

とても便利なライブラリです。

参考サイト

「primeライブラリ」
http://docs.ruby-lang.org/ja/2.1.0/library/prime.html