diff --git a/algo/local_improving.cpp b/algo/local_improving.cpp new file mode 100644 index 0000000000000000000000000000000000000000..06484a7caf31a5d514136f893ce96dc92f7cf768 --- /dev/null +++ b/algo/local_improving.cpp @@ -0,0 +1,64 @@ +#include "../pipe.h" +#include <functional> +#include <cassert> + +// ****** ARGS ******** +// <int> max number of changes + +using std::pair; + +const int VERSION = 2; +const bool ALLOW_INPUT_MISTAKES = 0; +const bool ALLOW_MISTAKES = 0; + +vector<bool> solve(int n, vector<int> input, vector<bool> out, + int argc, char const* const* argv) +{ + assert(argc==1); + int max_changes = atoi(argv[0]); + assert(max_changes > 0); + + vector<int> other = lib::gen_arr_other_car_of_type(n, input); + + std::function<bool (int, int , int)> f = [&](int changes, int score_diff, int begin_index) + { + for(int i=begin_index; i<2*n;i++) if(i < other[i]) + { + out[i] = !out[i]; + out[other[i]] = !out[other[i]]; + + int new_score_diff = score_diff; + if(i) new_score_diff += out[i]==out[i-1] ? -1 : 1; + if(i+1 != other[i]) + { + new_score_diff += out[i]==out[i+1] ? -1 : 1; + new_score_diff += out[other[i]]==out[other[i]-1] ? -1 : 1; + } + if(other[i]!=2*n-1) new_score_diff += out[other[i]]==out[other[i]+1] ? -1 : 1; + + if(new_score_diff < 0) + { + fprintf(stderr, "%d %d %d\n", changes, i, new_score_diff); + return true; + } + + + if(changes+1 < max_changes) + if(f(changes+1, new_score_diff, i+1)) + return true; + + out[i] = !out[i]; + out[other[i]] = !out[other[i]]; + } + return false; + }; + + while (f(0, 0, 0)) + { + + fo(i, 2*n) fprintf(stderr, "%c", out[i]?'1':'0'); + fprintf(stderr, "\n", n); + } + + return out; +} diff --git a/algo/rg.cpp b/algo/rg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..81b769d4c394700e7267229ad5aa60b4ed3ceabf --- /dev/null +++ b/algo/rg.cpp @@ -0,0 +1,42 @@ +#include "../main.h" + +const int VERSION = 1; +const bool ALLOW_MISTAKES = 0; + +vector<bool> solve(int n, vector<int> input, + int argc, char const* const* argv) +{ + if(n == 0) return vector<bool>(); + vector<int> other = lib::gen_arr_other_car_of_type(n, input); + vector<bool> out(2*n); + + vector<int> r_input(2*n-2); + for(int i=1;i<2*n;i++) if(i != other[0]) + r_input[i - 1 - (i>other[0])] = input[i] - (input[i] > input[0]); + + auto r_out = solve(n-1, r_input, argc, argv); + + for(int i=1;i<2*n;i++) if(i != other[0]) + out[i] = r_out[i - 1 - (i>other[0])]; + + if(other[0] == 2*n-1) + { + out[0] = 1; + out[other[0]] = 0; + } + else if(other[0] == 1) + { + out[0] = !out[2]; + out[1] = out[2]; + } + else + { + if(out[other[0]-1] == out[1] && out[other[0]+1] == out[1]) + out[0] = !out[1]; + else + out[0] = out[1]; + out[other[0]] = !out[0]; + } + + return out; +} diff --git a/algo/rsg.cpp b/algo/rsg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..47895a2fba073a73fbabaaa3c11f87882074509f --- /dev/null +++ b/algo/rsg.cpp @@ -0,0 +1,96 @@ +#include "../main.h" + +const int VERSION = 1; +const bool ALLOW_MISTAKES = 0; + + +vector<int> solve_star(int n, vector<int> input) +{ + if(n == 0) return vector<int>(); + vector<int> other = lib::gen_arr_other_car_of_type(n, input); + vector<int> out(2*n); // 0: * -1, 1: colors + + vector<int> r_input(2*n-2); + for(int i=1;i<2*n;i++) if(i != other[0]) + r_input[i - 1 - (i>other[0])] = input[i] - (input[i] > input[0]); + + auto r_out = solve_star(n-1, r_input); + + for(int i=1;i<2*n;i++) if(i != other[0]) + out[i] = r_out[i - 1 - (i>other[0])]; + + if(other[0] == 2*n-1) // B + { + out[0] = 1; + out[other[0]] = -1; + } + else if(other[0] == 1) // A + { + out[0] = -out[2]; + out[1] = out[2]; + } + else if(out[other[0]-1] == out[other[0]+1] && out[other[0]-1]) // C + { + out[0] = -out[other[0]-1]; + out[other[0]] = out[other[0]-1]; + } + else if(out[other[0]+1] && out[other[0]-1]) // D + { + out[0] = out[1]; + out[other[0]] = -out[1]; + } + else if(out[1] == -out[other[0]-1] || out[1] == -out[other[0]+1]) // E + { + out[0] = out[1]; + out[other[0]] = -out[1]; + } + else // F + { + out[0] = out[1]; + out[other[0]] = -out[1]; + if(!out[other[0]-1]) + { + out[other[0]-1] = -out[1]; + out[other[other[0]-1]] = out[1]; + } + else + { + out[other[0]+1] = -out[1]; + out[other[other[0]+1]] = out[1]; + } + } + + if(other[1] != 2 && other[1] != 2*n-1 + && out[1-1] && out[1+1] + && out[other[1]-1] && out[other[1]+1]) // G + { + int diffs = 0; + diffs += out[1] != out[1-1]; + diffs += out[1] != out[1+1]; + diffs += out[other[1]] != out[other[1]-1]; + diffs += out[other[1]] != out[other[1]+1]; + if(diffs == 2) + { + out[1] = out[other[1]] = 0; + } + } + //fo(i, 2*n) fprintf(stderr, "%c", out[i]?out[i]==1?'1':'0':'*'); + //fprintf(stderr, "\n", n); + return out; +} + +vector<bool> solve(int n, vector<int> input, + int argc, char const* const* argv) +{ + vector<int> other = lib::gen_arr_other_car_of_type(n, input); + auto out_star = solve_star(n, input); + vector<bool> out(2*n); + fo(i, 2*n) + { + if(out_star[i]) + out[i] = out_star[i] > 0; + else + out[i] = i > other[i]; + } + return out; +} diff --git a/build.mk b/build.mk index 9c8685ab1aed390a5c8e3a3d5332d15d84d8cc0b..1eb333fcceb69a6ec6dbb74139ab9c947ce14f18 100644 --- a/build.mk +++ b/build.mk @@ -58,7 +58,10 @@ endef $(eval $(call standard_algo,greedy)) $(eval $(call standard_algo,maxcut)) $(eval $(call standard_algo,semidef_prog)) +$(eval $(call standard_algo,rg)) +$(eval $(call standard_algo,rsg)) $(eval $(call standard_pipe,fix_naive)) $(eval $(call standard_pipe,fix_better)) +$(eval $(call standard_pipe,local_improving)) diff --git a/config.mk b/config.mk index 0a26bc792f1e659c08f071f96645a2d0ba3760a2..732f4d3c2590167c25f3cb5d5035a55b0aff9bea 100644 --- a/config.mk +++ b/config.mk @@ -1 +1 @@ -algorithms=greedy maxcut fix_naive fix_better semidef_prog +algorithms=greedy maxcut fix_naive fix_better semidef_prog local_improving rg rsg