simanのブログ

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

去年を振り返って(2013)

2013年のうちに書いとくべきだったけど忘れてました。

競技プログラミングな年

2013年は競技プログラミングの年でした。 今までは趣味でアプリ開発とかしてましたけど、違った面白さがあったハマりました。今年のレーティングはアルゴリズムのほうが1128(緑)でマラソン1622(黄)で終え、1年目にしてはまずまずだったのかなーと思います。個人的にはマラソンのほうが長期的なコードが書けて面白かったです。競技を始めるきっかけになったCodevsのほうにもファイナリストとして出場できてとてもよかったです。来年はもっといい成績を残せるように精進したいと思います。

24開発コンテスト入賞

開発のほうでは、クックパッド主催の開発コンテスト24で特別賞を受賞しました。もともと、24時間でどれだけのものが作れるんだろうと思って1人友人を誘って参加してみたコンテストなのですが、まさか賞を貰えるなんて思いませんでした。


こうして1年を振り返ってみると、色々なことに手を出していたんだなーという印象を受けます。今年は何しようかな。

RubyでShoesを使ってGUIプログラミング - Hello World

RubyGUIプログラミングしたいなと思い検索してみると、一番最初にShoesがヒットしたので少し触ってみました。

ダウンロードはこちらから
http://shoesrb.com/downloads.html

とりあえず簡単なHello Worldを作ってみました。

Shoes.app do
  button "Click me!" do
    alert("Hello World!")
  end
end

hello.rbと名前をつけて保存したらshoes hello.rbで実行ができます。

shoes hello.rb 



実行するとこんな感じで画面が出力されます。
f:id:simanman:20131231093059p:plain

ボタンをクリックしてみると
f:id:simanman:20131231093129p:plain

とりあえずこんな感じでHello Wroldを出力してみました。今後、色々調べてみてどんなことが出来るのか試していきたいと思います。

RubyでHashのsortの返り値をHashにする

RubyのHashのsortは返り値がArrayになっています。

hash = { a: 30, b: 66, c: 45, d: 100, e: 80 }

p hash.sort_by{|k,v| v }
[[:a, 30], [:c, 45], [:b, 66], [:e, 80], [:d, 100]]

ArrayではなくHashで受け取りたい場合は、この値をそのままHashに入れてあげれば大丈夫です。

hash = { a: 30, b: 66, c: 45, d: 100, e: 80 }

result = hash.sort_by{|k,v| v }

p result

sorted_hash = Hash[result]

p sorted_hash
[[:a, 30], [:c, 45], [:b, 66], [:e, 80], [:d, 100]]
{:a=>30, :c=>45, :b=>66, :e=>80, :d=>100}

追記 ( 2014/1/10 )

Ruby2.1からはArrayに対してto_hが使用できるようになったので、上記のようにHashに渡すのではなくto_hでハッシュに戻すことが出来るようになりました。

hash = { a: 30, b: 66, c: 45, d: 100, e: 80 }

p hash.sort_by{|k,v| v }.to_h
{:a=>30, :c=>45, :b=>66, :e=>80, :d=>100}

Rubyのcompact

Array#compactメソッドは配列の要素からnilを取り除くメソッドです。compact!だと自身も変更します。

array = [ 1, nil, 3, nil, 5 ]

p array
p array.compact
p array

array.compact!
p array
[1, nil, 3, nil, 5]
[1, 3, 5]
[1, nil, 3, nil, 5]
[1, 3, 5]

要素からnilを排除するときに使用します。

実行速度が気になった

配列のサイズを大きくして速度を測ってみました。測定方法として、Rubyでは添字に値を入れるとそれ以前の値をnilで埋めてくれるので、それをcompactメソッドを使用して消しています。

array = []
array[5] = 1
p array
[nil, nil, nil, nil, nil, 1]

array[5]より前の値がnilになっていることがわかる


require 'benchmark'

Benchmark.bm do |x|
  10.times do |i|
    puts "Array size = #{10**i}"
    x.report do
      array = []
      array[10**i-1] = 1
      array.compact!
    end
  end
end
       user     system      total        real
Array size = 1
   0.000000   0.000000   0.000000 (  0.000009)
Array size = 10
   0.000000   0.000000   0.000000 (  0.000004)
Array size = 100
   0.000000   0.000000   0.000000 (  0.000005)
Array size = 1000
   0.000000   0.000000   0.000000 (  0.000005)
Array size = 10000
   0.000000   0.000000   0.000000 (  0.000060)
Array size = 100000
   0.000000   0.000000   0.000000 (  0.000568)
Array size = 1000000
   0.010000   0.000000   0.010000 (  0.007023)
Array size = 10000000
   0.020000   0.030000   0.050000 (  0.052151)
Array size = 100000000
   0.200000   0.270000   0.470000 (  0.475037)
Array size = 1000000000
   1.970000   2.840000   4.810000 (  4.805006)

実装見る限りだと、配列を線形探索してnil排除してる感じだったので、こんなものなのかなーと思います。

ちなみに最後の10億の配列はメモリが5G近く奪われました。