第四回オフラインリアルタイムどう書くの解答例(Java)

参加できなかったので、非リアルタイム解答しました。

```java:Tetroid.java
import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class Tetroid {

	private final int CELL_NUM = 4;

	protected int getX(String str) {
		return Integer.parseInt(String.valueOf(str.charAt(0)));
	}

	protected int getY(String str) {
		return Integer.parseInt(String.valueOf(str.charAt(1)));
	}

	protected final boolean isL(int[][] shape) {
		int firstX = shape[0][0];
		int firstY = shape[0][1];
		if (firstX != shape[1][0] || (firstY + 1) != shape[1][1]) {
			return false;
		}
		if (firstX != shape[2][0] || (firstY + 2) != shape[2][1]) {
			return false;
		}
		if ((firstX + 1) != shape[3][0] || (firstY + 2) != shape[3][1]) {
			return false;
		}
		return true;
	}

	protected final boolean isI(int[][] shape) {
		int firstX = shape[0][0];
		int firstY = shape[0][1];
		if (firstX != shape[1][0] || (firstY + 1) != shape[1][1]) {
			return false;
		}
		if (firstX != shape[2][0] || (firstY + 2) != shape[2][1]) {
			return false;
		}
		if (firstX != shape[3][0] || (firstY + 3) != shape[3][1]) {
			return false;
		}
		return true;
	}

	protected final boolean isT(int[][] shape) {
		int firstX = shape[0][0];
		int firstY = shape[0][1];
		if ((firstX + 1) != shape[1][0] || firstY != shape[1][1]) {
			return false;
		}
		if ((firstX + 1) != shape[2][0] || (firstY + 1) != shape[2][1]) {
			return false;
		}
		if ((firstX + 2) != shape[3][0] || firstY != shape[3][1]) {
			return false;
		}
		return true;
	}

	protected final boolean isO(int[][] shape) {
		int firstX = shape[0][0];
		int firstY = shape[0][1];
		if (firstX != shape[1][0] || (firstY + 1) != shape[1][1]) {
			return false;
		}
		if ((firstX + 1) != shape[2][0] || firstY != shape[2][1]) {
			return false;
		}
		if ((firstX + 1) != shape[3][0] || (firstY + 1) != shape[3][1]) {
			return false;
		}
		return true;
	}

	protected final boolean isS(int[][] shape) {
		int firstX = shape[0][0];
		int firstY = shape[0][1];
		if ((firstY + 1) != shape[1][1]) {
			return false;
		}
		if ((firstX + 1) != shape[2][0] || (firstY + 1) != shape[2][1]) {
			return false;
		}
		if ((firstX + 1) != shape[3][0] || (firstY + 2) != shape[3][1]) {
			return false;
		}
		return true;
	}

	protected int[][] flipHorizontal(int[][] shape) {
		int[][] result = new int[CELL_NUM][2];
		for (int i = 0; i < CELL_NUM; i++) {
			result[i][0] = 4 - shape[i][0];
			result[i][1] = shape[i][1];
		}
		sortCell(result);
		return result;
	}

	protected int[][] flipVertical(int[][] shape) {
		int[][] result = new int[CELL_NUM][2];
		for (int i = 0; i < CELL_NUM; i++) {
			result[i][0] = shape[i][0];
			result[i][1] = 4 - shape[i][1];
		}
		sortCell(result);
		return result;
	}

	protected int[][] rotate90deg(int[][] shape) {
		int[][] result = new int[CELL_NUM][2];
		for (int i = 0; i < CELL_NUM; i++) {
			result[i][0] = 4 - shape[i][1];
			result[i][1] = shape[i][0];
		}
		sortCell(result);
		return result;
	}

	protected int[][] rotate180deg(int[][] shape) {
		int[][] result = new int[CELL_NUM][2];
		for (int i = 0; i < CELL_NUM; i++) {
			result[i][0] = 4 - shape[i][0];
			result[i][1] = 4 - shape[i][1];
		}
		sortCell(result);
		return result;
	}

	protected int[][] rotate270deg(int[][] shape) {
		int[][] result = new int[CELL_NUM][2];
		for (int i = 0; i < CELL_NUM; i++) {
			result[i][0] = shape[i][1];
			result[i][1] = 4 - shape[i][0];
		}
		sortCell(result);
		return result;
	}

	protected int compare(int[] is, int[] target) {
		if (target[0] < is[0]) {
			return 1;
		} else if (is[0] < target[0]) {
			return -1;
		}
		if (target[1] < is[1]) {
			return 1;
		} else if (is[1] < target[1]) {
			return -1;
		}
		return 0;
	}

	protected void sortCell(int[][] shape) {
		for (int i = 0; i < CELL_NUM - 1; i++) {
			for (int k = CELL_NUM - 1; i < k; k--) {
				if (0 < compare(shape[k - 1], shape[k])) {
					int[] tmp = shape[k];
					shape[k] = shape[k - 1];
					shape[k - 1] = tmp;
				}
			}
		}
	}

	protected int[][] getData(String input) {
		int[][] result = new int[4][2];
		String[] strings = input.split(",");
		List<int[]> tmp = new ArrayList<>();
		for (String str : strings) {
			int x = getX(str);
			int y = getY(str);
			int[] point = { x, y };
			tmp.add(point);
		}
		return tmp.toArray(result);
	}

	protected char shapeCheck(int[][] shape) {
		if (isL(shape)) {
			return 'L';
		}
		if (isI(shape)) {
			return 'I';
		}
		if (isT(shape)) {
			return 'T';
		}
		if (isO(shape)) {
			return 'O';
		}
		if (isS(shape)) {
			return 'S';
		}
		return '-';
	}

	protected char execute(String input) {
		int[][] shape = getData(input);
		sortCell(shape);
		int[][][] shapes = new int[8][4][2];
		shapes[0] = shape;
		shapes[1] = rotate90deg(shape);
		shapes[2] = rotate180deg(shape);
		shapes[3] = rotate270deg(shape);
		shapes[4] = flipHorizontal(shape);
		shapes[5] = rotate90deg(shapes[4]);
		shapes[6] = flipVertical(shape);
		shapes[7] = rotate90deg(shapes[6]);

		for (int[][] point : shapes) {
			char result = shapeCheck(point);
			if (result != '-') {
				return result;
			}
		}
		return '-';
	}

	@Test
	public void testTetroid() throws Exception {
		/* #1 */test("55,55,55,55", '-');
		/* #2 */test("07,17,06,05", 'L');
		/* #3 */test("21,41,31,40", 'L');
		/* #4 */test("62,74,73,72", 'L');
		/* #5 */test("84,94,74,75", 'L');
		/* #6 */test("48,49,57,47", 'L');
		/* #7 */test("69,89,79,68", 'L');
		/* #8 */test("90,82,91,92", 'L');
		/* #9 */test("13,23,03,24", 'L');
		/* #10 */test("24,22,25,23", 'I');
		/* #11 */test("51,41,21,31", 'I');
		/* #12 */test("64,63,62,65", 'I');
		/* #13 */test("49,69,59,79", 'I');
		/* #14 */test("12,10,21,11", 'T');
		/* #15 */test("89,99,79,88", 'T');
		/* #16 */test("32,41,43,42", 'T');
		/* #17 */test("27,16,36,26", 'T');
		/* #18 */test("68,57,58,67", 'O');
		/* #19 */test("72,62,61,71", 'O');
		/* #20 */test("25,24,15,14", 'O');
		/* #21 */test("43,54,53,42", 'S');
		/* #22 */test("95,86,76,85", 'S');
		/* #23 */test("72,73,84,83", 'S');
		/* #24 */test("42,33,32,23", 'S');
		/* #25 */test("66,57,67,58", 'S');
		/* #26 */test("63,73,52,62", 'S');
		/* #27 */test("76,68,77,67", 'S');
		/* #28 */test("12,11,22,01", 'S');
		/* #29 */test("05,26,06,25", '-');
		/* #30 */test("03,11,13,01", '-');
		/* #31 */test("11,20,00,21", '-');
		/* #32 */test("84,95,94,86", '-');
		/* #33 */test("36,56,45,35", '-');
		/* #34 */test("41,33,32,43", '-');
		/* #35 */test("75,94,84,95", '-');
		/* #36 */test("27,39,28,37", '-');
		/* #37 */test("45,34,54,35", '-');
		/* #38 */test("24,36,35,26", '-');
		/* #39 */test("27,27,27,27", '-');
		/* #40 */test("55,44,44,45", '-');
		/* #41 */test("70,73,71,71", '-');
		/* #42 */test("67,37,47,47", '-');
		/* #43 */test("43,45,41,42", '-');
		/* #44 */test("87,57,97,67", '-');
		/* #45 */test("49,45,46,48", '-');
		/* #46 */test("63,63,52,72", '-');
		/* #47 */test("84,86,84,95", '-');
		/* #48 */test("61,60,62,73", '-');
		/* #49 */test("59,79,69,48", '-');
		/* #50 */test("55,57,77,75", '-');
	}

	protected void test(String input, char result) {
		Tetroid tet = new Tetroid();
		assertEquals(result, tet.execute(input));
	}
}
```