作成したアルゴリズムが行進する

11日目の記事は @okateim さんの [「最短包含区間問題」](https://qiita.com/okateim/items/99bc26e8757f9c45e3e9) でした。

※[注意]この記事はネタです。

#"アルゴリズムこうしん"とは

>アルゴリズムたいそう / アルゴリズムこうしんとは、NHK教育「ピタゴラスイッチ」の中で行われる体操のようなレクリエーションである。
>[(引用: ニコニコ大百科 - アルゴリズムこうしん)](https://dic.nicovideo.jp/a/%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%93%E3%81%86%E3%81%97%E3%82%93)

詳しくはNHK教育の"ピタゴラスイッチ"を見てください。

#行進の状態

|ID|掛け声(状態)|備考|
|:---|:---|:---|
|0|( いっぽ すすむ だけ )|最初の状態|
|1|いっぽ すすんで まえならえ|メイン行進の1番目|
|2|いっぽ すすんで えらいひと|メイン行進の2番目|
|3|ひっくりかえって ぺこりんこ|メイン行進の3番目|
|4|よこにあるいて きょろきょろ|メイン行進の4番目|
|5|ちょっと ここらで ひらおよぎ|メイン行進の5番目|
|6|ちょっと しゃがんで くりひろい|メイン行進の6番目|
|7|くうき いれましょ シュウッ シュウ|メイン行進の7番目|
|8|くうきが はいって ピュウッ ピュウ|メイン行進の8番目|
|9|そろそろ おわりかな|終了にかけての行進|
|10|おわり|行進終了|

この辺は**`enum`**でまとめましょう。

```cpp:enum
	enum algorithm_march_name :size_t {
		empty,
		maenarae,
		eraihito,
		pekorinko,
		kyorokyoro,
		hiraoyogi,
		kurihiroi,
		shushu,
		pyupyu,
		owarikana,
		owari,
	};
```

また、文章もまとめます。

```cpp:string
	constexpr std::array<const char* const, 11> algorithm_march_string{{
	"",
	"いっぽ すすんで まえならえ",
	"いっぽ すすんで えらいひと",
	"ひっくりかえって ぺこりんこ",
	"よこにあるいて きょろきょろ",
	"ちょっと ここらで ひらおよぎ",
	"ちょっと しゃがんで くりひろい",
	"くうき いれましょ シュウッ シュウ",
	"くうきが はいって ピュウッ ピュウ",
	"そろそろ おわりかな",
	"おわり"
	}};
```

行進の状態を**蝶々に例えると**

|状態|蝶々|
|:---|:---|
|最初の状態|卵|
|メイン行進|幼虫|
|終了にかけての行進|さなぎ|
|行進終了|成虫|

こんな感じです。~~例えがわかりにくすぎる~~

#行進に使う変数はクラスにまとめておきます。

```cpp:The_Algorithm_March.hpp
	class AlgorithmMarch {
	private:
		//行進(更新)カウンタ
		size_t update_counter = 0;
		//メイン行進のループ数
		size_t main_loop = 2;
		size_t main_loop_counter = 0;
		//おわりかなのループ数
		size_t end_loop = 5;
		size_t end_loop_counter = 0;
		bool is_end_loop = false;
		bool is_end = false;
		//行進するメンバー数
		size_t people_num;
		std::unique_ptr<size_t[]> people;
	};
```

これにて完成です。

#全体のソースコード

```cpp:The_Algorithm_March.hpp
//------------------------------
//The Algorithm March
//------------------------------

#pragma once
#include <array>
#include <vector>
#include <string>
#include <memory>
#include <iostream>

namespace march {

	enum algorithm_march_name :size_t {
		empty,
		maenarae,
		eraihito,
		pekorinko,
		kyorokyoro,
		hiraoyogi,
		kurihiroi,
		shushu,
		pyupyu,
		owarikana,
		owari,
	};

	constexpr std::array<const char* const, 11> algorithm_march_string{{
	"",
	"いっぽ すすんで まえならえ",
	"いっぽ すすんで えらいひと",
	"ひっくりかえって ぺこりんこ",
	"よこにあるいて きょろきょろ",
	"ちょっと ここらで ひらおよぎ",
	"ちょっと しゃがんで くりひろい",
	"くうき いれましょ シュウッ シュウ",
	"くうきが はいって ピュウッ ピュウ",
	"そろそろ おわりかな",
	"おわり"
	}};

	class AlgorithmMarch {
	private:
		//行進(更新)カウンタ
		size_t update_counter = 0;
		//メイン行進のループ数
		size_t main_loop = 2;
		size_t main_loop_counter = 0;
		//おわりかなのループ数
		size_t end_loop = 5;
		size_t end_loop_counter = 0;
		bool is_end_loop = false;
		bool is_end = false;
		//行進するメンバー数
		size_t people_num;
		std::unique_ptr<size_t[]> people;

	public:
		//コンストラクタ
		//AlgorithmMarch(行進のループ数, "おわりかな"の回数, 行進する人数)
		AlgorithmMarch(const size_t main_, const size_t end_, const size_t num_)
			:main_loop(main_), end_loop(end_), people_num(num_), people(new size_t[num_]) {
			for (size_t i = 0; i < num_; ++i) people[i] = empty;
		}
		//コンストラクタ
		//AlgorithmMarch(行進する人数)
		AlgorithmMarch(const size_t num_)
			: people_num(num_), people(new size_t[num_]) {
			for (size_t i = 0; i < num_; ++i) people[i] = empty;
		}

		size_t updateCounter() const { return update_counter; }
		size_t mainLoop() const { return main_loop; }
		size_t mainLoopCounter() const { return main_loop_counter; }
		size_t endLoop() const { return end_loop; }
		size_t endLoopCounter() const { return end_loop_counter; }
		bool isEndLoop() const { return is_end_loop; }
		bool isEnd() const { return is_end; }
		//行進する人数を返す
		size_t peopleNum() const { return people_num; }
		
		//指定したIDの人の行進状態を返す
		size_t peopleArrayID(const size_t id_) const { return people[id_]; }

		//人々の行進状態をstd::vectorに入れる
		void peopleVector(std::vector<size_t>& people_vector_) {
			people_vector_.resize(people_num);
			for (size_t i = 0; i < people_num; ++i) people_vector_[i] = people[i];
		}
		//人々の行進状態を配列に入れる
		void peopleArray(size_t* const people_vector_) {
			for (size_t i = 0; i < people_num; ++i) people_vector_[i] = people[i];
		}

		int statusUpdateMain(const size_t id_) {
			switch (people[id_])
			{
			case empty:
				people[id_] = maenarae;
				return 1;
			case owarikana:
			case owari:
				break;
			case pyupyu:
				people[id_] = maenarae;
				break;
			default:
				++people[id_];
				break;

			}
			return 0;
		}

		//行進を更新
		int statusUpdate(const size_t id_) {

			if (is_end) {
				for (size_t i = 0; i < people_num; ++i) people[i] = owari;
				return 3;
			}
			if (end_loop_counter > 0 && people[id_] != owarikana) {
				people[id_] = owarikana;
				for (size_t i = id_ + 1; i < people_num; ++i) statusUpdateMain(i);
				return 2;
			}
			return statusUpdateMain(id_);
		}

		void mainLoopUpdate() {
			if (update_counter % 8 == 0) {
				if (main_loop == main_loop_counter) is_end_loop = true;
				++main_loop_counter;
			}
			++update_counter;
		}

		void endLoopUpdate() {
			if (!is_end_loop) return;
			if (end_loop == end_loop_counter) is_end = true;
			++end_loop_counter;
		}

		void statusUpdate() {
			//"おわり"だったら終了
			if (is_end) return;
			mainLoopUpdate();
			endLoopUpdate();
			for (size_t i = 0; i < people_num; ++i) if (statusUpdate(i)) break;
		}

		void print(const size_t id_) {
			std::cout << algorithm_march_string[people[id_]];
		}
		void print(const size_t id_, const std::array<const char* const, 11>& message_) {
			std::cout << message_[people[id_]];
		}

		void print() {
			for (size_t i = 0; i < people_num; ++i) print(i);
		}
		void print(const std::array<const char* const, 11>& message_) {
			for (size_t i = 0; i < people_num; ++i) print(i, message_);
		}

		void print(const std::string& str_) {
			for (size_t i = 0; i < people_num; ++i) {
				print(i);
				std::cout << str_;
			}
		}
		void print(const std::string& str_, const std::array<const char* const, 11>& message_) {
			for (size_t i = 0; i < people_num; ++i) {
				print(i, message_);
				std::cout << str_;
			}
		}

	};

}
```

```cpp:Source.cpp
#include "The_Algorithm_March.hpp"

int main() {

	//行進を作成(行進のループ数, "おわりかな"の回数, 行進する人数)
	march::AlgorithmMarch am(3, 10, 5);
	
	//行進メインループ
	while(!am.isEnd()) {
		
		//行進を更新
		am.statusUpdate();

		//参加者の行進を"/"で区切る
		am.print("/", march::algorithm_march_string);

		//1ターンの行進が終わったら改行
		std::cout << std::endl;
	}

	return 0;
}
```

#実行結果

```出力
いっぽ すすんで まえならえ/////
いっぽ すすんで えらいひと/いっぽ すすんで まえならえ////
ひっくりかえって ぺこりんこ/いっぽ すすんで えらいひと/いっぽ すすんで まえならえ///
よこにあるいて きょろきょろ/ひっくりかえって ぺこりんこ/いっぽ すすんで えらいひと/いっぽ すすんで まえならえ//
ちょっと ここらで ひらおよぎ/よこにあるいて きょろきょろ/ひっくりかえって ぺこりんこ/いっぽ すすんで えらいひと/いっぽ すすんで まえならえ/
ちょっと しゃがんで くりひろい/ちょっと ここらで ひらおよぎ/よこにあるいて きょろきょろ/ひっくりかえって ぺこりんこ/いっぽ すすんで えらいひと/
くうき いれましょ シュウッ シュウ/ちょっと しゃがんで くりひろい/ちょっと ここらで ひらおよぎ/よこにあるいて きょろきょろ/ひっくりかえって ぺこりんこ/
くうきが はいって ピュウッ ピュウ/くうき いれましょ シュウッ シュウ/ちょっと しゃがんで くりひろい/ちょっと ここらで ひらおよぎ/よこにあるいて きょろきょろ/
いっぽ すすんで まえならえ/くうきが はいって ピュウッ ピュウ/くうき いれましょ シュウッ シュウ/ちょっと しゃがんで くりひろい/ちょっと ここらで ひらおよぎ/
いっぽ すすんで えらいひと/いっぽ すすんで まえならえ/くうきが はいって ピュウッ ピュウ/くうき いれましょ シュウッ シュウ/ちょっと しゃがんで くりひろい/
ひっくりかえって ぺこりんこ/いっぽ すすんで えらいひと/いっぽ すすんで まえならえ/くうきが はいって ピュウッ ピュウ/くうき いれましょ シュウッ シュウ/
よこにあるいて きょろきょろ/ひっくりかえって ぺこりんこ/いっぽ すすんで えらいひと/いっぽ すすんで まえならえ/くうきが はいって ピュウッ ピュウ/
ちょっと ここらで ひらおよぎ/よこにあるいて きょろきょろ/ひっくりかえって ぺこりんこ/いっぽ すすんで えらいひと/いっぽ すすんで まえならえ/
ちょっと しゃがんで くりひろい/ちょっと ここらで ひらおよぎ/よこにあるいて きょろきょろ/ひっくりかえって ぺこりんこ/いっぽ すすんで えらいひと/
くうき いれましょ シュウッ シュウ/ちょっと しゃがんで くりひろい/ちょっと ここらで ひらおよぎ/よこにあるいて きょろきょろ/ひっくりかえって ぺこりんこ/
くうきが はいって ピュウッ ピュウ/くうき いれましょ シュウッ シュウ/ちょっと しゃがんで くりひろい/ちょっと ここらで ひらおよぎ/よこにあるいて きょろきょろ/
いっぽ すすんで まえならえ/くうきが はいって ピュウッ ピュウ/くうき いれましょ シュウッ シュウ/ちょっと しゃがんで くりひろい/ちょっと ここらで ひらおよぎ/
いっぽ すすんで えらいひと/いっぽ すすんで まえならえ/くうきが はいって ピュウッ ピュウ/くうき いれましょ シュウッ シュウ/ちょっと しゃがんで くりひろい/
ひっくりかえって ぺこりんこ/いっぽ すすんで えらいひと/いっぽ すすんで まえならえ/くうきが はいって ピュウッ ピュウ/くうき いれましょ シュウッ シュウ/
よこにあるいて きょろきょろ/ひっくりかえって ぺこりんこ/いっぽ すすんで えらいひと/いっぽ すすんで まえならえ/くうきが はいって ピュウッ ピュウ/
ちょっと ここらで ひらおよぎ/よこにあるいて きょろきょろ/ひっくりかえって ぺこりんこ/いっぽ すすんで えらいひと/いっぽ すすんで まえならえ/
ちょっと しゃがんで くりひろい/ちょっと ここらで ひらおよぎ/よこにあるいて きょろきょろ/ひっくりかえって ぺこりんこ/いっぽ すすんで えらいひと/
くうき いれましょ シュウッ シュウ/ちょっと しゃがんで くりひろい/ちょっと ここらで ひらおよぎ/よこにあるいて きょろきょろ/ひっくりかえって ぺこりんこ/
くうきが はいって ピュウッ ピュウ/くうき いれましょ シュウッ シュウ/ちょっと しゃがんで くりひろい/ちょっと ここらで ひらおよぎ/よこにあるいて きょろきょろ/
そろそろ おわりかな/くうきが はいって ピュウッ ピュウ/くうき いれましょ シュウッ シュウ/ちょっと しゃがんで くりひろい/ちょっと ここらで ひらおよぎ/
そろそろ おわりかな/そろそろ おわりかな/くうきが はいって ピュウッ ピュウ/くうき いれましょ シュウッ シュウ/ちょっと しゃがんで くりひろい/
そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/くうきが はいって ピュウッ ピュウ/くうき いれましょ シュウッ シュウ/
そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/くうきが はいって ピュウッ ピュウ/
そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/
そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/
そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/
そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/
そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/
そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/そろそろ おわりかな/
おわり/おわり/おわり/おわり/おわり/
```

おわり。