ひさしぶり
気がついたら での議論を参考に少し書き直してみた。
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倍も遅くなるって、なにか大きな失敗をしてそうな気がするなぁ。