😸

競技プログラム用のローカル実行環境を作ってみた

2024/02/22に公開

はじめに

もともと筆者はプログラミング初心者でしたがpaizaで数年の時間をかけてスキルチェックを進める中で段々とランクの高い問題に正答できるようになりました。目下のところAランク、Sランクを安定して正答できるようになるところが目標です。

paizaのWebサイト上でのコーディングだと部分的なデバッグがやりずらいなど諸々コーディング効率が下がるのを感じたため、使い慣れた環境でコーディング&実行確認する環境を作ってみました。paizaの問題のみならずAtCoderなど「ソースコードを提出してWebサイト上で実行結果の成否を評価する」枠組みのサイトであれば汎用的に活用できると思います。

概要

この実行環境では問題ごとに用意された入力例をテキストファイルに転記しておき、実装したプログラムに渡して実行結果を確認できます。

リポジトリのリンクはこちらです。
現在PythonとC#に対応しています。PythonはVSCode、C#はVisualStudio2019での動作を前提としています。
また、筆者が扱える言語が上記2つなので、その他言語の展開は今のところ考えておりません。
https://github.com/gkmaro634/CompetitiveProgramming

image

使い方

AtCoderのこちらの問題を例にとってPythonでの使用例を説明します。
https://atcoder.jp/contests/abs/tasks/practice_1

1.入力例をhandinput.txtにコピペする

問題ページには入力例が掲載されています。

この内容を本環境のhandinput.txtにコピペします。

2.標準入力の内容を変数に格納する

script.pyのexecuteメソッド内で標準入力の内容を変数に格納するためのコードを記述します。
予め頻出パターンのコードをコメントに記載しているので、それをコピペして流用すると多少効率的です。変数名は混乱を避けるため問題文と揃えるほうが良いでしょう。

3.問題を解くためのメソッドの引数を変える

script.pyのresolveメソッドの引数を問題で扱う変数と整合するよう変更します。

4.問題を解く

script.pyのresolveメソッド内で問題を解くためのコードを記述していきます。

5.回答を出力する

script.pyのexecuteメソッド内でresolveメソッドにわたす変数を変更し、resolveメソッドの戻り値を出力します。

6.ソースコードを提出する

期待結果との一致が確認できたらローカル環境で記述したソースコードを提出先のサイトのエディタにコピペして提出します。

今回の例のソースコード全体はこちらです。
[if len(sys.argv) > 1 and sys.argv[1] == "DEBUG":]以下でローカル環境特有の分岐に入るため、提出先での実行結果に影響を及ぼすことなく実行できます。

#!/usr/bin/env python3
import numpy as np

def resolve(a, b, c, s):
    """
    問題固有のメソッド。引数や戻り値は問題によって変える。
    """

    ans = f'{a+b+c} {s}'

    return ans

def execute():
    """
    pytestでの呼び出しを想定したメソッドである。
    """

    # read single value
    # N = int(input())

    # read splitted two values
    # H, W = list(map(int, input().split()))

    # read values
    # A = list(map(int, input().split()))

    # read 2d values
    # M = [list(map(int, input().split())) for i in range(N)]

    a = int(input())
    b, c = list(map(int, input().split()))
    s = input()

    ret = resolve(a, b, c, s)
    print(ret)
        
    return f"{ret}"

if __name__ == '__main__':
    import sys

    if len(sys.argv) > 1 and sys.argv[1] == "DEBUG":
        # launch.jsonで第1引数にDEBUGを渡すように設定している
        # ローカル実行環境の場合のみここを通る
        import os
        from pathlib import Path
        import utils
        data_dir = Path(__file__).parent.parent
        fpath = os.path.join(data_dir, "handinput.txt")
        utils.replace_stdin(fpath)

    execute()

まとめ

競技プログラミングの問題をローカル環境で実行する環境およびその使い方を紹介しました。
個人的な感想としては下記理由により本環境の使用以前と比べてプログラミング学習が捗るようになりました。

  • ローカル環境での試行錯誤がやりやすい
  • 作成したコードを無加工のままコピペで提出できてお手軽

今後も本環境を活用しながらpaizaやAtCoderで研鑽を続けていきたいと思います。

Discussion