RubyでExcel列名変換問題を解いて上司に対抗しよう!

社内でFizzBuzz問題のコンテストをしたら
あまり出来がよくなかったという記事があって
以前その問題をRubyで解いた投稿をしたよ


RubyでFizzBuzz問題を解いて上司に対抗しよう! - hp12c


FizzBuzz問題を使って社内プログラミングコンテストを開催してみた - ITは芸術だ


でその元記事の人によれば
第2回目の社内プログラミングコンテスト
開催されたらしいんだ


Excel列名変換問題で第2回社内プログラミングコンテストを開催してみた(前編) - ITは芸術だ


今度はFizzBuzz問題よりも難易度の高い
Excel列名変換問題が2題出題されたよ
詳細は元記事をみて欲しいけど
簡単に言うと
Excelのアルファベットの列名を数字に変換するものと
その逆変換をするものだよ
例えば「AA」は27に「XFD」は16384になるよ


少し前の投稿で僕は
Rubyでは何でも作れて
ロシアンルーレットのためのメソッドまで
予め用意されているって紹介したよ*1


RubyのRSpecでリボルバーを作ってロシアンルーレットしようよ! - hp12c


だから当然にRubyには
Excelのためのメソッドもあって
それらを使えば先の問題は簡単に解けちゃうんだよ:)

def alpha2num(alphabets)
 [*'A'..alphabets].size
end

def num2alpha(number)
 alpha = 'A'
 (number-1).times { alpha.succ! }
 alpha
end

alphabets = %w(A B Z AA AB AZ BB AAA IV ZZZ XFD)
numbers = alphabets.map { |alpha| alpha2num alpha }
  # => [1, 2, 26, 27, 28, 52, 54, 703, 256, 18278, 16384]
numbers.map { |num| num2alpha num }
  # => ["A", "B", "Z", "AA", "AB", "AZ", "BB", "AAA", "IV", "ZZZ", "XFD"]


つまりRubyではアルファベットは
順位が決まった比較可能なオブジェクトで
「Z」の次は「AA」で「ZZ」の次は「AAA」
になるよう設計されているんだ
ちょっと速度上の問題はあるかもしれないけどね


でもなんかこれで解けたっていうのは
ずるっぽい感じがするから
僕も上司に恥をかかされないように
勉強中のrspecを使ってまじめに解いたから
ここに貼っておくよ


*1:Array#rotate! #shuffle #cycleのことです^^;