/* Subject: Contest submission for problem #1, file 1.java */ /* cs61b-cq@imail.EECS.Berkeley.EDU */ /* Thu Sep 11 15:01:07 PDT 2003 */ /*___CONTEST_SUBMISSION___ cs61b-cq 1 */ /** * CS 198, Fall 2003 * Assignment #2, Problem #1 * @author Eric Siroker */ import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.util.Enumeration; import java.util.Iterator; import java.util.LinkedList; import java.util.TreeSet; class P1 { private static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); public static void main(String[] args) throws IOException { LinkedList squares = new LinkedList(); String line; while ((line = reader.readLine()) != null && !line.equals("0")) { squares.add(readSquare(Integer.parseInt(line.trim()))); } for (Iterator iterator = squares.iterator(); iterator.hasNext();) { printSquare((Square)iterator.next()); } } public static Square isolateLegTriangle(Square square) { Square isolatedSquare = new Square(square.getSize()); for (int row = 0; row < square.getSize(); row++) { for (int column = 0; column < square.getSize(); column++) { isolatedSquare.setElement(row, column, row + column < square.getSize() - 1 ? '0' : square.getElement(row, column)); } } return isolatedSquare; } public static Square isolateHypotenuseTriangle(Square square) { Square isolatedSquare = new Square(square.getSize()); for (int row = 0; row < square.getSize(); row++) { for (int column = 0; column < square.getSize(); column++) { isolatedSquare.setElement(row, column, row > column || row + column < square.getSize() - 1 ? '0' : square.getElement(row, column)); } } return isolatedSquare; } public static boolean isUniform(Square square) { char character = square.getElement(square.getSize() - 1, square.getSize() - 1); for (int row = 0; row < square.getSize(); row++) { for (int column = 0; column < square.getSize(); column++) { if (square.getElement(row, column) != '0' && square.getElement(row, column) != character) { return false; } } } return true; } public static Square readSquare(int elements) throws IOException { Square square = new Square(elements); for (int row = 0; row < elements; row++) { String line = reader.readLine(); for (int column = 0; column < elements; column++) { square.setElement(row, column, line.charAt(column)); } } return square; } public static void printSquare(Square square) { LinkedList squares = new LinkedList(); squares.add(square); squares.addAll(square.getInnerSquares()); CharacterCounter counter = new CharacterCounter(square); // Crap? for (int count = 0; count < square.getSize() - 3; count++) { counter.increment(square.getElement(square.getSize() - 1, square.getSize() - 1)); } for (Iterator iterator = squares.iterator(); iterator.hasNext();) { square = (Square)iterator.next(); for (int rotations = 0; rotations <= 3; rotations++) { Square isolatedSquare = isolateLegTriangle(square); if (isUniform(isolatedSquare) && isolatedSquare.equals(isolatedSquare.getTranspose())) { counter.increment(square.getElement(0, square.getSize() - 1)); } square = square.getRotated(); } if (square.getSize() % 2 == 1) { for (int rotations = 0; rotations <= 3; rotations++) { Square isolatedSquare = isolateHypotenuseTriangle(square); if (isUniform(isolatedSquare) && isolatedSquare.equals(isolatedSquare.getFlipped())) { counter.increment(square.getElement(0, square.getSize() - 1)); } square = square.getRotated(); } } } System.out.print("(" + counter.getTotalCount() + ")"); for (int index = 0; index < counter.getSize(); index++) { char character = counter.getCharacter(index); System.out.print(" " + counter.getCount(character) + " " + character); } System.out.println(); } } class CharacterCounter { private char[] characters = new char[20 * 20]; private int[] counts = new int[20 * 20]; private int size = 0, totalCount = 0; public CharacterCounter(Square square) { for (int row = 0; row < square.getSize(); row++) { for (int column = 0; column < square.getSize(); column++) { char character = square.getElement(row, column); if (getIndex(character) == -1) { characters[size] = character; counts[size] = 0; size++; } } } } public char getCharacter(int index) { return characters[index]; } public int getCount(char character) { int index = getIndex(character); return index == -1 ? -1 : counts[index]; } public int getSize() { return size; } public int getTotalCount() { return totalCount; } public void increment(char character) { int index = getIndex(character); if (index != -1) { counts[index]++; totalCount++; } } private int getIndex(char character) { for (int index = 0; index < characters.length; index++) { if (characters[index] == character) { return index; } } return -1; } } class Square { char[][] characters; public Square(int size) { characters = new char[size][size]; } public boolean equals(Square square) { if (characters.length != square.characters.length) { return false; } for (int row = 0; row < characters.length; row++) { for (int column = 0; column < characters.length; column++) { if (characters[row][column] != square.characters[row][column]) { return false; } } } return true; } public char getElement(int row, int column) { return characters[row][column]; } public Square getFlipped() { Square square = new Square(characters.length); for (int row = 0; row < characters.length; row++) { for (int column = 0; column < characters.length; column++) { square.characters[characters.length - row - 1][column] = characters[row][column]; } } return square; } public InnerSquare getInnerSquare(int firstRow, int firstColumn, int size) { InnerSquare square = new InnerSquare(firstRow, firstColumn, size); for (int row = 0; row < size; row++) { for (int column = 0; column < size; column++) { square.characters[row][column] = characters[row + firstRow][column + firstColumn]; } } return square; } public TreeSet getInnerSquares() { TreeSet innerSquares = new TreeSet(); if (characters.length == 2) { return new TreeSet(); } else { for (int row = 0; row <= 1; row++) { for (int column = 0; column <= 1; column++) { InnerSquare innerSquare = getInnerSquare(row, column, characters.length - 1); innerSquares.addAll(innerSquare.getInnerSquares()); innerSquares.add(innerSquare); } } } return innerSquares; } public Square getRotated() { Square square = new Square(characters.length); for (int row = 0; row < characters.length; row++) { for (int column = 0; column < characters.length; column++) { square.characters[column][characters.length - row - 1] = characters[row][column]; } } return square; } public int getSize() { return characters.length; } public Square getTranspose() { Square square = new Square(characters.length); for (int row = 0; row < characters.length; row++) { for (int column = 0; column < characters.length; column++) { square.characters[row][column] = characters[column][row]; } } return square; } public void setElement(int row, int column, char value) { characters[row][column] = value; } public String toString() { StringBuffer string = new StringBuffer((characters.length + 1) * characters.length - 1); for (int row = 0; row < characters.length; row++) { string.append(characters[row]); if (row != characters.length - 1) { string.append('\n'); } } return string.toString(); } } class InnerSquare extends Square implements Comparable { public int row, column; public InnerSquare(int row, int column, int size) { super(size); this.row = row; this.column = column; } public int compareTo(Object object) { InnerSquare innerSquare = (InnerSquare)object; if (equals(innerSquare)) { return 0; } else { return -1; } } public boolean equals(InnerSquare innerSquare) { return row == innerSquare.row && column == innerSquare.column && characters.length == innerSquare.characters.length; } }