static soln solve_greedy(char[,] grid, int N, string add_order) { soln result; int i, j, k, ell; result = new soln(N); copy_2d(result.grid, grid, N); for (i = 0; i < N; ++i) { for (j = 0; j < N; ++j) { for (k = 0; k < add_order.Length; ++k) { if (result.grid[i, j] == add_order[k]) { for (ell = 0; ell < k; ++ell) { if ((k == 2) && (ell == 1)) { continue; } if (try_add(add_order[ell], i, j, result, N)) { break; } } } } } } result.points = calc_points(result.grid, N); return(result); }
static bool try_add2(char m, int r, int c, soln s, int N, int[] rows, int[] cols, int[] ups, int[] downs) { char existing; bool valid, n_plus, n_times; existing = s.grid[r, c]; s.grid[r, c] = m; n_plus = ((m == 'x') || (m == 'o')) && !((existing == 'x') || (existing == 'o')); n_times = ((m == '+') || (m == 'o')) && !((existing == '+') || (existing == 'o'));; valid = !(n_plus && ((rows[r] > 0) || (cols[c] > 0))) && !(n_times && ((ups[r + c] > 0) || (downs[r - c + N - 1] > 0))); if (valid) { ++s.num_added; s.added.Add(m + " " + (r + 1) + " " + (c + 1)); if (n_plus) { ++rows[r]; ++cols[c]; } if (n_times) { ++ups[r + c]; ++downs[r - c + N - 1]; } return(true); } s.grid[r, c] = existing; return(false); }
static bool try_add(char m, int r, int c, soln s, int N) { char existing; existing = s.grid[r, c]; s.grid[r, c] = m; if (is_valid(s.grid, N, r, c)) { ++s.num_added; s.added.Add(m + " " + (r + 1) + " " + (c + 1)); return(true); } s.grid[r, c] = existing; return(false); }
static soln solve_greedy2(char[,] grid, int N, int[] rows, int[] cols, int[] ups, int[] downs, string add_order, int r_off, int c_off) { soln result; int i, j, k, ell, r, c; result = new soln(N); copy_2d(result.grid, grid, N); result.points = calc_points(grid, N); for (i = 0; i < N; ++i) { r = (i + r_off) % N; for (j = 0; j < N; ++j) { c = (j + c_off) % N; for (k = 0; k < add_order.Length; ++k) { if (result.grid[r, c] == add_order[k]) { for (ell = 0; ell < k; ++ell) { if ((k == 2) && (ell == 1)) { continue; } result.points -= pts(result.grid[r, c]); if (try_add2(add_order[ell], r, c, result, N, rows, cols, ups, downs)) { result.points += pts(add_order[ell]);; break; } else { result.points += pts(result.grid[r, c]); } } } } } } return(result); }
// T(N) = N^2 + P * T(N) static soln solve(char[,] grid, int N, int points, int min_i, int min_j) { int i, j; soln best, current; best = new soln(N); best.points = points; copy_2d(best.grid, grid, N); for (i = min_i; i < N; ++i) { for (j = ((i == min_i) ? min_j: 0); j < N; ++j) { /* Add model to blank */ if (grid[i, j] == '.') { grid[i, j] = '+'; if (is_valid(grid, N, i, j)) { current = solve(grid, N, points + 1, i, j + 1); if (current.points > best.points) { best = current; } } grid[i, j] = 'x'; if (is_valid(grid, N, i, j)) { current = solve(grid, N, points + 1, i, j + 1); if (current.points > best.points) { best = current; } } grid[i, j] = 'o'; if (is_valid(grid, N, i, j)) { current = solve(grid, N, points + 2, i, j + 1); if (current.points > best.points) { best = current; } } grid[i, j] = '.'; } /* Upgrade from '+' */ else if (grid[i, j] == '+') { grid[i, j] = 'o'; if (is_valid(grid, N, i, j)) { current = solve(grid, N, points + 1, i, j + 1); if (current.points > best.points) { best = current; } } grid[i, j] = '+'; } /* Upgrade from 'x' */ else if (grid[i, j] == 'x') { grid[i, j] = 'o'; if (is_valid(grid, N, i, j)) { current = solve(grid, N, points + 1, i, j + 1); if (current.points > best.points) { best = current; } } grid[i, j] = 'x'; } } } return(best); }
static soln solve_smart_rec(char[,] grid, int N, int[] rows, int[] cols, int[] ups, int[] downs, int points, int r, int c) { int i, j; soln res, alt, best; string to_try; char current; bool not_plus, not_times; Console.WriteLine("Call number: " + (++num_calls)); res = new soln(N); res.points = points; copy_2d(res.grid, grid, N); best = res; if (c >= N) { c = 0; r += 1; } if (r >= N) { return(res); } switch (current = grid[r, c]) { case 'o': to_try = "o"; break; case '+': to_try = "o+"; break; case 'x': to_try = "ox"; break; case '.': to_try = "o+x."; break; default: return(null); } for (i = 1; i <= 3; ++i) { foreach (char m in to_try) { not_plus = (m != current) && (m != '+'); not_times = (m != current) && (m != 'x'); if (not_plus && ((rows[r] > 0) || (cols[c] > 0))) { continue; } if (not_times && ((ups[r + c] > 0) || (downs[r - c + N - 1] > 0))) { continue; } if (not_plus) { ++rows[r]; ++cols[c]; } if (not_times) { ++ups[r + c]; ++downs[r - c + N - 1]; } res.grid[r, c] = m; alt = solve_smart_rec(res.grid, N, rows, cols, ups, downs, points + pts(m) - pts(current), r + i % 2, c + i / 2); if (alt.points > best.points) { best = alt; } res.grid[r, c] = current; if (not_plus) { --rows[r]; --cols[c]; } if (not_times) { --ups[r + c]; --downs[r - c + N - 1]; } } } return(best); }