CodeIQ:// TODO: 田中くんMarkdown直しといて

私自身が表題の問題を解いた時のプログラムについて解説します。
問題の詳細は「// TODO: 田中くんMarkdown直しといて」(CodeIQ)を参照してください。

問題の概要

Markdown形式のリストを整形せよという問題です。
ルールは次の通りです。

  • 標準入力に修正前の文字列が与えられます
  • 修正前の文字列は1行から10行です
  • 修正前の文字列の各行は 1-3桁の整数 + 半角ピリオド + [a-z]で構成される2-9文字の文字列です
  • 修正後の文字列の各行は 固定数値1 + 半角ピリオド + 半角スペース1文字 + [a-z]で構成される2-9文字の文字列です
  • 修正前後の 2-9文字の文字列 は同じ内容であること

具体的には次のようにパラメータが入力されます。

1. hoge
2. hige
3. hage

それを次のように修正します。

1. hoge
1. hige
1. hage

私のプログラム

Javascript(Node.js)で解答しています。

process.stdin.resume();
process.stdin.setEncoding('utf8');

var MarkListFormat = MarkListFormat || {
	inputed : Array(),
}

MarkListFormat.output = function(line){
	console.log(line);
}

MarkListFormat.formatList = function(input){
	var out = input.replace(/^(\d+?)\./, "1. ");
	console.log(out);
}

process.stdin.on('data', function (chunk) {
	var inputed = Array();
    var lines = chunk.toString().split('\n');

    var N = lines.length;
    for(var i=0; i<lines.length; i++) {
		var input = lines[i].trim();
		if (input.match(/^(\d+?)\./)) {
			MarkListFormat.inputed.push(input);
		}
    }
});

process.stdin.on('end', function () {
	for(var i=0; i<MarkListFormat.inputed.length; i++){
		//console.log(MarkListFormat.inputed[i]);
		MarkListFormat.formatList(MarkListFormat.inputed[i]);
	}
});

解説

この問題は難しくありません。
素直に処理すれば正しい結果にできます。

Javascriptと名前空間

Javascriptで以外と困るのがJavascriptにはJavaのような名前空間の仕組みがないことです。これはNode.jsですが上ブラウザで実行される場合、名前が衝突しておかしくなることが割と良くあります。私の経験で覚えているのはnameという変数を使ったらあるブラウザでは正しく動くのに別のブラウザではダメということがありました。どうも、タグのname属性と衝突していたような記憶があります。
それを防ぐためのテクニックが4行目です。
 var Hoge = Hoge || {};
のようにある名前のオブジェクトがなかったら生成し、自作するfunctionや変数は全てそのメンバにしてしまうとGlobalな名前空間に属する名前はHogeだけになります。これで名前の衝突を気にしなくて良くなります。
ちなみに、このプログラムではやっていませんが、名前空間オブジェクトのメンバにアクセスする場合、Webを検索するとthisを使ってthis.ValNameとかthis.FuncName()とかするのが一般的なようですが、私はHoge.ValNameとかHoge.FuncName()のようにしています。これはthisを使うとクロージャなどでthisが参照しているオブジェクトが変わってしまうためですが、thisを使う方が良い理由はあるのでしょうか?

入力と出力

process.stdin.on('data', function)で入力値を配列MarkListFormat.inputedにバッファし、process.stdin.on('end', function)で処理して出力しています。

MarkListFormat.formatList()

処理の本体です。と言っても正規表現で置換しているだけです。
私は念のため最短マッチしていますがしなくても問題ないかもしれません。

雑感

この問題をJavascriptでやった理由は確か、このころElectronでアプリケーションを作っていてJavascriptの正規表現が頭にあったからだと思います。問題を一目見て正規表現で置換すればOKと思いましたから。
C言語の場合CodeIQでregex.hを使えるかどうかわからないので自力でやることになりますが、1行の先頭から「.」を探してsprintf("1. %s", line+x)のようにすれば良いのでそんなんに難しくはありません。
※lineは1行分の文字列のバッファ。xは「.」の次のポインタ位置。