simanのブログ

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

RubyのFixnumの最大値と最小値

気になったので調べてみました。
Rubyではある値を越えた時にFixnumからBignumへと変わります。

p (2**0).class #=> 1
p (2**10).class #=> 1024
p (2**100).class #=> 1267650600228229401496703205376
p (2**1000).class #=> 略
Fixnum
Fixnum
Bignum
Bignum

そこで二分探索を行ってFixnumとBignumの境界値を調べてみました。

class Fixnum
  class << self
    def const_missing(name)
      if [:MAX,:MIN].include?(name)
        generate_max_min
        self.const_get(name)
      else
        super
      end
    end

    def generate_max_min
      a = 0
      b = 2**256

      while b-a > 1
        c = (a+b)/2

        if c.instance_of?(Fixnum)
          a = c
        else
          b = c
        end
      end

      self.const_set(:MAX, a)
      self.const_set(:MIN, -(a+1))
    end
  end
end

p Fixnum::MAX
p Fixnum::MIN
4611686018427387903
-4611686018427387904

ちゃんと境界値が取得できているかチェックします

p 4611686018427387903.class
p 4611686018427387904.class
p -4611686018427387904.class
p -4611686018427387905.class
Fixnum
Bignum
Fixnum
Bignum

ちゃんと取得できていました。試していないですが、実行する環境によって値が変わったりするかも。

追記

実装レベルで説明があってとても参考になりました
http://patshaughnessy.net/2014/1/9/how-big-is-a-bignum

今年の目標(2014)

競技プログラミングを頑張る

topcoderのrateを上げる。
・アルゴリズム1500以上
・マラソン2000以上

モバイルアプリに挑戦

何かアプリを1つ作る

新しい言語に挑戦

達人プログラマー的な


今年もいい年になりますように

去年を振り返って(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}