// ランダムテストケース生成器 // パターンファイルは手動と自動で作りました #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define REP(i,a,b) for(int i=a;i<(int)b;i++) #define rep(i,n) REP(i,0,n) #define all(c) (c).begin(), (c).end() #define zero(a) memset(a, 0, sizeof a) #define minus(a) memset(a, -1, sizeof a) template ostream& operator << (ostream& ost, vector const& v) { rep(i, v.size()) { if(i) ost << endl; ost << v[i]; } ost << endl; return ost; } template constexpr bool in_range(T y, T x, T H, T W) { return 0<=y&&y>19)^t^(t>>8); } unsigned next(unsigned k) { return next()%k; } } rndgen; vector> smalls = { #include "pattern_smalls" }; vector> mediums = { #include "pattern_mediums" }; vector> larges = { #include "pattern_larges" }; vector> extreme_larges = { #include "pattern_extreme_larges" }; vector> huges = { #include "pattern_huges" }; void verify_patterns() { auto verify_field = [](vector & v) { int N = v.size(), M = v[0].size(); rep(y, N) rep(x, M) { if(v.size() != N) { cout << "v.size(): " << v.size() << " not equal to N = " << N << endl; exit(-1); } if(v[y].size() != M) { cout << "v["< const& pattern, int sy, int sx, int H, int W) { int PH = pattern.size(), PW = pattern[0].size(); REP(i, sy, sy + PH) REP(j, sx, sx + PW) { if(pattern[i-sy][j-sx] == '.') { continue; } if(field[i][j]) { return false; } int xcount = 0; rep(k, 8) { int ni = i + dy[k], nj = j + dx[k]; if(!in_range(ni, nj, H, W)) { continue; } if(in_range(ni, nj, sy+PH, sx+PW)) { xcount += work[ni][nj]; } else { xcount += field[ni][nj]; } if(work[ni][nj] && field[ni][nj]) { return false; } } if(xcount <= 2) { work[i][j] = 1; } else if(pattern[i-sy][j-sx] != '.') { return false; } } return true; } bool try_to_place_pattern(vector const& pattern, int H, int W) { int PH = pattern.size(), PW = pattern[0].size(); if(H < PH || W < PW) { return false; } int MaxTrials = 20; // Trial bool ok = 0; rep(trial, MaxTrials) { int y = H == PH ? 0 : rndgen.next(H - PH), x = W == PW ? 0 : rndgen.next(W - PW); copy_to_work_with_range(y, x, PH, PW); if(!place_pattern_to_work(pattern, y, x, H, W)) { continue; } ok = 1; copy_to_field_with_range(y, x, PH, PW); break; } return ok; } int N; string fname_prefix; int MaxPaintHuge; int MaxPaintExL; int MaxPaintLarge; int MaxPaintMedium; int MaxPaintSmall; void make_random_pattern(int H, int W) { auto trial_result_message = [](bool ok, string const& msg){ cout << msg << " trial "; if(ok) cout << "succeeded." << endl; else cout << "failed." << endl; }; bool ok = 1; rep(i, MaxPaintHuge) { int tryidx = rndgen.next(huges.size()); ok &= try_to_place_pattern(huges[tryidx], H, W); } trial_result_message(ok, "Huge"); ok = 1; rep(i, MaxPaintExL) { int tryidx = rndgen.next(extreme_larges.size()); ok &= try_to_place_pattern(extreme_larges[tryidx], H, W); } trial_result_message(ok, "ExLarge"); ok = 1; rep(i, MaxPaintLarge) { int tryidx = rndgen.next(larges.size()); ok &= try_to_place_pattern(larges[tryidx], H, W); } trial_result_message(ok, "Large"); ok = 1; rep(i, MaxPaintMedium) { int tryidx = rndgen.next(mediums.size()); ok &= try_to_place_pattern(mediums[tryidx], H, W); } trial_result_message(ok, "Medium"); ok = 1; rep(i, MaxPaintSmall) { int tryidx = rndgen.next(smalls.size()); ok &= try_to_place_pattern(smalls[tryidx], H, W); } trial_result_message(ok, "Small"); } int main() { verify_patterns(); while(1) { cout << "\n----------------------------------------\n"; cout << endl; cout << "Which size do you want? [Height, Width]\n"; int H, W; cin >> H >> W; if(cin.eof()) { break; } assert(1 <= H && H <= 1000 && 1 <= W && W <= 1000); cout << "What is file name prefix?\n"; cin >> fname_prefix; cout << "How many files do you want?: [1,...]\n"; cin >> N; cout << "Max Paint? [Huge, ExL, Large, Medium, Small]\n"; cin >> MaxPaintHuge >> MaxPaintExL >> MaxPaintLarge >> MaxPaintMedium >> MaxPaintSmall; cout << "Making random patten field...\n\n"; rep(fturn, N) { cout << "\nPatten - " << fturn + 1 << "\n"; make_random_pattern(H, W); ofstream ofs(("newpat/" + fname_prefix + to_string(fturn + 1)).c_str()); ofs << H << " " << W << endl; rep(i, H) rep(j, W) { ofs << (field[i][j] ? 'x' : '.'); if(j == W-1) ofs << endl; } } } return 0; }