CodeIQ:◆小説発売記念問題◆【夏のミステリー】殺人現場のコード

私自身が表題の問題を解いた時のプログラムについて解説します。
問題の詳細は「◆小説発売記念問題◆【夏のミステリー】殺人現場のコード」(CodeIQ)を参照してください。

問題の概要

問題を引用します。
問題
殺人現場にプログラマが倒れていて、途中までプログラムが書かれている。
「続きを書いて欲しい」
これはダイイングメッセージなのか?
どうやらプログラムは、暗号を解き明かして、連続殺人犯の名前を出力するようだ。

暗号は各行、小文字のアルファベットで表されており、aを2の1乗、bを2の2乗、cを2の3乗……の2進数として、その文字列を結合したものだ。
各行の暗号を解き明かして、連続殺人犯の名前を出力しよう。

// 入力例
100000000000000000000100000000100000
100010100000000000000000000
// 出力例
the
cat
// 途中まで書かれたコード JavaScript (Node.js)
process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', function (chunk) {
  var lines = chunk.toString().split('\n');
  lines.forEach(function(line) {
    var arr = line.match(/■■■■/g);
    if (arr === null) return;
    var res = arr.map(function(x) {
      return ■■■■;
    }).join('');
  process.stdout.write(res + '\n');
  });
});

私のプログラム

Rubyで解答しています。

#!/usr/bin/ruby

def solve(line)
	arr = line.split("1")
	arr.shift

	str = ""
	for a in arr
		str += (0x60 + a.size).chr
	end

	return str
end

while line = gets
	line.strip!
	next if line.empty?

	puts solve(line)
end

解説

問題文のプログラムは全く無視してしまいました。

main

入力値を1行ずつsolve()に渡して結果の文字列を印字します。

solve(line)

入力値を'1'で分割します。0だけの文字列の配列ができます。
先頭が1なので最初の要素は空文字列になるのでそれを捨てます(5行目)。
0の数はaは1、bは2、…と1ずつ増えてゆくので0x60に0の数を足した値がそのアルファベットの文字コードになります。それを繋げてやれば良いだけです。

雑感

問題文のコードは無視しましたが、やっていることは同じですね。
正規表現は「1(0+)」だと思うけど。最短マッチにする必要はないよね。