競技プログラミングのAtCoderやってみた所感

空き時間にAtCoderというサービスをやってみたので感想や環境など。

概要

AtCoderは日本企業が運営している競技プログラミングのサイト。毎週主に土曜日の夜に定期コンテストが開かれていて、Webから登録すれば簡単に参加することができる。

コンテストの流れ

コンテストは事前に告知された時間にみんなで一斉に行う。

開始時間になるとページに問題が表示されるので、それに沿うようにコーディングを行う。

ソースコードをWeb画面から送信するとサーバでコンパイル、テストケースが実行され成否が判定される。正解した問題数と回答時間で順位が決まるようだ。

プログラミング言語はC++やJavaなどの選択肢から選ぶが、主要なものはほぼ揃っている。COBOLなんかもあるが流石に利用者はほぼ見当たらない。自分はC#でやっている。

所感

プログラミングというよりはアルゴリズムのコンテストといった感じで、数学的な問いをプログラムで実装するようなものが基本。

評価は「インプットに対するアウトプット」「計算時間」「回答時間」でされるので、コーディングのフォーマットやエラー処理なんかは特に問われれない。

難易度

毎週やってるBeginner Contestは難易度準にA~Fまでの問題がある。

ABは初学者教本にあるような基礎。足し引きと分岐・ループができればだいたいOK。

Cは数1Aぐらいまでの内容で、プログラミング的にも再帰やコレクションの使い分け、計算量を想定した実装が必要になってくる。普通のプログラマはこのあたりが及第点だろうか。

Dからは動的計画法や漸化式みたいな考え方が出てくるし、既知のアルゴリズムをベースにしたりする必要があるので、現役理系学生以外は対策しないと厳しい。

実務に活かせるか

内容がアカデミック寄りなので、ほとんどの現場ではあまり直接的な関係はなさそう。実際の業務コーディングではアルゴリズムより機能の切り分けや将来設計、速度より安全な実装と適切なエラー処理などの方が大事になってくる。

検索エンジンやミドルウェアを作るならそういう機会もあるかもしれない。

就職アピールなら評価の対象は問題そのものよりも、プログラミングへの興味の高さや、やっていくうえでの工夫や学習法あたりになるだろうか。

コーディング環境とか

一応Webサイト上にデバッグ環境みたいなのはあるが、すべてそれで賄うのは厳しいので、ローカル環境でコーディングをして完成ソースだけコピペしていると思われる。

自分はC#なので VisualStudio Communityでプロジェクトを作っている。

こんな感じ。

Program.cs

using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Linq;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args) {
#if DEBUG
        MyDebugger.Test(process, "../TextFile1.txt");
#else
        object ret = process(new StreamReader(Console.OpenStandardInput()));
        Console.WriteLine(ret);
#endif
    }

    static object process(TextReader input) {
        //ここにコードを書く
    }
}
MyDebugger.cs

using System;
using System.Diagnostics;
using System.IO;

public static class MyDebugger
{
    public static void Test(Func<TextReader, object> process, string inputfile) {
        Debug.WriteLine("TEST CASE OF " + inputfile);
        using (var reader = new StreamReader(inputfile)) {
            var count = 1; string str;
            var sw = new Stopwatch();
            while((str=ReadBlock(reader))!= null) {
                Debug.WriteLine("----------" + count++ + "----------");
                sw.Reset();
                sw.Start();
                object ret = process(new StringReader(str));
                sw.Stop();
                Debug.WriteLine(ret);
                Debug.WriteLine(sw.ElapsedMilliseconds + "ms");
            }
        }
        Debug.WriteLine("END DEBUG");
    }

    public static string ReadBlock(StreamReader reader) {
        var text = new System.Text.StringBuilder();
        while (true) {
            var str = reader.ReadLine();
            if (str == null) break;
            if (str.Trim() == "" && text.Length > 0) break;
            if (str.Trim() != ""){
                text.Append(str);
                text.AppendLine();
            }
        }
        if (text.Length == 0) return null;
        return text.ToString();
    }
    
    public static string ArrayToString(System.Collections.IEnumerable list) {
        var buil = new System.Text.StringBuilder();
        buil.Append("[");
        foreach(var x in list) {
            buil.Append(x.ToString());
        }
        buil.Append("]");
        return buil.ToString();
    }
}

デバッグ時はテキストファイルからテストケースを読み込んで実行するようにしてある。提出するのは Program.cs のみ。

あとは自作のスニペットツールに、インプットや組み合わせ関数など頻出するコードを登録してある。ここはもう少し充実させたいが、何が必要かが分かるには経験が必要かな。

なんだかんだで一斉に問題を解いて結果が出るのは楽しいので、しばらく続けてみようかと思う。

コメント