LoginSignup
42
21

More than 3 years have passed since last update.

TypeScriptでAtCoderに挑戦してみる

Posted at

こんにちは、この記事はTypeScript AdventCalendar 8日目の記事です。

概要

普段PythonでAtCoderに挑戦しているが、せっかくなので好きなTypeScriptで挑戦してみたい...!!!
ということで、とりあえず簡単なABC(AtCoderの初心者向けコンテスト)の簡単な問題をTypeScriptで解いてみることにしました。

ちなみにJavaScript/TypeScriptで競技プログラミングをする際の注意点はこの記事がよくまとまっています。
(どう考えても向いてなさそう)
JavaScript/TypeScriptで競技プログラミングをするには 後編

AtCoderとは

日本最大の競技プログラミングのコンテストサイトです。
週末にはなにかしらのコンテストが開催されています。

また、対応言語の種類も多いのが特徴で、ばっちりTypeScriptも入っています。バージョンは2.1.6です。
提出 - AtCoder Beginner Contest 143 - Google Chrome 2019-12-07 11.20.24.png

環境構築

ローカルで動作確認できるように環境を構築しましょう。
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問題を解いてみましょう。
今回解く問題は、以下の問題です。

A - Curtain

この問題を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];

ab+をつけることで、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に提出する

最後に、AtCoderに提出してみましょう。
A - Curtain - Google Chrome 2019-12-07 12.13.45.png

自分の提出 - AtCoder Beginner Contest 143 - Google Chrome 2019-12-07 12.14.34.png

ACと出れば正解です :tada: :tada::tada:

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オンリーでコンテストに参加してみたい...!

42
21
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
42
21