void eval_block(code *block, map* vars) { while (true) { code_skip_whitespace(block); if (block->source[block->pos] == '?') { uint8_t brackets = 0; size_t start, length = 0; mpz_t value; mpz_init(value); block->pos++; code_skip_whitespace(block); _parse_value(block, value, vars); code_skip_whitespace(block); start = block->pos + 1; while (true) { length++; if (block->source[block->pos] == '{') { brackets++; block->pos++; } else if (block->source[block->pos] == '}') { brackets--; block->pos++; if (brackets == 0) break; } else { block->pos++; } } if (mpz_sgn(value) == 0) { code subblock; code_init(&subblock); code_append(&subblock, block->source + start * sizeof(char), length - 2); eval_block(&subblock, vars); code_free(&subblock); } mpz_clear(value); } else if (block->source[block->pos] == '!') { mpz_t value; mpz_init(value); block->pos++; code_skip_whitespace(block); _parse_value(block, value, vars); mpz_out_str(stdout, 10, value); printf("\n"); mpz_clear(value); } else { char *var = malloc(1024 * sizeof(char)); mpz_t value; mpz_init(value); _parse_variable_name(block, var); code_skip_whitespace(block); switch (block->source[block->pos]) { case '=': block->pos++; code_skip_whitespace(block); _parse_value(block, value, vars); map_set(vars, var, value, false); break; case '+': block->pos += 2; code_skip_whitespace(block); _parse_value(block, value, vars); map_set(vars, var, value, true); break; case '-': block->pos += 2; code_skip_whitespace(block); _parse_value(block, value, vars); mpz_neg(value, value); map_set(vars, var, value, true); break; default: fprintf(stderr, "Parse error\n"); } free(var); mpz_clear(value); } code_skip_whitespace(block); if (block->pos >= block->length) return; if (block->source[block->pos] == ';') { block->pos++; } else { fprintf(stderr, "Missing ;\n"); return; } } }
/*蓮メリちゅっちゅ*/ std::vector<answer_type_y> Murakami::operator() (){ bool const w_mode = true; auto const width = data_.split_num.first; auto const height = data_.split_num.second; //sort_compare();//sorted_comparation作成 /* #ifdef _OPENMP //OpenMPを使ったコード std::cout << "use openMP" << std::endl; #else //OpenMPを使わない場合のコード std::cout << "no use openMP" << std::endl; #endif */ make_sorted_comparation(); //boost::timer t; std::vector<block_data_> block_list(height * width); unsigned int unique_number_cnt = 0; //ブロックの左上に分割画像を配置するループ for (int i = 0; i < height; i++){ for (int j = 0; j < width; j++){ //block_list[i * width + j][0][0].y = i; //block_list[i * width + j][0][0].x = j; block_list[i * width + j].block = { { { j, i } } };//std::vector < std::vector<point_type> > {std::vector < point_type > {point_type{ j, i } }}; block_list[i * width + j].u_this_number = unique_number_cnt; unique_number_cnt++; } } //std::cout << "a"; //block_combination b; for (int i = 0; i < block_list.size(); i++){//ブロック比較ループ改良 block_combination b; for (int j = i; j < block_list.size(); j++){ if (i == j) continue; b = w_mode ? eval_block(block_list[i].block, block_list[j].block) : eval_block2(block_list[i].block, block_list[j].block); block_list[i].score_data_[block_list[j].u_this_number] = std::move(score_data{ b.score, b.shift_x, b.shift_y }); } } int a;//デバッグ用の変数 try{ while (block_list.size() != 1){//メインループ a = block_list.size(); block_combination best_block_combination;//一番いいblockの組み合わせいれるところ best_block_combination.score = std::numeric_limits<bigint>::min(); block_combination b; for (int i = 0; i < block_list.size(); i++){//ブロック比較ループ改良 for (int j = i; j < block_list.size(); j++){ if (i == j) continue; std::unordered_map<unsigned int, score_data>::iterator m_it = block_list[i].score_data_.find(block_list[j].u_this_number); if (m_it != block_list[i].score_data_.end()){ //TODO ここを参照渡しにする b.block1 = block_list[i].block; b.block2 = block_list[j].block; b.score = block_list[i].score_data_[m_it->first].score; b.shift_x = block_list[i].score_data_[m_it->first].shift_x; b.shift_y = block_list[i].score_data_[m_it->first].shift_y; } else{ b = w_mode ? eval_block(block_list[i].block, block_list[j].block) : eval_block2(block_list[i].block, block_list[j].block); } if (best_block_combination.score < b.score)best_block_combination = std::move(b); } } if (best_block_combination.score == std::numeric_limits<bigint>::min()){ //std::cout << "本当に結合するブロックがなかったので解を出さずにMurakamiは終了します"; throw std::runtime_error("Murakami_runtime_error"); } block_type combined_block = std::move(combine_block(best_block_combination));//ブロックを結合する boost::remove_erase_if(block_list, [&best_block_combination](block_data_ it){//block_listから結合する前のブロックを消す return (it.block == best_block_combination.block1 || it.block == best_block_combination.block2); }); block_data_ p_b; p_b.block = combined_block; block_list.push_back(p_b);//結合したのを入れる //std::cout << "***" << block_list.size() << "***" << "\r" << std::flush; /* for (const auto& i : block_list){ for (const auto& j : i.block){ for (const auto& k : j){ //std::cout << k.x << "," << k.y << " "; std::cout << boost::format("(%2d,%2d)") % k.x % k.y; } std::cout << "\n"; } std::cout << "\n"; } */ /*デバッグ画像表示 std::vector<std::vector<std::vector<point_type>>> raw_block_list; for (auto const& block_it : block_list){ raw_block_list.push_back(block_it.block); } gui::combine_show_image(data_, comp_, raw_block_list); */ } }catch (...){ std::cerr << "ダメ_Murakami_だめ" << std::endl; //std::cout << t.elapsed() << "s経過した(Murakami内で計測)" << std::endl; std::vector<std::vector<point_type>>exception_array; std::vector<block_type> temp_array; for (auto hoge : block_list){ temp_array.push_back(hoge.block); } exception_array = std::move(force_combine_block(temp_array)); return std::vector<answer_type_y>{ { std::move(exception_array), 0, cv::Mat() } }; } //std::cout << t.elapsed() << "s経過した(Murakami内で計測)" << std::endl; /*デバッグ表示 for (int i = 0; i < height; i++){ for (int j = 0; j < width; j++){ std::cout << block_list[0].block[i][j].x << "," << block_list[0].block[i][j].y << "|"; } std::cout << "\n"; } */ return std::vector<answer_type_y>{ { block_list.at(0).block, 0, cv::Mat() } }; }