/** * https://www.hackerrank.com/contests/rookierank/challenges/magic-square-forming * All Contests RookieRank Magic Square Forming */ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.StringTokenizer; public class Solution { public static void main(String[] args) throws NumberFormatException, IOException { FasterScanner sc = new FasterScanner(System.in); int size = 3; int[][] magicSquare = new int[size][size]; int minOperations = 0; for (int row = 0; row < size; row++) { for (int col = 0; col < size; col++) { magicSquare[row][col] = sc.nextInt(); } } minOperations = solveProblem(magicSquare); System.out.println(minOperations); sc.close(); } /** * Compute the minimum amount of operations required to change the inputed * 3x3 matrix into a magic square. * * Using a known magic square, rotate and flip it to get the 8 possible * squares and compare the input against these 8 magic squares to find the * min number of operations. * * @param magicSquare * @return */ public static int solveProblem(int[][] magicSquare) { int minOperations = Integer.MAX_VALUE; int current = 0; int[][] knownSquare = { { 8, 1, 6 }, { 3, 5, 7 }, { 4, 9, 2 } }; current = compareSquares(magicSquare, knownSquare); minOperations = Math.min(minOperations, current); for (int i = 0; i < 3; i++) { knownSquare = rotate90(knownSquare); current = compareSquares(magicSquare, knownSquare); minOperations = Math.min(minOperations, current); } knownSquare = flip(knownSquare); current = compareSquares(magicSquare, knownSquare); minOperations = Math.min(minOperations, current); for (int i = 0; i < 3; i++) { knownSquare = rotate90(knownSquare); current = compareSquares(magicSquare, knownSquare); minOperations = Math.min(minOperations, current); } return minOperations; } public static int compareSquares(int[][] A, int[][] B) { int size = 3; int result = 0; for (int row = 0; row < size; row++) { for (int col = 0; col < size; col++) { result += Math.abs(A[row][col] - B[row][col]); } } return result; } public static int[][] rotate90(int[][] magicSquare) { int[][] result = new int[3][3]; int size = 3; for (int row = 0; row < size; row++) { for (int col = 0; col < size; col++) { result[col][size - 1 - row] = magicSquare[row][col]; } } return result; } public static int[][] flip(int[][] magicSquare) { int size = 3; int[][] result = new int[size][size]; for (int row = 0; row < size; row++) { for (int col = 0; col < size; col++) { result[row][col] = magicSquare[row][size - col - 1]; } } return result; } /** Buffered replacement for the java.util.Scanner */ static class FasterScanner { private static BufferedReader _reader; private static StringTokenizer _parser; public FasterScanner(InputStream input) { _reader = new BufferedReader(new InputStreamReader(input)); _parser = new StringTokenizer(""); } /** * Get the next string token from the buffer. */ public String next() throws IOException { while (!_parser.hasMoreTokens()) { _parser = new StringTokenizer(_reader.readLine()); } return _parser.nextToken(); } /** * Get the next line of text from the buffer. */ public String nextLine() throws IOException { try { return _reader.readLine(); } catch (IOException ex) { return null; } } /** * Get the next int from the buffer. */ public int nextInt() throws NumberFormatException, IOException { return Integer.parseInt(next()); } /** * Get the next long from the buffer. */ public long nextLong() throws NumberFormatException, IOException { return Long.parseLong(next()); } /** * Close the scanner. */ public void close() throws IOException { _parser = null; if (_reader != null) { _reader.close(); _reader = null; } } } }