LoginSignup
13
12

More than 5 years have passed since last update.

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

Posted at

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

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

こちらです。

// 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)

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

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

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

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

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

ちなみに、24回目のB問題を解いたときの回答がこちら。

// 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;
  }
});

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

13
12
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
13
12