【どこでも精進】競プロのためのC++スマホコーディング環境構築　※iOS限定

競プロが好きな人の多くは、できるだけ多くの精進時間を確保したいと考えていると思います。そのため、通勤・通学などで電車移動する際に競プロの問題を考察するという人も多いかと思います。しかし、電車内ではパソコンを開くことができず、考察ができても実装ができないためもやもやすることが多いのではないでしょうか？

ただ、AtCoderに用意されているコードテストは、スマホから操作することを想定されていないため、非常に不便に感じるかと思います。

そこで、この記事ではアプリを使って競プロの環境構築を行うことで、比較的楽に実装を行えるようにする方法を説明します。

:::note alert
2025年6月現在、本記事で扱っているアプリがApp Storeから削除されているようです。申し訳ございません。
:::

:::note warn
本記事は、iOSのみを対象としています。Androidにも同様のアプリはあるようですが、私が実機を持っておらずテストできないため対象外とします。Android端末をご使用の方は申し訳ございません。
:::

:::note warn
iOS15以降にする必要があります。また、iOSのバージョンによっては動かない場合があるそうです。(具体的なバージョンは不明ですが、1年ぐらい前に試してできなかったとの情報をいただいています。1年以上アップデートしてない人はしましょう)
ちなみに、私の環境はiPhone 11 / iOS 16.5.1(c)です。
:::

## 目次

[1. アプリのインストール](#1-アプリのインストール)
[2. bits/stdc++.hの導入](#2-bitsstdchの導入)
[3. AtCoder Libraryの導入](#3-atcoder-libraryの導入)
[4. 提出方法](#4-提出方法)
[5. AtCoder Easy Testの導入](#5-atcoder-easy-testの導入)
[6. マクロのすすめ](#6-マクロのすすめ)
[7. おわりに](#7-おわりに)


## 1. アプリのインストール

:::note alert
2025年6月現在、本記事で扱っているアプリがApp Storeから削除されているようです。申し訳ございません。
:::

本記事では、モバイルCのいうアプリを使います。App Storeで「モバイルC」と検索し、画像のアプリをインストールしてください。

![IMG_7126.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420070/4dc4fd95-5379-705e-8255-50b847fab07d.jpeg)

スワイプでカーソルを動かしたり範囲選択したりできる機能がかなり便利です。iOSのC++実行環境をいくつか試しましたが、この機能の1点でモバイルCを採用しました。

:::note warn
モバイルCはよく落ちます。コードはこまめに保存しましょう。
:::

## 2. bits/stdc++.hの導入

bits/stdc++.hとは、C++の標準ライブラリを片っ端からincludeできる便利なファイルです。しかし、残念ながらモバイルCはbits/stdc++.hに対応していません(Clangなので)。なので、自分で用意しましょう。

### bitsフォルダの作成
コーディングを行うファイルと同じ階層で左上のフォルダ作成ボタンを押し、bitsというフォルダを作成します。

### stdc++.hファイルの作成
bitsフォルダに移動し、左上のファイル作成ボタンを押し、stdc++.hというファイルを作成します。

次に、以下のソースコードをstdc++.hにコピペします。

<details><summary>ソースコード</summary><div>


```cpp:stdc++.h
// C++ includes used for precompiling -*- C++ -*-

// Copyright (C) 2003-2022 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file stdc++.h
 *  This is an implementation file for a precompiled header.
 */

// 17.4.1.2 Headers

// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <csetjmp>
#include <cstdarg>
#include <cstddef>
#include <cstdlib>

#if __cplusplus >= 201103L
#include <cstdint>
#endif

// C++
// #include <bitset>
// #include <complex>
#include <algorithm>
#include <bitset>
#include <functional>
#include <iterator>
#include <limits>
#include <memory>
#include <new>
#include <numeric>
#include <typeinfo>
#include <utility>

#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <initializer_list>
#include <ratio>
#include <scoped_allocator>
#include <tuple>
#include <typeindex>
#include <type_traits>
#endif

#if __cplusplus >= 201402L
#endif

#if __cplusplus >= 201703L
#include <any>
// #include <execution>
#include <optional>
#include <variant>
#endif

#if __cplusplus >= 202002L
#include <bit>
#include <compare>
#include <concepts>
#include <numbers>
#include <ranges>
#include <span>
#include <source_location>
#include <version>
#endif

#if __cplusplus > 202002L
#include <expected>
#include <stdatomic.h>
#if __cpp_impl_coroutine
# include <coroutine>
#endif
#endif


#if _GLIBCXX_HOSTED
// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cwchar>
#include <cwctype>

#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cuchar>
#endif

// C++
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <codecvt>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif

#if __cplusplus >= 201402L
#include <shared_mutex>
#endif

#if __cplusplus >= 201703L
#include <any>
#include <charconv>
// #include <execution>
#include <filesystem>
#include <optional>
#include <memory_resource>
#include <string_view>
#include <variant>
#endif

#if __cplusplus >= 202002L
#include <barrier>
#include <bit>
#include <compare>
#include <concepts>
#include <format>
#include <latch>
#include <numbers>
#include <ranges>
#include <span>
#include <stop_token>
#include <semaphore>
#include <source_location>
#include <syncstream>
#include <version>
#endif

#if __cplusplus > 202002L
#include <expected>
#include <spanstream>
#if __has_include(<stacktrace>)
# include <stacktrace>
#endif
#include <stdatomic.h>
#include <stdfloat>
#endif

#endif // HOSTED

```

</div></details>

※このソースコードは、[gccのbits/stdc++.h](https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=libstdc%2B%2B-v3/include/precompiled/stdc%2B%2B.h)のうち、モバイルCで使用した際にエラーが出た部分をコメントアウトしたものです。

### コードの実行
もとの階層に戻り、`test.cpp`というファイルを作成してください。

:::note warn
ファイル作成時、デフォルトで拡張子が.cになっていますが、.cppにしないと動かないので注意してください。
:::

test.cppに、以下のコードをコピペして実行してみてください。`Hello,world!`が出力されたら成功です。

```cpp:test.cpp
#include "bits/stdc++.h"
using namespace std;
int main(){
	cout << "Hello,world!\n";
}
```

`#include<bits/stdc++.h>`だと動かないので、`#include "bits/stdc++.h"`を使っていることに注意してください。なお、AtCoderに提出する際にこの表記のままでも問題なく動きます。



## 3. AtCoder Libraryの導入

AtCoderをやるときにAtCoder Library(ACL)を使いたい人は多いと思います。そこで、モバイルCにACLを導入する方法を説明します。

### ACLリポジトリのクローン
モバイルCでは、なんとgitの一部機能が使えます。

ファイル選択画面下部の`>_`と書かれたボタンを押します。

![IMG_7566.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420070/83c26406-1035-e46d-c3e1-3827e3c7f333.jpeg)



するとターミナルが開くので、以下のコマンドをコピペして実行してください。
```bash
git2 clone https://github.com/atcoder/ac-library.git ACL
cp ACL/atcoder .
```

ファイル一覧に戻ると、`ACL`というフォルダと`atcoder`というフォルダができていると思います。
`atcoder`の方を開くと、`dsu`や`fenwicktree`など拡張子がついていないファイルがたくさんあると思います。これらはファイルの中身が`#include "atcoder/hoge.hpp"`という形式の文字列になっているので、これらをすべて`#include hoge.hpp`に書き換えます。かなり面倒ですが、がんばってください。

これで、ACLの導入は完了です。`test.cpp`で以下のコードを実行し、動作確認を行ってみましょう。`Hello,world!`と表示されたら成功です。

```cpp:test.cpp
#include "bits/stdc++.h"
#include "atcoder/all"
using namespace std;
using namespace atcoder;
int main() {
	cout << "Hello,world!\n";
}
```

## 4. 提出方法
実装が終わってサンプルが合ってることも確認できたら、さっそく提出しましょう。

コードのコピペは結構面倒なので、ファイルを選択して提出します。AtCoderのコードを書くフォームの下に「ファイルを開く」というボタンがあるので押してください。すると、iOSのファイル選択画面が開くと思うので、`このiPhone内/モバイルC/Data/CCR/UserFiles/作成したファイル.cpp` を選択します。するとコードが入力されるので、提出ボタンを押して提出しましょう。

:::note warn
コード編集後、ファイルを選択する前にコードを保存することを忘れないようにしましょう。保存ボタンを押すか、コードを実行することで保存されます。
:::

ところで、みなさんはこの機能を使ったことはありましたか？私はPCでは基本VSCodeからのコピペなので、スマホコーディングするようになるまでこの機能自体知りませんでした。

## 5. AtCoder Easy Testの導入
毎回サンプルをコピペしてテストしてもよいのですが、ブラウザとモバイルCを切り替えながらテストするのは少し面倒です。
そこで、AtCoder Easy Testというツールを導入してみましょう。
AtCoder Easy Testは、AtCoderなどのコンテストサイトでソースコードを提出欄に入力するだけで自動でサンプルのテストを行ってくれるツールです。詳しくはこちらの記事をご覧ください：[AtCoder Easy Test を支える技術](https://qiita.com/magurofly/items/4b60dc02283e70230f71)

### Userscriptsインストール
パソコンでユーザースクリプトを使うときはTampermonkeyなどが便利ですが、残念ながらiOSには対応していません。そこで、iOSのSafariでスクリプトを動かすために、Userscriptsというアプリを使用します。

AppStoreで`Userscripts`と検索し、画像のアプリをインストールしてください。

![IMG_7552.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420070/41f65317-3104-34fe-aa15-9d4dd19a02ab.jpeg)


### Userscriptsアプリの設定
先ほどダウンロードしたアプリを開き、`Set Userscripts Directory`ボタンを押します。するとiOSのファイル選択画面が開くので、適当なフォルダを作成してそのフォルダを選択し、右上の開くボタンを押します。

### Safariの機能拡張を有効化
iOSの設定アプリを開き、Safari>機能拡張　からUserscriptsをオンに変更します。


### EasyTestのソースコードをUserscriptに導入
[EasyTestのインストールページ](https://greasyfork.org/ja/scripts/433152-atcoder-easy-test-v2)を開きます。
`スクリプトのインストール`と書かれたボタンを長押しするとメニューが出てくるので、`リンク先のファイルをダウンロード`を選択します。


:::note warn
普通にボタンを押すだけだと、ソースコードが画面に表示されるだけでダウンロードできません。
:::

ダウンロードが終わったら、URL欄のパズルのボタンを押します。

![IMG_7553.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420070/f00f2a93-666d-40b0-0971-77866f3a0ba9.jpeg)


するとメニューが表示されるので、`ダウンロード`を選択してください。

そしたらファイル一覧みたいなやつが出てくるので、AtCoder Easy Test v2.userの右側にある虫眼鏡のボタンを押します。

![IMG_7554.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420070/03a459ef-5037-1fd4-8dda-b11dd90242ca.jpeg)

すると、またiOSのファイル選択画面が開くので、AtCoder Easy Test v2.userを長押しし、出てきたメニューの`移動`を押し、先ほどUserscriptアプリで設定したフォルダに移動させます。


### スクリプトの有効化
[なんでもいいのでAtCoderの問題](https://atcoder.jp/contests/abc313/tasks/abc313_a)を開きます。

次に、URL欄の左側のパズルのボタンを押し、メニューの`Userscript`を選択します。

するとこのような画面が出てきます。(私はac-predictorも入れていますが気にしないでください)

![IMG_7555.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420070/c60dce9a-f6af-7091-70ff-0d48b4e3510b.jpeg)

右上のスイッチを青くなるように変更し、AtCoder Easy Test v2を押して明るくしてください。

ここまで完了したら、全て閉じてブラウザを再起動してみてください。AtCoderの提出欄の近くにボタンが増えていたら成功です。

![IMG_7556.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/420070/ba69e2be-11cf-6378-d5a3-ddaacae1ad29.jpeg)

## 6. マクロのすすめ

スマホコーディングは、フリック入力や小さいソフトウェアキーボードなどで入力する必要があり、結構大変です。特に、C++は記述量も多く疲れてしまいます。
そこで、スマホ用のテンプレートを作成することをおすすめします。
たとえば、あの悪名高い(？) [repマクロ](https://atcoder.jp/contests/apg4b/tasks/APG4b_an?lang=ja)などは記述量を減らすのにかなり役立ちます。

下記のマクロは特に使用頻度が高く非常におすすめです。
```C++
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define vec vector
#define all(a) a.begin(), a.end()
#define pb push_back 
```

普段はマクロを使わないという人でも、スマホコーディングするときは使ってみてはどうでしょうか？（ちなみに、私はもともとrepマクロを使わない派だったのですが、スマホで使うようになってからはPCでも使うようになりました）

ぜひみなさんも自分に合ったいろんなマクロを作ってみてください。

:::note warn
変数名や関数名がマクロ名と被らないように注意しましょう。
:::

## 7. おわりに
環境を構築することで、スマホでも割と快適に精進できます。
この記事がみなさんの精進時間の増加やレート向上につながれば幸いです。

#### おまけ
問題の考察をするとき、紙などに書いて考察したい人が多いと思います。しかし、電車の中などでは、紙とペンを使うのはなかなか大変です。また、iPadは重いし結構高いペンをなくしそうで怖いです。そこで、**電子メモパッド**がおすすめです。ダイソーなどで500円ぐらいで買えます。

:::note warn
まわりの人の迷惑にならないように注意しましょう。
:::