こんにちは、この記事はTypeScript AdventCalendar 8日目の記事です。
概要
普段PythonでAtCoderに挑戦しているが、せっかくなので好きなTypeScriptで挑戦してみたい...!!!
ということで、とりあえず簡単なABC(AtCoderの初心者向けコンテスト)の簡単な問題をTypeScriptで解いてみることにしました。
ちなみにJavaScript/TypeScriptで競技プログラミングをする際の注意点はこの記事がよくまとまっています。
(どう考えても向いてなさそう)
JavaScript/TypeScriptで競技プログラミングをするには 後編
AtCoderとは
日本最大の競技プログラミングのコンテストサイトです。
週末にはなにかしらのコンテストが開催されています。
また、対応言語の種類も多いのが特徴で、ばっちりTypeScriptも入っています。バージョンは2.1.6です。
環境構築
ローカルで動作確認できるように環境を構築しましょう。
Node.jsやnpmは入っている前提で環境構築を進めます。
まずはnpm initでpackage.jsonを作ります。
$ npm init
その後、TypeScriptを動かすのに必要なモジュールをインストールします。
$ npm install typescript@2.1.6 ts-node @types/node
ts-node
はTypeScriptをコンパイルせずにそのまま動かせるモジュールです。
ABC-A問題を解いてみる
環境が整ったので、ABC-A問題を解いてみましょう。
今回解く問題は、以下の問題です。
この問題をPythonで解くと以下になります。
def a():
a_, b = map(int, input().split())
res = a_ - b * 2
print(res if res > 0 else 0)
if __name__ == '__main__':
a()
一番簡単な問題なのでロジックも極めてシンプルです。
ファイル作成
TypeScriptファイルを作成して開きましょう。
$ touch index.ts
入力
まずは標準入力を受け付ける必要があります。
シンプルに a b
という1行を取り込んで、スペースでsplitすればいいだけです。
ただ、TypeScriptだとここでまずつまづきますw
Node.jsの標準入力と
こちらの記事を参考に、以下の2つの方法で標準入力を取り込んでみます。
readFileSyncを利用する
fsのreadFileSyncを利用します。
割と簡潔に書けますが、Windowsで動かない という致命的な欠点があります。
これ以降は、こちらを利用します。
import * as fs from 'fs';
const input = fs.readFileSync("/dev/stdin", "utf8");
readlineモジュールを利用する
readlineモジュールを利用します。
Windowsでも動きますが、とにかくコードが複雑です。
最後にreadlineモジュールを用いた、コード例も載せておきます。
const lines=[];
const reader = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
reader.on('line', function (line) {
lines.push(line);
});
reader.on('close', function () {
// この中に入力が終わった後の処理=ロジックを記載する。
});
入力したものをsplitして変数にする
入力できれば、あとはスムーズに書けます。
stringであればsplit
を利用して、分割して、変数に代入します。
import * as fs from 'fs';
const input = fs.readFileSync("/dev/stdin", "utf8").split(" ");
const a = +input[0];
const b = +input[1];
a
とb
は+
をつけることで、string型からnumber型へ変換を行っています。
+をつけないと、後の計算時にエラーになります。
計算して出力する
残りは、Pythonなどとほぼほぼ変わらずTypeScript独特のポイントはありません。
ただ計算してロジックを書いて出力するだけです。
出力は、入力とうってかわっておなじみのconsole.log()
を利用すればよいので非常に簡単です。
import * as fs from 'fs';
const input = fs.readFileSync("/dev/stdin", "utf8").split(" ");
const a = +input[0];
const b = +input[1];
const res = a - b * 2;
if (res > 0) {
console.log(res);
} else {
console.log(0);
}
動作確認する
これで、コードが完成したので動かしてみましょう!
先ほども言ったとおり、このコードはWindowsでは動かないので、Windows環境以外で動かしましょう。
$ ./node_modules/.bin/ts-node index.ts
12 4
4
問題に記載されている入力例を入力して、出力例通りに出ればOKです。
ちなみに、入力が終わったら、Ctrl+Dを打ってEOF文字を入力する必要があります。
AtCoderに提出する
AC
と出れば正解です
readlineを使ったサンプル例
const lines=[];
const reader = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
reader.on('line', function (line) {
lines.push(line);
});
reader.on('close', function () {
const input = (lines[0] as string).split(" ");
const a = +input[0];
const b = +input[1];
const res = a - b * 2;
if (res > 0) {
console.log(res);
} else {
console.log(0);
}
});
感想
- 案外、標準入力以外はサクッと書ける
- 標準入力だけはめんどくさいのでテンプレート化などの対策が必要
- 今回は、非常に簡単な問題だったけど、複雑なデータ構造(queue, treeなど)を利用する場合、さらに大変そう...
というわけで、本記事は以上になります。
いつかはTypeScriptオンリーでコンテストに参加してみたい...!