AndroidスマホにAtCoder精進用CLI環境を構築してみた


# はじめに

競技プログラミングの精進中、電車の中とかで解法を思いついて急にコードを書きたくなることって、ありますよね。あることにします。

個人的に、そんなときに手元にはAndroidスマホ1台しかない、という状況がよくあるので、それでも最低限なんとかできる環境を整えてみました。

スマホの物理的に狭く誤操作しやすいスペースで、VSCodeなどのリッチなアプリを操作したり、複数のアプリを並行して使用するのが面倒だったので、できるだけ端末(CLI)1枚に閉じて完結する環境を目指した結果、自分なりには満足できる環境が整いました。

この記事はその作業メモです。

:::note info
あくまで自分の環境ではこれで出来ましたよという記録です。構築手順や安全な環境を保証するものではありませんので、ご了承ください。
:::

# 環境

+ 端末： Xperia 10 VI SOG14
+ Anodoid バージョン: 14
+ 使用言語 : C++

# 動作イメージ

最終的にこんな感じになります。(gif 1分43秒)(クリックして拡大)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798407/a25a2bbd-b205-4cdf-5c60-c3816a12ae4c.gif" width="120px">

# 手順
## termux をインストール

[termux](https://github.com/termux) はAndroid上で使用できる端末エミュレータです。READMEなどによると、Googel Play ストアでの更新やサポートは終了しているということなので、[F-Droid](https://f-droid.org/) からダウンロードしてインストールします。

https://f-droid.org/ja/packages/com.termux/

:::note warn
セキュリティ面のリスクは自己判断でお願いします
:::

## コンパイル環境を整える

C/C++ コンパイラと、使用したいテキストエディタをインストールします。

termux 内の環境はある種の疑似環境のようで、sudo などによるユーザ権限の切り替えは不要だそうです。使用するパッケージも termux 用にビルドされたものだそうなので、 `pkg` というコマンドを使用します。使い勝手はほぼ apt と同様だと思います。

```bash
$ termux-change-repo
$ pkg upgrade -y
$ pkg install -y neovim
$ pkg install -y clang
```

### コンパイルオプションのalias定義

コンパイル時にいちいちオプションを手書きするのが面倒なので `bash` に alias 定義を追加しました。

`clang` は `gcc(g++)` とは別のコンパイルドライバですが、自身を gcc(g++) に見せかける状態をインストール時に作成するので、慣れた名前のそちらを使用します。

ついでに、スマホのソフトキーボードで `+` を入力するのが地味に面倒だったので、普段は "gcc" を使用することにしました。 

```.bashrc
alias g++="g++ --std=c++20 -g -O0 -Wall"
alias gcc="g++"
```

## atcoder-cli のインストール

結果からいうとそれほど特別なことはなく、[atcoder-cliの開発者様のブログ](http://tatamo.81.la/blog/2018/12/07/atcoder-cli-installation-guide/) など先達のノウハウを参考にさせていただいて構築できました。

ただし、termux の初期状態では、今どきの linux ディストロの最小インストールでも入るような、かなり基礎的なコマンドもインストールされていませんので、**エラーになった場合は随時足りないパッケージを追加していく** 必要があります。（今後の作業はすべて同様）

エラーになった場合は、ログをさかのぼるとエラーが出始めたあたりに「このコマンドが見つからない」という警告があるはずです。足りないと言われたコマンドを実際に投入してみると、このパッケージをインストールしろというメッセージが出る親切設計なので、難しいことはないと思います。

### Node.js, Python3 のインストール

[atcoder-cli](https://github.com/Tatamo/atcoder-cli) と [online-judge-tools](https://github.com/online-judge-tools/oj) 用に Node.js と Python3 をインストールします。

```pkg
$ pkg install -y nodejs python3
```

`npm` コマンドで atcoder-cli をインストールします

```npm
$ npm update -g npm
$ npm install -g atcoder-cli
```

## online-judge-tools のインストール

`pip3` コマンドで、online-judge-tools をインストールします。

```pip3
$ pip3 install online-judge-tools
```

### おそらく追加が必要なパッケージ

私の環境の場合は online-judge-tools のインストール時に以下のパッケージの追加が必要になりました。

  + python-lxml
  + rust

```bash
$ pkg install -y python-lxml rust
```

# 動作確認

## コンテストディレクトリを作成

実際に AtCoder にコードを提出できるかを確認します。適当なコンテストを選んで `acc new` で作業ディレクトリを作成します。

```bash
$ acc new abc001
```

### おそらく追加が必要なパッケージ

私の環境では python の `distutils` パッケージがないというエラーが発生しました。検索してみるとこちらは[現在は廃止されたパッケージとのことでした](https://qiita.com/pitao/items/1740a62ddee797aed807)ので、代わりに `setuptools` モジュールを追加します。

```pip3
$ pip3 install setuptools
```

## 提出用コードの作成

acc new コマンドが正常に終了したら作成されたディレクトリ配下で提出用のコーディングをします。
コーディングができたらローカルでコンパイルします。

```bash
$ cd abc001/a
$ vi main.cpp
$ g++ main.cpp
```

このタイミングで自分がコンパイルに使いそうなパッケージを追加でインストールしました。 

  + binutils
  + ld
  + ldd

```bash
$ pkg install -y binutils ld ldd 
```

### コンパイル時にライブラリが見つからないエラーがでる場合

`clang` をインストールしたままのシェルで作業している場合は、いったんログアウトして termux を再実行すると解決するような気がします。 


## サンプルを使用したローカルテストの実行

`oj t` コマンドを使用してあらかじめダウンロードされているサンプルを使用したテストを実行します。

```bash
$ oj t -d tests
```

テストの実行はできましたが、GNU time がないという警告が出たので追加しました。

```bash
$ pkg install -y time 
```

## オンラインジャッジへのコード提出

`acc submit` コマンドを使用して、AtCoder にコードを提出します。
提出前に `acc login` で AtCoder にログインしておきます。

```bash
$ acc login
$ acc submit main.cpp
```

ログイン状態に関するエラーが出る場合は、出力されている内容に従って、いったん `oj login` コマンドで online-judge-tools 側でログインした実績を作れば、うまくいくと思います。

![nobrowser.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798407/34804ba5-f110-6034-3020-db1a24a29361.png)

termux の場合上記のような「Webブラウザが実行できない」旨のエラーが出ると思いますが、前段が SUCCESS になっていれば提出は成功していますので、別のWebブラウザから提出結果にアクセスすれば、結果を確認できます。

以上で最低限の環境構築は終了です。ここからの環境改善は先達のノウハウと同様だと思いますので、ご自分の好みに合わせて環境を変更してください。

# おまけの環境構築（非推奨部分）

## bits/stdc++.h作成

競プロ勢が好んで使う bits/stdc++.h は本来 GNU が配置しているものなので、`clang` を使用する本環境には存在しません。が、面倒くさいので自分は手で作ってしまいました。

具体的には、/data/data/com.termux/files/usr/include/c++/v1/bits/stdc++.h を勝手に作って、中身で c++/v1 配下にあるヘッダファイルを全部 include しただけのファイルを作成しています。

## 提出結果取得用Webスクレイピングスクリプト

ジャッジ提出時、提出結果を見るためにWebブラウザを操作するのが面倒だな、CLIで表示できないかな、と思ってしまったので、なんとかしようとしたら、なんとかなってこんな感じになりました。

![browser.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798407/e4fa8531-7fac-8863-33a3-8be99f18d9b5.png)

不具合とかの責任を負いたくないので迷いましたがせっかくので GitHub に公開しておきました。GitHubの使用自体初めてなので、手違いなどはご容赦ください。使用は自己責任でお願いします。

https://github.com/DaisukeTK/alt_browser_acc

## コード提出時の確認プロンプト

online-judge-tools の仕様により、コードの提出時には確認プロンプトが表示されます。

![confirm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798407/0e9b2ace-2e60-344e-f122-dfcb047ee92f.png)

ソースを覗いてみたところ、上記の警告は `acc new` が作成するディレクトリパスと `oj` 側が想定しているパスが食い違っていることが原因のように見えましたが、環境を整えて警告がでないようにしたとしても、結局 Yes or No のプロンプトは出力されるようです。

自分の使い方の範囲で、`acc` を使用して AtCoder のみを対象にしている限りはここでミスオペしている可能性はまずないはずなので、作者様に失礼かなと思いましたが、ローカルのスクリプトを少し弄ってプロンプトの表示を抑止しています。

具体的には、submit.py の run 関数内の confirm の処理部分をコメントアウトしています。

# さいごに

有用なツールを公開してくださっている方々に感謝します。利用されている方は、ぜひ GitHub にスター★(いいね的なもの)をつけにいきましょう。

https://github.com/termux 

https://github.com/Tatamo/atcoder-cli

https://github.com/online-judge-tools/oj