We will hold AtCoder Heuristic Contest 011.
- Contest URL: https://atcoder.jp/contests/ahc011
- Start Time: https://www.timeanddate.com/worldclock/fixedtime.html?iso=20220528T1200&p1=248
- End Time: https://www.timeanddate.com/worldclock/fixedtime.html?iso=20220605T1900&p1=248
- Duration: 8 days (long-term contest)
- Writer: wata
- Rated range: All (Heuristic Rating)
AtCoder Heuristic Contest (AHC) is a new series of programming contests that will be held regularly on AtCoder. Unlike algorithm contests such as ABC/ARC/AGC, the goal is to create a better solution to a problem for which it is difficult to find the optimal solution. We are planning to hold a long-term contest with a duration of more than a week and a short-term contest with a duration of less than a day, alternately about once a month.
AHC uses a new rating system that is different from the existing ABC/ARC/AGC rating system. Unlike the ABC/ARC/AGC ratings, AHC rating does not decrease even if contest performance is poor. Please feel free to participate. You can check the current ranking here: https://atcoder.jp/ranking?contestType=heuristic
We are looking forward to your participation!
Just a question regarding time complexity, in my local machine for N=10, code runs in 400ms whereas on atcoder platform same one runs on 30ms. Which one should I consider?
Apparently, heuristic contests doesn't have editorial. Where can I find editorial/approaches?
If you can read Japanese: https://atcoder.jp/contests/ahc011/editorial/4093
Can someone discuss some of the strategies they used to get beyond 35 million?
Here is a short description of my ideas that got me first to 17 million and then to around 35 million with some optimization.
Basic idea for ~15 million:
A simple heurisitic for generating a large tree (hopefully a complete one) is to choose a random point and dfs from it. When we reach a new cell, we will try the 15 non-empty masks in random order satisfies and place a mask if it satisfies the following two conditions:
This hueristic seems to generate complete trees for n <= 7 but only trees of size 90-95 on average for n = 10. Still a decent start.
To make stuff easier later, lets ensure the empty cell is always at (0, 0)
Now to think about a simple heurisitic for solving the puzzle.
Lets first solve an important problem — how can we move a non-empty cell from $$$(a, b)$$$ to $$$(c, d)$$$.
Suppose we have a valid sequence of cells $$$(x_1, y_1), (x_2, y_2), \cdots, (x_k, y_k)$$$ such that $$$(x_i, y_i)$$$ is adjacent (sharing a side) to $$$(x_{i + 1}, y_{i + 1})$$$, $$$(x_1, y_1) = (a, b)$$$ and $$$(x_k, y_k) = (c, d)$$$. In other words this sequence of cells represents a path from $$$(a, b)$$$ to $$$(c, d)$$$. If our cell is currently at $$$(x_i, y_i)$$$ and we want to move it to $$$(x_{i + 1}, y_{i + 1})$$$, we need to move the empty cell to $$$(x_{i + 1}, y_{i + 1})$$$ (without moving the cell at $$$(x_i, y_i)$$$ in the process) and then move it to $$$(x_i, y_i)$$$. Repeating this will allow us to move our required cell from $$$(a, b)$$$ to $$$(c, d)$$$. To move the empty cell to the target location without moving certain cells we don't want it to move (like $$$(x_i, y_i)$$$ here), we can use a list of 'blocked' cells and bfs around them to find a path.
Note that if we use bfs to find the original path from $$$(a, b)$$$ to $$$(c, d)$$$ as well as the path for the empty cell, we will minimize the number of moves used which is what we want.
Now that we know how to move a cell fairly arbitrarily, lets think about how to transform a grid from the original one to the target one. One simple way is to try to transform it into a smaller subproblem. Since we have an $$$n \cdot n$$$ unsolved grid, lets try reducing it to an $$$(n - 1) \cdot (n - 1)$$$ unsolved grid by solving the last row and column. This seems to be a pretty common idea, so here is a nice blog describing how we can do that.
Solving the last two rows we place in a given column / last two columns we place in a given row seems tough due to the value potentially getting stuck, so lets just forget about it for now. Additionally our method doesn't work once we have a 3x3 left so skip that as well.
Even with this incomplete puzzle solver, it is enough to get close to 15 million. (I didn't submit this, so no submission to link unfortunately.)
15 to 20 million:
This allows us to generate a complete tree within ~2s around 90% of the time for n = 10.
Score — 19988760
20 to 25 million:
Since the grid is bipartite and we move the empty cell one step in each move, exactly half the 3x3 states are reachable from a given state at the end. However since we potentially have repeated values in this 3x3, we may have multiple winning states that match the expected values, so our odds are better.
Score — 25412653
25 to 30 million:
Tree generator:
Puzzle solver:
These two together also make the chance of finding a 3x3 matching at the end almost 100%.
Score — 30038670
30 to ~35 million:
Basic thought — Different trees from the same masks can have drastically different costs to solve using the puzzle solver.
Until we are out of time, lets repeat the following process:
Generate a perfect tree.
Run puzzle solver on it for a small amount of runs to get a estimate of how good the tree is.
Replace the existing tree if the current run has a better answer.
Once we are done with this, we run the puzzle solver on the "best" tree for some more time to optimize the answer we got.
Score — 34779126
Unfortunately got busy after this an didn't get any time to try out any further ideas. Some ideas I had for > 35 million:
Tree generator:
Puzzle solver:
Would love to hear what other participants did to reach more than 35 million.