Advent Challenge 1: Help Santa unlock his present vault!
Java



import java.util.Arrays;

public class SantaMatrix4 {
&#9;
&#9;public static void flipV(int[][] matrix, int row1, int col1, int row2, int col2) {
&#9;&#9;for (int row = row1; row &lt;= (row2 - row1) / 2 + row1; row++) {
&#9;&#9;&#9;for (int col = col1; col &lt;= col2; col++) {
&#9;&#9;&#9;&#9;int tmp = matrix[row][col];
&#9;&#9;&#9;&#9;matrix[row][col] = matrix[row2 - row + row1][col];
&#9;&#9;&#9;&#9;matrix[row2 - row + row1][col] = tmp;
&#9;&#9;&#9;}
&#9;&#9;}
&#9;}
&#9;
&#9;public static void flipH(int[][] matrix, int row1, int col1, int row2, int col2) {
&#9;&#9;for (int row = row1; row &lt;= row2; row++) {
&#9;&#9;&#9;for (int col = col1; col &lt;= (col2 - col1) / 2 + col1; col++) {
&#9;&#9;&#9;&#9;int tmp = matrix[row][col];
&#9;&#9;&#9;&#9;matrix[row][col] = matrix[row][col2 - col + col1];
&#9;&#9;&#9;&#9;matrix[row][col2 - col + col1] = tmp;
&#9;&#9;&#9;}
&#9;&#9;}
&#9;}

&#9;public static void main(String[] args) {
&#9;&#9;int counter = 0;
&#9;&#9;int n = Integer.parseInt(args[counter++]);
&#9;&#9;int[][] matrix1 = new int[n][n];
&#9;&#9;for (int i = 0; i &lt; n; i++) {
&#9;&#9;&#9;for (int j = 0; j &lt; n; j++) {
&#9;&#9;&#9;&#9;matrix1[i][j] = Integer.parseInt(args[counter++]);
&#9;&#9;&#9;}
&#9;&#9;}
&#9;&#9;&#9;&#9;
&#9;&#9;int[][] matrix2 = new int[n][n];
&#9;&#9;for (int i = 0; i &lt; n; i++) {
&#9;&#9;&#9;for (int j = 0; j &lt; n; j++) {
&#9;&#9;&#9;&#9;matrix2[i][j] = Integer.parseInt(args[counter++]);
&#9;&#9;&#9;}
&#9;&#9;}
&#9;&#9;&#9;
&#9;&#9;int[] ops = new int[5 * matrix1.length * matrix1.length * 2];
&#9;&#9;int numOps = 0;
&#9;&#9;int opsI = 0;
&#9;&#9;
&#9;&#9;for (int row = 0; row &lt; n; row++) {
&#9;&#9;&#9;for (int col = 0; col &lt; n; col++) {
&#9;&#9;&#9;&#9;int goal = matrix2[row][col];
&#9;&#9;&#9;&#9;boolean gotIt = false;
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;//Look for required number to the right
&#9;&#9;&#9;&#9;for (int i = row; i &lt; n &amp;&amp; !gotIt; i++) {
&#9;&#9;&#9;&#9;&#9;for (int j = col; j &lt; n &amp;&amp; !gotIt; j++) {
&#9;&#9;&#9;&#9;&#9;&#9;if (i == row &amp;&amp; j == col) continue;
&#9;&#9;&#9;&#9;&#9;&#9;if (matrix1[i][j] == goal) {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;flipH(matrix1, row, col, i, j);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;flipV(matrix1, row, col, i, j);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = 1;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = row;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = col;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = i;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = j;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;numOps++;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;gotIt = true;
&#9;&#9;&#9;&#9;&#9;&#9;}
&#9;&#9;&#9;&#9;&#9;}
&#9;&#9;&#9;&#9;}

&#9;&#9;&#9;&#9;//Look for required number below and to the left
&#9;&#9;&#9;&#9;for (int i = row + 1; i &lt; n &amp;&amp; !gotIt; i++) {
&#9;&#9;&#9;&#9;&#9;for (int j = 0; j &lt; col &amp;&amp; !gotIt; j++) {
&#9;&#9;&#9;&#9;&#9;&#9;if (matrix1[i][j] == goal) {
&#9;&#9;&#9;&#9;&#9;&#9;&#9;flipH(matrix1, i, j, i, col);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = 2;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = i;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = j;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = i;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = col;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;flipV(matrix1, row, col, i, col);
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = 3;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = row;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = col;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = i;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;ops[opsI++] = col;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;numOps += 2;
&#9;&#9;&#9;&#9;&#9;&#9;&#9;gotIt = true;
&#9;&#9;&#9;&#9;&#9;&#9;}
&#9;&#9;&#9;&#9;&#9;}
&#9;&#9;&#9;&#9;}
&#9;&#9;&#9;&#9;
&#9;&#9;&#9;}
&#9;&#9;}

&#9;&#9;System.out.println(Arrays.toString(ops));
&#9;&#9;System.out.println(numOps);
&#9;}
}


Slightly faster hard-coded version: Try it online!

Input is space separated integers via the command line. The first integer is the width of the two matrices. The remaining integers are their elements, row-by-row.

Every permutation of a matrix can be obtained with just the horizontal flip and vertical flip operators, so I ignored the rest except for replacing a consecutive vFlip and hFlip in the same region with a rotation by 180 degrees.

The program scans through each element. Whenever we encounter an element that has the wrong bit, it looks further ahead through the array to find a spot that has the correct bit. I've divided the search region in two: those with an equal or larger column coordinate, and those with a smaller column coordinate. Note that the latter must have a larger row coordinate based on the way we're traversing the array. If we find a correct bit in the first search region, we can just rotate by 180 degrees the sub-matrix spanning the two elements for a total of one operation. If it's in the second region, we can use a horizontal flip to move the correct bit to the same column as the wrong bit and then vertically flip the sub-matrix spanning the two for a total of two operations.

The output of the program is an array that should be mentally split into groups of five. Each group is (i, row1, col1, row2, col2) where i is 0 for a no-op, 1 for a rotation by 180 degrees, 2 for a horizontal flip, and 3 for a vertical flip. The remaining 4 components describe the region over which the operation runs. I am not sure if this is a readable format.

For the given test case, I get 258 operations and two to three milliseconds on my computer.