ひさしぶり

気がついたら での議論を参考に少し書き直してみた。

class Cards{
public:
  Cards(vector<int> xs):
    values(xs),len(xs.size()){}
  inline int pop(size_t i){
    len--;
    swap(values[i], values[len]);
    return values[len];
  }
  inline void revert(size_t i){
    swap(values[i], values[len]);
    len++;
  }
  vector<int> values;
  size_t len;
};

挙動は一目瞭然かと思うけども一応テスト用の出力結果を貼ろう。

  DP(hands.values);
  DP(hands.pop(2));
  DP(hands.values);
  hands.revert(2);
  DP(hands.values);
----以下出力
hands.values: {4, 14, 15, 17, 49}
hands.pop(2): 15
hands.values: {4, 14, 49, 17, 15}
hands.values: {4, 14, 15, 17, 49}

これを使って最初から最後まで同じカード配列を使い回す。


コア部分もシンプルにして一つの関数にまとめてみた。

Result turn(const int iturn, Cards& unknowns, Cards &hand, 
		   const scores &round_score, const scores &game_score){

  Result result;
  size_t N = unknowns.len;
  
  for(size_t myi=0; myi<hand.len; myi++){
    int my = hand.pop(myi);
    eval_value score = 0;

    for(size_t i=0; i < N; i++){
      int o1 = unknowns.pop(i);
      for(size_t j=0; j < N - 1; j++){
	if(i == j) continue;
	int o2 = unknowns.pop(j);
	if(iturn == 3){
	  score += end_of_game(
	    end_of_round(
	      end_of_turn(my, o1, o2, round_score), 
	      game_score));
	  
	}else{
	  score += turn(
	    iturn + 1,
	    unknowns, hand,
	    end_of_turn(my, o1, o2, round_score),
	    game_score).score;
	}
	unknowns.revert(j);
      }
      unknowns.revert(i);
    }
    if(score > result.score){
      result.score = score;
      result.hand = my;
    }

    hand.revert(myi);
  }
  return result;
}

あれー、実行すると9.9秒かかる。。古いバージョンで4.2秒くらいなのに。。
http://coderepos.org/share/browser/lang/python/saichugen/experiments/cpp/saichugen_simple.cpp?rev=27176
んー。2倍も遅くなるって、なにか大きな失敗をしてそうな気がするなぁ。