競技プログラミング用のJavaScriptテンプレートを作った

競技プログラミングをJavaScriptで解く際の、ある程度のテンプレを作成しました。

※ 筆者はまだ競技プログラミングを２回しか受験していません。今後テンプレには手が加えられる可能性があります。

 

こちらです。

```js
// JSでのIO処理準備
var lines     = [];
var readline  = require('readline').createInterface(process.stdin, process.stdout);

// 入力値の数値化
var parseInt10 = function(elem) {
  return parseInt(elem, 10);
}
var toInt = function(line) {
  var intArray = line.split(' ').map(parseInt10);
  if(intArray.length === 1) {
    return intArray[0];
  } else {
    return intArray;
  }
};

// 設定情報
var settings = {};
var defineRule = function(index, data, vars) {
  settings[index] = {};
  for(var i = 0; i < vars.length; i += 1) {
    settings[index][vars[i]] = data[i];
  }
};

// テンプレここまで

// 問題に即した設定定数
var RESULT, TEMP, LENGTH;

// 入力値の加工
var calculate = function(data) {
  // ここに処理
};

// main
readline.on('line', function(line) {
  line = toInt(line); // 入力値の数値化
  lines.push(line);

  // 処理内容は入力回数に依存
  switch(lines.length) {
    // 初期設定
    case '設定条件':
    defineRule(1, line, ['times', 'people']);
    break;

    // 最終処理
    case '終了条件':
    console.log(RESULT); // 最終出力
    process.exit(0); // 処理の終了
    break;

    // 途中処置
    default:
    calculate(line);
    break;
  }
});
```

※ 使われている変数や関数は全て見本です。

 

ポイントは初期設定処理と、処理本体ですね。

 

競技プログラミングでは、最初に設定値が与えられる模様なのでその処理を用意しました。(defineRule)

オブジェクトにごっそり詰め込んでいます。この処理ならば、２回目、３回目の入力が再度設定だった場合でも対応できます。

 

また、処理本体にはswitch文を使っています。

処理の種類は「初期設定」「中間処理」「最終週処理」になります。なので、条件分岐が少なくとも3つ以上になるはず。なのでswitch文を選択しました。

 

そして、入力値の数値化ですが、入力直後に行いました。(toInt)

 

まだまだ改良の余地はありそうですね。順次改良していきます。

 

ちなみに、[24回目](http://abc024.contest.atcoder.jp/)のB問題を解いたときの回答がこちら。


```js
// JSでのIO処理準備
var lines     = [];
var readline  = require('readline').createInterface(process.stdin, process.stdout);

// 入力値の数値化
var parseInt10 = function(elem) {
  return parseInt(elem, 10);
}
var toInt = function(line) {
  var intArray = line.split(' ').map(parseInt10);
  if(intArray.length === 1) {
    return intArray[0];
  } else {
    return intArray;
  }
};

// 設定情報
var settings = {};
var defineRule = function(index, data, vars) {
  settings[index] = {};
  for(var i = 0; i < vars.length; i += 1) {
    settings[index][vars[i]] = data[i];
  }
};

// テンプレここまで

// 問題に即した設定定数
var DOOR_OPEN_GROSS_TIME = 0,
    LAST_ENTERED_TIME;

// 入力値の加工
var alterLastEntered = function(enteredAt) {
  LAST_ENTERED_TIME = enteredAt;
};
var accumulatePeriod = function(enteredAt) {
  var openPeriod =
    enteredAt - LAST_ENTERED_TIME < settings['1']['T'] ?
    enteredAt - LAST_ENTERED_TIME :
    settings['1']['T'];

  DOOR_OPEN_GROSS_TIME += openPeriod;
};

// main
readline.on('line', function(line) {
  line = toInt(line); // 入力値の数値化
  lines.push(line);

  // 処理内容は入力回数に依存
  switch(lines.length) {
    // 初期設定
    case 1:
    defineRule(1, line, ['N', 'T']);
    break;

    // 初回処理
    case 2:
    alterLastEntered(line);
    break;

    // 最終処理
    case settings['1']['N']+1:
    accumulatePeriod(line);
    DOOR_OPEN_GROSS_TIME += settings['1']['T'];

    console.log(DOOR_OPEN_GROSS_TIME); // 最終出力
    process.exit(0); // 処理の終了
    break;

    // 途中処置
    default:
    accumulatePeriod(line);
    alterLastEntered(line);
    break;
  }
});
```

 

みなさんも適宜改変して利用してみてください。