LoginSignup
1
0

More than 5 years have passed since last update.

第2回 オフラインリアルタイムどう書くの参考問題の解答例。ruby で。

Posted at

オフラインでリアルタイムに「どう書く」をやるイベント第二回
http://atnd.org/events/30900
の、参考問題
http://qiita.com/items/9d80de41903775296ca6
の解答例。rubyで。

#!ruby
#encoding:utf-8

def bitrot( q )
  len=q.to_i
  bits=q.split(':')[1].to_i(16)
  offset=(len&1)*3
  rotated_bits=(0...len*len).map{ |pos|
    y,x=pos.divmod(len) 
    bits[(len-x-1)*len+y+offset]<<(pos+offset)
  }.inject( &:| )
  "%d:%0*x"%[len,(len*len+offset)/4,rotated_bits]
end

DATA.each{ |line|
  q,expected=line.chomp.split(/\s+→\s+/)
  r=bitrot q
  puts(("%s  →  %s"%[q,r])+(r==expected ? '' : '**NG**'))
}
__END__
3:5b8 → 3:de0
1:8 → 1:8
2:8 → 2:4
2:4 → 2:1
2:1 → 2:2
3:5d0 → 3:5d0
4:1234 → 4:0865
5:22a2a20 → 5:22a2a20
5:1234567 → 5:25b0540
6:123456789 → 6:09cc196a6
7:123456789abcd → 7:f1a206734b258
7:fffffffffffff → 7:ffffffffffff8
7:fdfbf7efdfbf0 → 7:ffffffffffc00
8:123456789abcdef1 → 8:f0ccaaff78665580
9:112233445566778899aab → 9:b23da9011d22daf005d40

ruby なので、多倍長整数がそのまま使える。
divmod を初めて使った。役に立つのはこういうシチュエーションだよね、と思う。

ややトリッキーな offset=(len&1)*3 は、余る bit の数の計算。
紙の上で計算してみると、一辺の長さが偶数なら余らず、奇数なら3bit 余る。
ということで、len%2==0 ? 0 : 3 でもいいんだけど、ちょっとゴルフな気分で。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0