13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[C++] 競プロで面倒なコンパイルコマンド入力をzshのSuffix Aliasesでいい感じにする

Posted at

C++のプログラムのコンパイルは以下のようなコマンドで行いますが、速度が求められる競技プログラミングではタイピングの時間がもったいなく感じます。

$ g++ -o hoge hoge.cpp

C++14とデバッグのオプションをつけると、こんなに長くなってします。

$ g++ -std=c++14 -g -O0 -o hoge hoge.cpp

私はコンテスト開始前に上記のコマンドを入力しておき、シェルの履歴を利用して時間短縮をしていたのですが~~(アホくさ)~~、zshのSuffix Aliasesという素晴らしい機能でそれが改善できたので、記事にしました。

環境

macOS 10.13.5
zsh 5.5.1

zshとは

シェルの一つです。強力な補完やワイルドカードを利用したファイルの指定、コマンド修正など便利な機能が盛りだくさんです。私は最近使い始めたのですが、大変満足しています。

Suffix Aliasesとは

Suffix Aliasesはzshの便利な機能の一つです。ファイルの拡張子に関連したエイリアスを作成し、ファイル名を打ち込むだけでそのエイリアスを実行することができるようになります。
例えば、hoge.pyを実行するときは

$ python hoge.py

と実行すると思いますが、Suffix Aliasesでファイル名だけで実行できます。

$ alias -s py=python # エイリアスの作成
$ hoge.py            # python hoge.pyと同じ

やりたいこと

Suffix Aliasesを使ってC++のプログラムのコンパイルとプログラムの実行を

$ hoge.cpp

で自動で行えるようにします。プログラムの実行だけをしたい時にコンパイルをすることは無駄なので、ファイルの更新日時を見て、コンパイルが必要か判断することにします。以下のフローに詳細を示します。

flow.png

シェルスクリプトを書く

~/.zshrcに以下を追加します

~./zshrc
function with_echo() {
  echo $@
  $@
}

function cpp_compile() {
  with_echo g++ -std=c++14 -g -O0 -o $1 $2
}

function cpp_run() {
  cpp_file=$1
  exe_file=${cpp_file:0:-4}
  shift

  if [ -s $cpp_file ]; then
    if [ ! -f $exe_file ]; then
      cpp_compile $exe_file $cpp_file && ./$exe_file $@
    else
      cpp_date=`date -r $cpp_file +%s`
      exe_date=`date -r $exe_file +%s`
      if [ $cpp_date -gt $exe_date ]; then
        cpp_compile $exe_file $cpp_file && ./$exe_file $@
      else
        ./$exe_file $@
      fi
    fi
  else
    echo $cpp_file is empty
  fi
}

alias -s cpp=cpp_run

with_echo()

echoで実行するコマンドを出力してから、コマンドを実行します。

cpp_compile()

C++14とデバッグのオプションをつけてg++でコンパイルをします。with_echo()でコンパイルが行われたことを示します。

cpp_run()

$1でコンパイル対象のファイル名を取得し、${cpp_file:0:-4}で実行ファイル名を作成します。また、if [ -s $cpp_file ]if [ ! -f $exe_file ]if [ $cpp_date -gt $exe_date ]がフローチャートの分岐に対応しています。
cpp_dateexe_dateは、C++のプログラムファイルと実行ファイルの更新日時のUNIX時間を変数に入れたもので

date -r $file_name +%s

で取得することができます。

cpp_compile $exe_file $cpp_file && ./$exe_file $@

shiftで引数を一つずらすことで$@で必要なコマンドライン引数を全取得できるようにし、&&でコンパイルが成功した場合のみプログラムをそのまま実行するようにします。

結果

result.png

最高ですね!!!!!

おわりに

プログラムのコンパイルと実行が$ hoge.cppだけで済むようになったので、めっちゃ捗ってます。皆さんもこの方法で一秒でも早くプログラムを提出しちゃってください!

13
5
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
13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?