これからの競技プログラミングインフラ環境

2016/03/19

Tweet

「main.cpp を提出」に NO と言いたいだけ.あと,マイナー言語使いを幸せにしたい.

競技プログラミングプラットフォームのこれまで

競技プログラミングのプラットフォームとして,大きく二種類に分類したい.何を提出するかによってである.

  1. プログラム
  2. 出力ファイル

どちらが良いか?というのは議論の余地がある.

普通の流れ

TopCoder,Codeforces, AtCoder, yukicoder

これらで問題を解くときには,通常以下の流れがある:

  1. 問題を読む
  2. 考察する
  3. プログラムを書く
  4. プログラムを提出者の環境でテストする
  5. ファイルを提出する
  6. サーバの環境でプログラムをテストする
  7. Accept/Error を表示する

Google Code Jam,Kaggle

Google Code JamKaggle は以下の流れがある:

  1. 問題を読む
  2. 考察する
  3. プログラムを書く
  4. プログラムを提出者の環境でテストする
  5. 出力ファイルを提出する
  6. サーバで出力ファイルを確認する
  7. Accept/Error を表示する

提出物の利点,欠点

プログラムのみの提出

TopCoder等のプログラム提出では,以下の利点がある:

逆に,以下の欠点がある:

この欠点は,C++等で標準ライブラリのみを使っている場合には問題ないが,例えば

出力ファイルの提出

Google Code Jam 等の出力ファイル提出式には以下の利点がある:

逆に欠点として以下がある:

普通?のプログラミングの潮流

今現在のプログラミングの潮流として, Infrastructure as Code というものがあり,例えば以下のものがある:

Docker は Linux の上で動く仮想マシンのようなもので,コードでインストールしたいパッケージなどを指定する. 仮想マシンといってもとても軽量なので,実行時間などにほぼ影響はない. 後に例がある.

sbt や stack は言語専用のもので,依存関係等を記述できる. ネットからライブラリをダウンロードするmakeみたいなものである. これも後に例がある.

これからの競技プログラミングインフラ

これからの競技プログラミングには,「プログラム提出」と「出力ファイル提出」の利点を合体したものが必要とされている(と思う). そして,これは今流行っている「Infrastructure as Code」的なものである程度解決できるだろう.

提出するものとしては,以下の二つ.(この二つは一緒でも良い?)

この方式の利点としては,

がある.欠点としては,以下がある.

今のファイル,出力提出よりも良いと考えられる.

例1: Scala の場合

Scala では,sbt というツールを依存関係等を記述するのに使える.

libraryDependencies += "org.scalatest" %% "scalatest" % "2.2.4" % "test"
libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.12.5" % "test"

scalaVersion := "2.11.8" // 最新版が使える!やったー

scalacOptions ++= Seq(
  "-optimize", // 最適化オプションも使えるよ
)

なお,ファイル構成は以下のようになるだろう.嬉しい副作用として,複数ファイルも扱える.

.
├── build.sbt
└── src
     ├── main
     │   └── scala
     │       ├── Geometry.scala
     │       ├── Main.scala
     │       ├── SegmentTree.scala
     │       └── UnionFind.scala
     └── test
          ├── resources
          └── scala
              ├── Test.scala
              └── UnionFindTest.scala

なお,コンパイル時間と実行時間を分けたいので,いい感じの方法が必要だと思う

例2: Python の場合

Python で速度を維持するには, numpy などを使いたい. ここでは,Dockerを例として使ってみる.

# これは Dockerfile です
FROM ubuntu:14.04

RUN apt-get update
RUN apt-get install python3 python3-numpy

# 自分はnumpy使える
ENTRYPOINT run.sh # ここは良い感じのコマンドにしたい

この環境下では,Numpyが使える.

import numpy as np
...

例3: C++の場合

Docker と Makefile を使う.

# これは Dockerfile です
FROM ubuntu:14.04

RUN apt-get update
RUN apt-get install clang++ boost

# 自分はnumpy使える
ENTRYPOINT run.sh # ここは良い感じのコマンドにしたい
CXX = clang++ # コンパイラ指定
CPP_FILE = main.cpp
CFLAGS = -O2 -Wall -std=c++11 -Wall -DDEBUG -lboost # コンパイルオプションも指定,boostも使えるよ
PROGRAM = ./a.out

all: $(PROGRAM)

$(PROGRAM):$(CPP_FILE)
    $(CXX) $(CFLAGS) $(CPP_FILE) -o $(PROGRAM)

感想

だれかやってほしい.

追記

どうにも難しいことはいろいろありそうだ.