サブロウ丸

Sabrou-mal サブロウ丸

主にプログラミングと数学

master mind by c++; part9 temaplate

今回やること

templateの導入, 及び color, hit-blow のデータ型の変更

template

関数の引数や返り値、またクラス属性の型を宣言時に可変にできる機能です.
ピンの色とhit-blowのデータ型を今まではどちらもint型で定義していましたが、それをshortに変えてみます.

環境によっても異なりますが、shortの方がintよりも型のサイズが小さいため、メモリの節約と計算の高速化が期待されます.

まず ./src/def.hの中身を変えます

using ColorType   = short; // ビンの色
using HintType    = short;  // ヒントタイプ
using Code        = std::vector<ColorType>;
using HitBlow     = std::pair<HintType, HintType>;
using CodeList    = std::deque<Code>;

ピンの色をColorType, hit-blowをHintTypeで管理することにします.
これに従って, 他の箇所も書き換えます.

./src/codeGenerator.h に itertools.rangeにて下記でvector<int>で色の集合を取り出している箇所があるため, そこを変更してみます.

   Itertools itertools;
   auto colors = itertools.range(0, config.nColors);

まずは, 現状だと itertools.rangeでvector<int>型が常に返されるようになっているため vector<ColorType>も返せるようにしましょう.

template<typename T>
std::vector<T> range(
    ...
)

templateを関数の頭に追加し, 関数内の型を適切にTを用いることで itertools.range<int>(0, 3) だと vector<int>型 の {0, 1, 2}が返され, itertools.range<ColorType>(0, 3) だと vector<ColorType>型 の {0, 1, 2}が返されます. さらに

template<typename T=int>
std::vector<T> range(
    ...
)

でTのデフォルト値をintにします. これでitertools.range(0, 3)vector<int>型 の {0, 1, 2}が返されます.

./src/itertools.h

/**
 * @brief iterator管理用
 */
class Itertools
{
public:
   /**
    * @brief beginからendまでstep幅のvecorを返す
    * @tparam T returning type
    * @param[in] begin
    * @param[in] end
    * @param[in] step default is 1
    * @retrun vecor<T>
    * @details range(0, 5) --> {0, 1, 2, 3, 4}
    *          range(5, -1, -1) --> {5, 4, 3, 2, 1}
    */
   template<typename T=int> // 変更 int -> T !!!
   std::vector<T> range( // 変更 int -> T !!!
         int begin,
         int end,
         int step=1
         )
   {
      assert( ( (end - begin)*step >= 0) && step != 0 );   // (end >= begin) => step > 0 && ...
      int n = std::abs(round((begin - end) / step));
      std::vector<T> res(n);  // 変更 int -> T !!!
      res[0] = begin;
      for ( int i = 1; i < n; i++ ) res[i] = res[i-1] + step;
      return res;
   }
 
   ... ( 略 )

./src/codeGenerator.h

   Itertools itertools;
   auto colors = itertools.range<ColorType>(0, config.nColors);

これでColorTypeに応じた色の集合が受け取れるようになりましたね.

実験

そのほかの箇所もColorType, HintTypeに応じて変更を行い, ピンの色, hit-blowの型を int → shortにして実験してみます.

sizeof(int) = 8
sizeof(short) = 4

実験環境なので、データ管理が効率的になっていることを期待します。

10回の実行時間の平均時間で比較します.

nColors nPins int - totalTime [msec] short - totalTime [msec]
5 5 6.7 0.8
6 5 4828.5 1123.4
7 5 31635.6 27990.2

実行時間を減少させることができていますね.

まとめ

templateを用いて, ピンの色, hit-blowの型を変更できるようにしました.

コード

他の記事